add_action('wp_footer', function () { echo ''; }, 99); inshane – CEnA https://cena.co.kr 씨이엔에이 Wed, 19 Aug 2026 18:09:43 +0000 ko-KR hourly 1 https://wordpress.org/?v=6.8.9 DDOS Attack 막기(Linux,Apache 환경) https://cena.co.kr/blocking-ddos-attack-in-linux-apache/ https://cena.co.kr/blocking-ddos-attack-in-linux-apache/#respond Mon, 04 Oct 2010 05:04:34 +0000 http://old.cena.co.kr/17407

 

Written by Inshane

불펌은 상관하지 않으나 내용 출처는 밝혀주시기 바랍니다. – CEnA

 

0. DDOS 개요

사이트를 운영하다보면 정말 별의 별놈이 다 있는걸 알 수 있는데

DDOS 공격은 여러 경로를 통해 감염된 좀비 PC들을 이용하여 한 서버에 트래픽을 과도하게 유발하여

서버 운영을 막는 변태적(?)인 공격이다.

일반적인 공격은 모든 아이피를 대상으로 개방된 웹서버를 지정하여 공격이 들어올때가 많으며,

이때 공격에 사용될 사이트내 특정 주소를 무한 연결하여 서버에 트래픽을 유발한다.

 

몇몇 중소업체를 대상으로 공격을 시도하는 푼돈벌이꾼, 자칭 “현수씨”로 인해

유무형의 피해를 보신 업체 관리자들을 위해 이 글을 적는다.

 

 

1. 기본적 설명 배경

 ㄱ. 서버환경은 :  CentOS 4, Apache, Oops-firewall(oops.org)를 기준으로 하되 기본 방화벽(iptable) 이라해도 별반 차이없다.
 ㄴ. 웹서버를 공격하고 있는것으로 간주하고 설명을 적는다.

 ㄷ. 모든 공격은 100% 막는다는게 없다. 막았다 생각되도 공격자가 공격 패턴을 바꿔가면서 공격하기 때문이다.

이런 싸움은 누가 먼저 지치느냐의 싸움이므로 공격시도시 빠른시간에 캐치하여 공격 패턴을 빠르게 추리는게 답이다.

2. 공격 진단

DDOS 공격시 공격자들은 DB에 Update나 Insert, Delete등을 일으키는 주소를 입력하여 공격하는 경우가 많다.

이경우는 DB 부하까지 같이 생기므로 서버 부하량 측정시 DB도 같이 점검하도록 한다.
(ex : 게시판 글 조회시 hit 수가 update되는걸 이용하여 특정 게시판 주소 등을 직접 입력하여 공격한다.)

 

또한 한개의 주소를 Attack하는 경우 해당 주소를 바꾸는 식으로 방어가 가능하기 때문에
여러개의 주소를 동시다발적으로 입력할때가 많다. 공격 패턴은 다양하지만

대부분 아래와 같은 방법으로 공격당하고있는 현재 서버 상태에 대한 진단이 가능하다.

 

ㄱ. $ top -d 1
  : httpd가 차지하는 점유율이나 평균 서버 부하량을 본다. 평균적인 서버 부하량을 미리 알고 있다면 비교가 될것이다.
 한서버에 웹+DB등 여러가지를 돌리는 서버라면 어느곳에서 부하가 생기는지 잘 측정해봐야 할것이다.

ㄴ. $ ps aux | grep httpd | wc -l   
  : 프로세서 개수 구하기, 일반적인 프로세서 개수보다 급증해 있는지 체크해본다.
 Apache 설정에서 지속성(KeepAlive) 등의 설정에 따라 프로세서의 기본 개수는 차이가 있다.

ㄷ. $ tail -f /var/log/httpd/access_log   //아파치 로그를 찍어봅니다. 
  : 웹서버를 공격한다면 로그를 직접 보는게 가장 확실하게 공격여부를 체크할 수 있다. 
 공격이 자주 시도되는 주소 몇개를 찾아서 해당내용만 grep ‘내용’ 등으로 걸어서 정확한 공격 주소를 찾아본다.

 

 3. 공격 대처
 
  ㄱ. 아파치를 종료시키거나 80포트(웹서비스 운영포트)를 차단한다.

포트 차단시 일부 https(443)등도 같이 차단해줘야 효과를 볼 수 있을것이다.
 
  ㄴ. 아파치 로그를 분석한다. 공격이 들어오는 웹주소를 찾아서 해당 주소의 IP리스트를 뽑는다.
  DDOS 공격시 좀비 pc는 최소 50대~최대 몇만대 가량의 pc가 동원될 수 있으며

중/소규모 웹서버에는 평균적으로 2천대에서 5천대정도의   좀비pc가 동원되는것으로 추정된다.
 이 좀비pc들을 죄다 Block 처리 하는식으로 내용을 뽑도록 한다.

 

  ㄷ. DB에 엑세스 하는 경우 DB에 Insert/Update/Delete를 못하도록 하고, 공격이 과다할때는 select도 부하량이 걸릴수 있으므로

모든 DB연결을 끊는것도 하나의 방법이다.

 

 

4. 테스트 예제 스크립트 작성

 

아래와 같이  192.168.10.1 주소에서 /test/test.html을 공격하고 있음을 알 수 있고, 해당 루틴을 뽑아내기 위해

아래와 같이 스크립트를 구성한다.

192.168.10.1 – – [04/Oct/2010:11:49:57 +0900] “GET /test/test.html HTTP/1.1” 200 5 “http://www.cena.co.kr/test/test.html” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.2; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)”
192.168.10.1 – – [04/Oct/2010:11:49:57 +0900] “GET /test/test.html HTTP/1.1” 200 5 “http://www.cena.co.kr/test/test.html” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.2; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)”
192.168.10.1 – – [04/Oct/2010:11:49:58 +0900] “GET /test/test.html HTTP/1.1” 200 5 “http://www.cena.co.kr/test/test.html” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.2; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)”
192.168.10.1 – – [04/Oct/2010:11:49:58 +0900] “GET /test/test.html HTTP/1.1” 200 5 “http://www.cena.co.kr/test/test.html” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.2; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)”
192.168.10.1 – – [04/Oct/2010:11:49:58 +0900] “GET /test/test.html HTTP/1.1” 200 5 “http://www.cena.co.kr/test/test.html” “Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.2; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)”

 

실제 스크립트 구현단계(test.sh)

 

 
  #!/bin/bash
  
  LANG=euc_UN  ## 한글인경우 10월로 표기되어 아파치 로그와 맞지 않아서 추가되는 구절이다.
  agoTime=`date --date '30 seconds ago' +"["%d"/"%b"/"%Y":"%H":"%M":"%S`  ## 아파치에서 일자,시간값을 뽑아낼때 형태이다. 30초 전의 시간을 뽑는다.
  nowTime=`date +"["%d"/"%b"/"%Y":"%H":"%M":"%S`  ## 현재의 시간을 뽑는다.
  
  awk '{if($4 >= "'"$agoDate"'" && $4 < "'"$nowDate"'"){ print $1" "$7 }}' /etc/httpd/logs/access_log | sort | uniq -c | awk '{if($1 >= 2){ print $2" "$3 }}' > /etc/oops-firewall/scripts/test/testsearch.temp
  awk '{print "%-A INPUT -s "$1" -j DROP"}' testsearch.temp >> /etc/oops-firewall/scripts/test/testinput_iptable.temp
  awk '{print $2}' testsearch.temp >> /etc/oops-firewall/scripts/test/testpattern.temp

 

핵심이 되는 구간은 7,8,9라인이다.
7번라인에서는 access_log에서 30초 전부터 현재시간까지의 로그를 뽑되($4)
그중에서 IP에 해당되는 부분($1) 과 엑세스주소를($7) 를 뽑는다.
(뽑히는 형태 :    192.168.10.1  /test/test.html 식이다.)

 

테스트를 위해 30초내 2번 이상 해당 로그가 찍혀 있다면(거의 대부분의 로그가 찍힐것이다.) attack으로 간주하도록 하였으나
실제로 DDOS 공격시 30초내 최소 10회 이상 Attack이 들어오므로 해당 수치를 조정할 필요가 있다.
너무 적게 잡으면 일반적인 유저가 블럭될 수 있고, 너무 크게 잡으면 DDOS공격자가 수치를 적당히 낮춰서

지속적으로 공격을 할수도 있으니 적절하게 정하도록 한다.

 

일반적인 DDOS 공격패턴은 크게 두가지로 나뉘는데 1분내 동원 가능한 pc가 1000대라면

 ㄱ. 1000대의 좀비pc가 트래픽이 허용하는 만큼 단일한 특정주소로 공격이 들어오는 경우
 가장 잘 발생하는 공격패턴이며, 보통 공격시 같은 아이피에서 1초에 3~10번가량을 페이지 Access 하므로 이를 추려낸다.

 

 ㄴ. 1000대가 각각 한번씩만 특정 주소를 엑세스하는경우
 거의 발생하지 않는 경우지만 정교하게 제어가 가능한 좀비pc라면 이런 패턴으로 공격이 들어올 수도 있다.
 이경우 검출 시간을 늘려서 IP를 체크하거나  IP로 비교하는 대신에 특정 주소로 비교를 하여

해당 주소로 공격이 들어감을 추릴 수 있다.  다소 검출에 까다로우므로 로그를 분석후 적용할 규칙을 정하도록 한다.

간혹 특정 주소도 순차적으로 바꿔가면서 엑세스 하는 경우가 있으나 대부분 숫자만 바꿔가거나(/test/test.html?id=1 ~ 1000), 

50개 이내의 주소를 번갈아가면서 공격하는 식이다.(ex : /test/test1.html~test50.html)

 

8번 라인은 방화벽에 등록할 IP내용이다.방화벽 단계에서 DROP하도록 한다.
%-A INPUT -s 192.168.10.1 -j DROP
구절이 완성되고 oops-firewall인 경우 user.conf에 등록시키도록 한다. (기본 iptable의 경우 iptable 설정에 등록시킨다.)

9번 라인은 공격으로 간주한 Pattern을 표기한것이다.

 

이후 자동으로 DDOS를 막기 위해 비교식을 추가로 더 넣어볼 수도 있다.

httpd 프로세서의 수를 검출해서 이 수치가 지정된 수치보다 더 커지는지를 감지하거나
(ex : httpdCnt=`ps -ef | grep ‘httpd’ | wc -l`)
네트워크 접속수치를 확인하여 이 수치가 지정된 수치보다 커지는지를 감지
(ex : connUserCnt=`netstat -na | grep ‘ESTABLISHED’ | wc -l` )

위의 방법을 응용하여 방어 방법을 마련할 수도 있다.

 

5. 마치며

DDOS의 가장 확실한 해결책은 모든 좀비PC를 차단하는 것이라 생각된다.

차단된 좀비PC가 실제 사이트 이용자인지 아닌지를 판단하여 적절한 보안대책을 설명해주도록 한다.

물론 차단된  IP를 풀어줄때도 충분히 고려하고 풀어주도록 하며, 섣부른 패턴 판단은 금물이니

꼼꼼하게 패턴을 판단해서 DDOS공격과 일반 사용자를 구분하도록 한다.

 

 

 

]]>

]]>
https://cena.co.kr/blocking-ddos-attack-in-linux-apache/feed/ 0
리눅스 호스트네임 변경 & SSH 서비스 포트 변경(Linux hostname & port change) https://cena.co.kr/linux-hostname-and-service-port-change/ https://cena.co.kr/linux-hostname-and-service-port-change/#respond Wed, 29 Sep 2010 01:50:07 +0000 http://old.cena.co.kr/17402

관리자 권한일때.

 

1. 호스트네임 변경 (PrevHostname 을 CEnAHostname으로 변경하고자 할때)

 

ㄱ. vi /etc/sysconfig/network

 

NETWORKING=yes
HOSTNAME=PrevHostname     // GATEWAY=192.168.1.1

 

ㄴ. vi /etc/hosts

 

# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1               PrevHostname localhost.localdomain localhost //

 

ㄷ. hostname CEnAHostname

 

ㄹ. service network restart

 

2. SSH 서비스 포트변경

 

주의사항 : 기본 ssh 서비스 포트 변경시 원격에서 작업하는경우 대단히 위험하므로 기존에 방화벽이 설치된 경우라면 꼭 변경이후에도 원활한 접근이 되도록 방화벽 작업을 사전에 해두는게 좋다.

 

# ssh 포트를 22 -> 2222로 변경코자 할때, CentOS 기준

 

ㄱ. vi /etc/services

 

ssh             22/tcp                                # CEnA SSH Remote Login Protocol , 22를 2222로 변경
ssh             22/udp                                # CEnA Remote Login Protocol , 22를 2222로 변경

 

ㄴ.  아래 두개 파일에서 port 항목을 변경하고자 하는 포트로 변경

 

vi /etc/ssh/ssh_config

vi /etc/ssh/sshd_config

 

ㄷ. /etc/init.d/sshd restart로 sshd 재시작

 

]]>
https://cena.co.kr/linux-hostname-and-service-port-change/feed/ 0
rsync를 이용한 서버간 백업 https://cena.co.kr/backup-between-servers-using-rsync/ https://cena.co.kr/backup-between-servers-using-rsync/#respond Tue, 12 Aug 2008 02:35:05 +0000 http://old.cena.co.kr/17384

rsync는 서버대 서버 백업에 있어서 아주 빠르고 간편하게 원하는 디렉토리나 파일을 맞춰줍니다..
본인은 이 설명에 대한 책임을 지지 않으므로 설정이 필요한경우 충분히 읽어보고 설정하도록 하며, 글을 퍼가는것은 자유지만 출처는 꼭 명시바랍니다.(CEnA.co.kr)

늘 그렇듯 자세한 설명에서의 존칭어는 생략합니다.

rsync의 대략적인 동작이나 이용범위는 다음과 같다. 설명의 편의상 아래부터
원본이되는 Master서버는 A(192.168.10.1)
대상이되는 Slave 서버는 B(192.168.10.2) 서버로 지칭하겠다.

1. A서버와 B서버가 있는 상황에서 B서버를 미러 서버로 이용하는 경우 두 서버의 상태를 동일하게 맞추는데 요긴하게 사용된다.

2. rsync는 “파일이 변경된 사항이 있을경우” 그 변경이 있었던 파일에 대해서 새롭게 복사해오는 구조이다. 물론 A서버에는 존재하고 B서버에는 존재하지 않는 파일이라면 B서버로 새롭게 복사해오는 구조이다.

다음의 예를 보자.

ㄱ.A서버의 대상 디렉토리
/home/testuser/

ㄴ. A서버 해당 디렉토리내 파일
test1.sql
test2.php
test3.tar.gz

ㄷ. B서버의 대상 디렉토리
/home/testuser/

ㄹ. B서버 해당 디렉토리내 파일
test1.sql

ㅁ. B서버에서 rsync를 했을때의 동작
test1.sql이 A,B서버가 동일한건지 비교, 같지 않으면 B로 가져온다 -> test2.php,test3.tar.gz 는 파일 자체가 존재하지 않으므로 바로 B로 가져온다.

ㅂ. rsync가 완료되고 나서 A,B의 내용이 동일한경우 다시 rsync를 돌리게 되면?
– 변경사항이 없는한 가져오는 내용은 없다.

———–설 정 부 분 ————————————-

설정 서버는 AnnyungLinux를 기준으로 하며, 설정 방법은 다음과 같다.
(아래로 내려가는 진행상황대로 하면 된다.)

[ 공통 설정 ]
1. 패키지 설치 :
AnnyungLinux의 경우 패키지 설치 : pkgadd -u rsync
CentOS, 페도라등 Yum이 지원되는경우 : Yum install rsync
컴파일 설치의 경우는 소스를 적절히 검색해서 다운받아 설치하도록 한다.

2. rsync 설정 수정 :
설치가 되고 나서는 다음 옵션을 변경해준다.
– /etc/xinetd.d/rsync 에서 disabled를 no로 변경

3. PORT 확인 : /etc/services 에서 873번 port 주석처리 제거
rsync는 get 방식으로 “긁어오는” 구조이다. 방화벽등의 설정에서 포트가 막혀 있다거나 하는 사항들에 대해서도 확인을 반드시 하기 바란다.

3. 재시작 : /etc/rc.d/init.d/xinetd restart

4. 시작확인(port:873) : netstat -anp | grep ‘LISTEN’
또는 방화벽등의 status를 찍어봄으로 확인 가능하다.

[마스터 192.168.10.1 서버(A서버)]
1. SSH 디렉토리 생성  : mkdir /root/.ssh(숨은디렉토리)

2 sshd_config 수정 :  PermitRootLogin yes
잠시 루트로그인을 열어주도록 한다. 어짜피 설정 다 되면 다시 닫는다.

3. sshd 재시작 :
/etc/rc.d/init.d/oops-firewall restart

[슬레이브 192.168.10.2 서버(B서버)]

1. SSH 디렉토리 생성 : mkdir /root/.ssh(숨은디렉토리)

2. 개인키, 공개키 생성 : ssh-keygen -t rsa -b 2048 -f 2_dsa
: 2_dsa, 2_dsa.pub 생성 확인 후 /root/.ssh/로 이동
– 편의상 앞의 2는 아이피에서 따온것임을 유념.

3. 2_dsa.pub 는 A 서버의 /root/.ssh/authorized_keys 로 복사
: scp -p /root/.ssh/2_dsa.pub 192.168.10.1:/root/.ssh/authorized_keys

[A 서버]
1. authorized_keys 파일 생성 확인 : /root/.ssh/authorized_keys

2. sshd_config 수정 :
sshd_config : PermitRootLogin forced-commands-only
– 이렇게 설정하게 되면 root 로그인의 경우 키를 이용해서만 로그인이 가능하며
그렇지 않은경우는 no로 설정한것과 같다.

3. sshd 재시작 : /etc/rc.d/init.d/oops-firewall restart

4. authorized_keys 수정 (중요!!)

– 원본의 상태
——————————————————–
ssh-rsa AAAXXXXXx ….XXXXX== root@test.com
—————————————————
– 추가되는 부분
——————————————————–
from=”192.168.10.2″,command=”/root/validate-rsync” ssh-rsa AAAXXXXXx…XXXXXX== root@test.com
—————————————————

5. /root/validate-rsync 파일 생성 : 반드시 실행권한(chmod 755 /root/validate-rsync)이 있어야 함
아래의 스크립트는 특수문자등을 통한 보안상의 문제를 방지하는데 그 목적이 있다.

#!/bin/sh

case "$SSH_ORIGINAL_COMMAND" in 
*\&*) 
echo "Rejected" 
;; 
*\(*) 
echo "Rejected" 
;; 
*\{*) 
echo "Rejected" 
;; 
*\;*) 
echo "Rejected" 
;; 
*\<*) 
echo "Rejected" 
;; 
*\`*) 
echo "Rejected" 
;; 
rsync\ --server*) 
$SSH_ORIGINAL_COMMAND 
;; 
*) 
echo "Rejected" 
;; 
esac

[ B 서버]

1. 접속테스트 : rsync -avz -e “ssh -i /root/.ssh/2_dsa” 192.168.10.1:/home/httpd/ /home/httpd/
(** 디렉토리가 경로의 끝일 경우 ‘/’ 를 해줘야 함)

2. cron 설정 : 00 * * * * rsync -avz –delete -e “ssh -i /root/.ssh/2_dsa” 192.168.10.1:/home/httpd/ /home/httpd/
(매시 정각마다 실행)

마치며:
미러 서버를 운용하는데 요긴하게 사용될 수 있으며, 더 많은 정보는
http://samba.anu.edu.au/rsync/ 를 참조하기 바란다.

]]>
https://cena.co.kr/backup-between-servers-using-rsync/feed/ 0
MySQL Replication 각종 에러 대처법 https://cena.co.kr/mysql-replication-troubleshootings/ https://cena.co.kr/mysql-replication-troubleshootings/#respond Fri, 18 Jul 2008 08:51:29 +0000 http://old.cena.co.kr/17351

http://hanaduri.egloos.com/19119/ 

리플리케이션이 오류로 인해 더이상 진행되지 않는 상황에서 포지션값을 강제 조정하는 방법은 다음과 같다.

ㄱ, Slave DB에서 show slave status; 로 상태를 확인한다.
에러 발생시 Read_Master_Log_Pos 값과 Exec_masterlog_pos 값이 차이가 나며 더이상 올라가지 않는다. 해당 에러 사항은 Last Errono와 Last_error를 참조한다.

샘플은 다음과 같다.
mysql> show slave status;
——————————————————————————–
| Master_Host    | Master_User | Master_Port | Connect_retry | Master_Log_File | Read_Master_Log_Pos | Relay_Log_File                | Relay_Log_Pos | Relay_Master_Log_File | Slave_IO_Running | Slave_SQL_Running | Replicate_do_db     | Replicate_ignore_db | Last_errno | Last_error | Skip_counter | Exec_master_log_pos | Relay_log_space |
——————————————————————————–

| 192.168.0.1 | replsvr     | 3306        | 60            | replication.030 | 101319330           | slavedb-relay-bin.006 | 311434018     | replication.030       | Yes              | Yes               | aDatabase,bDatabase |                     | 0          |            | 0            | 101319330           | 311434018       |
——————————————————————————–

ㄴ.위의 샘플에서 Exec_master_log_pos가 101319330에서 멈췄다면 Master DB에서 다음 사항을 확인한다.

## replication.030은 마스터로그파일, 101319330은 포지션값, limit는 포지션을 기준으로 행해진 작업을 3개 본다는 소리이다.

mysql> show binlog events in ‘replication.030′ from 101319330 limit 3;
——————————————————————————–
| Log_name        | Pos       | Event_type | Server_id | Orig_log_pos | Info                                                                                                                                         |
——————————————————————————–
| replication.030 | 101319330 | Query      | 1         | 101319330    | use `aDatabase`; UPDATE test SET money = money – 10 WHERE userid=’testuser’                                                                  |
| replication.030 | 101319428 | Intvar     | 1         | 101319428    | INSERT_ID=12256338                                                                                                                           |
| replication.030 | 101319456 | Query      | 1         | 101319456    | use `aDatabase`; INSERT INTO testlog (userid, money, code, cdate) VALUES (‘easytour’, ‘300’, ‘001’, 1216370157) |
——————————————————————————

만약 101319330의 쿼리에서 문제가 생겨 동작을 하지 않을때 정상 동작이 될것이라 예상되는 101319456 포지션으로의 변경은 다음과 같다.

##slave DB에서 다음작업을 행한다 ##
mysql> slave stop;   <-리플리케이션을 일단 중단한다.
mysql> change master to master_log_file=’replication.030′, master_log_pos=10139456;
mysql> slave start;

change master to  명령어는 master_log_pos 외에도 여러가지 설정값들에 대해서 변경이 가능하다.

상당히 많은 양이 에러로 인해 손실되었을 경우는 마스터와 슬레이브간의 데이터 동기화를 새로 하고 리플리케이션을 각각 구동해주는것이 좋다.

또한 리플리케이션 사용시 유용한 명령어들은 다음과 같다.

## 하나두리(http://hanaduri.egloos.com/19119/)님의 이글루스 내용을 참조했습니다.

Replication에 쓰이는 SQL 명령어

다음은 replication에서 사용되는 SQL 명령어의 요약이며, 괄호내의 slave, master는 master
서버와 slave 서버에서 실행됨을 의미한다.

START SLAVE             slave 스레드를 시작함(slave)

STOP SLAVE              slave 스레드를 중지함(slave)

SET SQL_LOG_BIN=0|1     SUPER 권한을 가진 사용자가 접속할 때 bin log의 사용 하용 여
부(master)

SET GLOBAL SQL_SLAVE_SKIP_COUNTER=n
master로부터 n 개의 이벤트를 경과토록 함.(slave)

RESET MASTER            모든 binary log를 삭제하고, binlog index 파일을 리셋함.(master) 구버전의 FLUSH MASTER임

RESET SLAVE             slave에게  master log에 있는  replication 위치를  잊게 하며,
master.info와 relay-log.info 파일을 지움(slave), 구버전의 FLUSH SLAVE임

LOAD TABLE tbl_name FROM MASTER
master에서 slave로 tbl_name을 복사함(slave)

LOAD DATA FROM MASTER
master에서 slave로 데이터를 복사함(slave)

CHANGE MASTER TO master_def_list
master_def_list로 지정한 값으로 master의 변수를 변경함(slave).
master_def_list는 컴마로 분리하며 다음과 같다.
MASTER_HOST, MASTER_USER, MASTER_PASSWORD,
MASTER_PORT, MASTER_CONNECT_RETRY,
MASTER_LOG_FILE, MASTER_LOG_POS
(예: CHANGE MASTER TO
MASTER_HOST=’master2.mycompany.com’,
MASTER_USER=’replication’,
MASTER_PASSWORD=’bigs3cret’,
MASTER_PORT=3306,
MASTER_LOG_FILE=’master2-bin.001′,
MASTER_LOG_POS=4,
MASTER_CONNECT_RETRY=10;

MASTER_POS_WAIT()       master의 binlog가 지정한 위치에 도달할 때까지 기다리도록 하는
함수(slave)

SHOW MASTER STATUS      master의 binlog의 상태정보를 보여줌(master)

SHOW SLAVE HOSTS        master에 등록된 모든 slave의 목록을 보임(master)

SHOW SLAVE STATUS       slave의 상태정보를 보여줌(slave)

SHOW MASTER LOGS        binary log의 목록을 보여줌(master)

SHOW BINLOG EVENTS      binary log의 event를 보여줌(master)
사용법 : SHOW BINLOG EVENTS [IN ‘logname’] [FROM pos] [LIMIT [offset,] rows]

SHOW NEW MASTER FOR SLAVE
새로 접속할 수 있는 master를 보여줌(slave)
사용법 : SHOW NEW MASTER FOR SLAVE WITH MASTER_LOG_FILE=’logfile’  AND MASTER_LOG_POS=pos AND MASTER_LOG_SEQ=log_seq AND MASTER_SERVER_ID=server_id

PURGE [MASTER] LOGS     지정한 bin log나 지정한 날짜 이전의 bin log 파일을 삭제함(master)
사용법 : PURGE [MASTER] LOGS TO ‘logname’; PURGE [MASTER] LOGS BEFORE ‘date’

【예제】
mysql> SHOW MASTER STATUS;
+————–+———-+————–+——————+
| File         | Position | Binlog_do_db | Binlog_ignore_db |
+————–+———-+————–+——————+
| unix-bin.016 | 168      |              |                  |
+————–+———-+————–+——————+

mysql> SHOW MASTER LOGS;
+————–+
| Log_name     |
+————–+
| unix-bin.001 |
| unix-bin.002 |
……
| unix-bin.015 |
| unix-bin.016 |
+————–+
=======================================================================
하나두리(http://hanaduri.egloos.com) 님의 이글루스는 링크를 참조하세요

]]>
https://cena.co.kr/mysql-replication-troubleshootings/feed/ 0
Arp Table의 이해(네트워크가 잘 안잡힐때) https://cena.co.kr/understanding-arp-table/ https://cena.co.kr/understanding-arp-table/#respond Mon, 11 Jun 2007 00:37:24 +0000 http://old.cena.co.kr/17363

얼마전 IDC에서 서버작업을 하는데 할당된 IP가 부족한 일이 발생하였다.

기존에 IP를 두개 사용하던 서버에서 한개로 전환하고 남는 IP를 새로운 서버에 적용하였다.
그런데 뭔가 이상한 증상이 생긴다.

1. 외부서버 -> 새로운서버로 접속을 시도시 맨 처음 접속이 되자마자 끊겨버린다. 그뒤 접속이 되지 않는다.
2. 새로운서버 -> 외부서버로 접속시도시 접속 되고나서 콘솔창이 먹통이 된다.

새로운 서버의 방화벽은 전부 꺼져있는데 왜 이런 증상이 생길까.
해답은 ARP에 있었다.

ARP(Address Resolution Protocol) : IP->MAC Address로 전환

내가 겪었던 상황을 보자.

==================================================================
서버 A, B가 있고 이 두개의 서버는 같은 게이트웨이를 이용한다.

A: 192.168.10.100(00:0A:0B:52:23:32)

||                                   -> Router – 192.168.10.1
V                                           (3A:3F:4C:52:18:1A)
B: 192.168.10.101(10:2A:3C:42:32:17)
==================================================================

A에서 B로 가는 패킷에서는 다음과 같은 과정을 거친다.
1. A -> B로 발송하기 위한 IP주소(이는 통신하기위해서 1차적으로 연결대상인 상대방의 아이피를 입력받는다)
2. A의 ARP 모듈에서 B의 IP를 입력받아 MAC주소를 반환.

즉 A와B의 통신에서는 IP뿐만이 아닌 MAC주소까지 얻어야 되는 상황.
그런데 이와 같은 치명적인 문제가 발생하였다.

B의 기존 IP 192.168.10.101은 또 다른 서버 C의 eth1에서 쓰고 있었으며,
현재 C서버는 다음과 같이 동작하고 있었다.
eth0 : 192.168.10.103
eth1 : 켜졌으나 아이피 할당안됨
즉 ifdown eth1등의 동작이 없어 아이피는 할당되지 않았으나
실제로 선의 연결/네트워크 카드는 동작중이다.

ifdown eth1로 C의 eth1을 완전 죽이고 내부에서 테스트를 한다.
(switch에서는 다른 MAC을 가진 NIC에서 동일한 IP가 올라오니 헛갈릴수가 있다.)

버그등으로 잘 되지 않을때는 ifconfig eth1 down 등으로 device를 내리고
A 서버에서도 모든 디바이스를 죽인후 새로 아이피를 먹일 eth0만 활성화를 시킨후
Gateway까지 핑이 가면 다음과 같이 테스트를 한다.

arping -c 30 -l eth0 -s IPAddress Gateway_IP
(-c는 시도 회수)

보통의 경우 자동으로 갱신되지만 특별한 경우 ARP Table을
강제적으로 갱신해줘서 해결볼수 있다.

]]>
https://cena.co.kr/understanding-arp-table/feed/ 0
MySQL Replication 개요 https://cena.co.kr/mysql-replication-summary/ https://cena.co.kr/mysql-replication-summary/#respond Mon, 19 Jun 2006 09:52:18 +0000 http://old.cena.co.kr/17327

MySQL Replication 개요

– 해당 글은 MySQL 4.0.x 버전에서 테스트후 작성된 글이며
공식적으로 Replication기능은 3.23 이상의 버전부터 지원되는것으로 알고 있습니다.
– 빠른 글 설명을 위해 대부분의 존칭은 생략합니다.

1. Replication 의 개요 & 필요성

나는 회사 서버에서 실제로 사용해본 데이터베이스는 MySQL과 MSSQL정도로만 압축되며,
현재 회사 서비스의 메인데이터베이스는 모두 MySQL로 이루어져있다.

좀 지난이야기이지만 데이터베이스가 엉켜(?)서 MySQL내의 특정 테이블이 말소되어버린적이 있다.
혹은 phpMyAdmin같은 웹 데이터베이스 관리 프로그램이나 MySQL-Front같은 어플리케이션 관리도구등을 사용한다면
버튼하나, 링크하나잘못 클릭해서 데이터베이스가 통째로 날라갈수가 있다.

그런데 일반 pc에서 하드포맷이나 데이터 삭제시
도스시절 unformat이나 undelete, finaldata 등등의 여러가지 방법으로 복구를 했던반면
데이터베이스는 한번 날라가면 끝이다.

데이터베이스의 보존방법은 크게 Dump를 이용한 방식과 Replication을 이용하는 방식이 있는데
두가지의 분명한 장단점이 존재한다!

ㄱ. Dump를 이용한 데이터베이스 백업의 장단점
– 문제가 생겼을때 특정 시점으로의 복원이 가능하다(덤프 받아놓은 날짜의 데이터베이스로 돌려놓을수 있다.
– 한번 덤프를 받을때 데이터가 많을수록 덤프 시간은 기하급수적으로 늘어난다.
– 한번 덤프를 받아놓은것들이 누적되면 용량이 장난아니게 불어난다.

ㄴ. Replication을 이용한 데이터베이스 백업의 장단점.
– 실시간으로 데이터를 옮겨적기때문에 원본 데이터베이스에 문제가 발생해서 서비스를 중단할 경우에도 리플리케이션서버로 대처가 가능하다.
– 특정시점으로의 복원은 불가능하다.
– Replication에 사용하는 Log를 주기적으로 비워주지 않으면 용량의압박이 상당하다.

위에서도 볼수있듯, 두가지의 가장큰 차이점은 특정시점으로의 복원여부, 그리고 실시간 백업이다.
그래서 나의 경우는 두가지 백업을 모두 애용하는 편이며, Replication은 이제 없으면 허전한 그런것이 되어버렸다.
리플리케이션의 구현시, 장점은 위에 있는게 전부가 아니다.
원본 데이터베이스(master)는 쓰기만 하고, 쿼리문 등으로 데이터베이스를 읽는 작업은 Slave에서 처리해도 가능한,
효율적인 분산작업을 위해서도 필요한것이다.

2. Replication의 설정

리플리케이션에서는 하드 IDE시절 수도없이 작업했던 Master, Slave의 개념만 잘 알고 있으면 된다.
Master는 원본데이터베이스, Slave는 백업받는 대상 데이터베이스라고 생각하면 되며, 일반적으로 알려진 리플리케이션의 설정은 다음과 같다.

(리눅스버전, MySQL 4.0 기준 설명)

ㄱ. Master의 설정
일단 처음부터 쉽게 생각하려면, Replication의 기본 구성은 다음과 같다.

a. Master에서는 데이터베이스에서 일어나는 모든 작업을 Log에 기록하게 되며, 해당 로그는 Postion 값을 가지고 있다.
b. Slave에서는 Master에 설정되어 있는 계정으로 접근하여 Master의 정보를 보게되며, Log의 Postion값을 읽어들여, 어디까지 가져왔는지를 알아내서
포지션값을 갱신하면서 데이터를 계속 긁어온다.

윗말을 정리하자면 Master는 값을 계속 기록만 하고, Slave에서는 Master로 접근후에 데이터를 계속 가져오기만 한다.
그럼 Slave에서 Master로 연결하기 위한 계정 설정은 Master에서 만들어주는것이며, 계정설정은 다음과 같은 방법으로 Master에 기록하게 된다.

GRANT file ON *.* TO 리플리케이션아이디@’아이피.아이피.아이피.아이피’ IDENTIFIED BY ‘패스워드’

권한 설정을 할때 file대신 All privileges 권한을 줘도 무방하긴하지만, 어짜피 file에 대해서만 긁어오는 작업을 수행하므로, 기타 권한에 대해 주는것은 불필요하다
또한 아이피부분 역시 %로 대처할수도 있으나, 대부분의 리플리케이션은 같은 네트워크안에 속해있는 서버끼리 작업하는게 보통이므로 아이피는 적어주는게 좋다.

권한 설정은 다 되었으므로, my.cnf에 대한 설정방법은 다음과 같다.
(윈도우 버전은 my.ini의 설정을 고치면 된다.)

——————-/etc/my.cnf————————–
[mysqld]
……

# MySQL 의 리플리케이션 기능을 사용하기 위한 binary log 설정
log-bin = /mysqltemp/log/replication.log
server-id   = 1
binlog-do-db = 데이터베이스1
binlog-do-db = 데이터베이스2
——————————————————–

log-bin = 파일경로/파일이름
입력하지 않는경우 기본적으로 Mysql의 Lib Directory에 기록이 된다.
해당 로그가 쌓이게될때 용량을 무시할 수준이 아니므로 기억하기 좋은 위치로 지정해서 사용하기 바란다.

server-id = 번호
해당 아이디의 숫자는 고유한 숫자를 입력해야되며 중요한건 slave와 id가 틀려야 한다.

binlog-do-db = 데이터베이스1
해당 MySQL내에서 여러 데이터베이스중 Replication을 할 데이터베이스를 적어준다.
데이터베이스가 다수인경우 해당 구절을 계속 추가해야되며,
binlog-do-db = 데이터베이스1,데이터베이스2 식으로 추가하는건 동작하지 않는다고 알려져있다.

ㄴ. Slave의 설정
Slave에서는 아까도 이야기 했듯 Master로 접근후에 데이터베이스를 가져오기만 하므로 별도의 계정생성이 필요없으며
my.cnf 설정파일을 수정하는것으로 작업이 완료된다.

——————-/etc/my.cnf————————–
[mysqld]

……

server-id       = 2
master-host     = 아이피.아이피.아이피.아이피
master-user     = 리플리케이션아이디
master-password = 패스워드
replicate-do-db = 가져올 데이터베이스1
replicate-do-db = 가져올 데이터베이스2
master-port     = 3306
——————————————————–

slave설정시 Master와 틀린건 가져올 마스터 데이터베이스의 아이피를 적어줘야한단것과(어디서 읽어올지는 알아야하니까)
접근에 필요한 계정(아까 GRANT file On…으로 생성한 계정의 아이디/패스워드)를 기록, 그리고 읽어들일 데이터베이스명
(Master의 binlog-do-db=데이터베이스1)을 기재해주어야 한다는것이다.

3. 동기화 팁
보통 리플리케이션은 백지상태에서 시작하기보다는 특정 데이터베이스가 돌아가고 있는 상황에서 리플리케이션 서버를 추가로 운영하는 경우로
발전되므로, 다음과 같은 두가지 처리방법이 있다.

※리플리케이션 동기화시에는 최대한 데이터베이스의 내용이 일치하는게 좋으므로, Master에서 더이상 DB의 입출력이 일어나지 않는 상태에서 작업하는것이 좋다.
즉. slave와 master의 mysql을 중단시켜놓고 작업을 하는것이 좋다.
(/etc/rc.d/init.d/mysql stop)

ㄱ. Dump를 이용하여 처리하는방법
– 데이터베이스를 덤프뜬후, Slave에서 Restore시키는 방식, 단점으론 시간이 굉장히 많이 소모되므로 추천하지 않는다.

ㄴ. MySQL 데이터 디렉토리를 통째로 옮기는 방법
– 권장하는 방식이며, 데이터베이스가 위치한곳 (/var/lib/mysql또는 /var/db같은…)을 통째로 압축해서 복사하거나, 아니면 그냥 복사하는 방식이다.
본인은 Linux(AnnyungLinux 1.2)서버에서 다른 리눅스서버(AnnyungLinux 1.2)로 옮길때 한번에 2기가 이상은 ftp에서 옮겨지지 않는 기현상(? 단일 파일 2G이상 생성 불가. 파티션형태…) 이 발생하여
다음과 같은 처리를 하였다.

a. tar cvfpz – sourcedirectory | split -b 1500m – databasebackup.tar.gz  (1.5G로 분할 압축) – Master에서 가져올 디렉토리를 압축
b. Slave에 접근후 ftp -> open 아이피.아이피.아이피.아이피, -> 압축파일 경로로 변경 -> get databasebackup.tar.gz
c. 가져온후 마스터측의 압축은 삭제, 복사작업등의 권한(chown,chmod)등은 적절하게 설정

4. 리플리케이션의 실제 동작명령

동기화가 완료되었다면 mysql에서 다음과 같은 명령어로 여러 동작들을 확인 가능하다.
(아이피는 임의처리하였다)

먼저 master 서버의 상태를 보자.

ㄱ. show processlist; – 현재 동작하고 있는 processlist를 확인가능하다.

mysql> show processlist;
+——–+———-+———————-+———+————-+——–+—————————————————————-+——————————————————————————————————+
| Id     | User     | Host                 | db      | Command     | Time   | State                                                          | Info                                                                                                 |
+——–+———-+———————-+———+————-+——–+—————————————————————-+——————————————————————————————————+
|      8 | replsvr  | ***.***.***.***:**** | NULL    | Binlog Dump | 747916 | Has sent all binlog to slave; waiting for binlog to be updated | NULL

ㄴ. show master status; – 리플리케이션 마스터의 동작 상태, 포지션값등을 알수있다.

mysql> show master status;
+—————–+———–+—————+——————+
| File            | Position  | Binlog_do_db  | Binlog_ignore_db |
+—————–+———–+—————+——————+
| replication.002 | 351161171 | test1, test2  |                  |
+—————–+———–+—————+——————+
1 row in set (0.00 sec)

여기서 중요한건 file에서 replication.002에 현재 기록중인것을 알고 있으며, slave측에서 001등을 다 가져온 상태라면 해당 로그(replication.001)는 지워도 무방하다.

slave의 상태는 다음과 같이 확인 가능하다.

mysql> show processlist;
+—-+————-+———–+——+———+——–+———————————————————————–+——————+
| Id | User        | Host      | db   | Command | Time   | State                                                                 | Info             |
+—-+————-+———–+——+———+——–+———————————————————————–+——————+
|  2 | system user |           | NULL | Connect | 748267 | Waiting for master to send event                                      | NULL             |
|  3 | system user |           | NULL | Connect | 8      | Has read all relay log; waiting for the I/O slave thread to update it | NULL             |

ㄷ. 동일하게 show slave status로 slave의 상태와 포지션값을 알수있다.(아이피, port 임의처리)

mysql> show slave status;
+—————-+————-+————-+—————+—————–+———————+——————————-+—————+———————–+——————+——————-+—————–+———————+————+————+————–+———————+—————–+
| Master_Host    | Master_User | Master_Port | Connect_retry | Master_Log_File | Read_Master_Log_Pos | Relay_Log_File                | Relay_Log_Pos | Relay_Master_Log_File | Slave_IO_Running | Slave_SQL_Running | Replicate_do_db | Replicate_ignore_db | Last_errno | Last_error | Skip_counter | Exec_master_log_pos | Relay_log_space |
+—————-+————-+————-+—————+—————–+———————+——————————-+—————+———————–+——————+——————-+—————–+———————+————+————+————–+———————+—————–+
| ***.***.**.*** | replsvr     | ****        | 60            | replication.002 | 355000057           | wisereplication-relay-bin.003 | 355000141     | replication.002       | Yes              | Yes               | test1,test2     |                     | 0          |            | 0            | 355000057           | 355000141       |
+—————-+————-+————-+—————+—————–+———————+——————————-+—————+———————–+——————+——————-+—————–+———————+————+————+————–+———————+—————–+

이때 중요한것은 master status와 slave status를 봤을때 읽어들이는 파일명(위에서는 replication.002)와 Postion을 비교해서 차이가 나지 않으면 성공한것이다.

ㄹ. 그외 명령어

reset Master;
reset slave;
위의 명령어로 둘의 포지션값과 로그파일 생성을 초기화 시킬수 있다.

slave stop;
master stop;
위의 명령어로 리플리케이션 서버의 동작정지를 시킬수 있다.

slave start;
master start;
위의 명령어로 리플리케이션 서버의 정지를 해제하고 다시 가동시킬수 있다.

5. 그 외의 환경 실험.
예전 리플리케이션을 구현할때 4.0과 4.1에서도 서로 리플리케이션이 가능했다.
4.0과 5.0간에는 테스트 해보지 않았으나 충돌이 발생할 확률이 지대일듯 하다.
(가급적 같은 버전을 쓰자?)
또한 리눅스(master), 윈도우즈(slave)같은 환경에서도 제대로 동작했다.
(운영체제는 가리지 않는다. 단지 윈도우즈/MySQL 조합은 그리 권장하는 조합이 아니란건…)

6. 끝으로
얼마전 윈도우즈 서버 해킹으로 인해 윈도우즈의 스케쥴 관리 기능을 이용해 매일 특정시간 주기적으로 데이터베이스를 덤프했는데
둘다 리눅스 머신으로 바뀌면서 Crontab, 쉘스크립트등의 사용법을 몰라서 아직 매일 Dump작업을 못하고 있는 실정이다.

다음 강좌에서 저말고 누군가 리눅스에서 crontab을 쓰는방법과 쉘스크립트 작성법등을 강좌 해주면 캐감사하겠다.

]]>
https://cena.co.kr/mysql-replication-summary/feed/ 0