'트래픽분산'에 해당되는 글 2건

  1. 2012.10.25 iptables 방화벽 및 라우팅, 트래픽 분산 (2)
  2. 2009.11.19 DNS와 GSLB(Global Server Load Balancing) (1)
2012. 10. 25. 16:04

iptables 방화벽 및 라우팅, 트래픽 분산

 

 



1.iptables 개요 
2.패킷의 흐름 
3.NAT 구성 방법 
4. PORT 포워딩 
5.iptables를 이용한 방화벽 구축 
6.Routing 분석 
7.트래픽 분산 


1.iptables 개요 
iptables은TABLE, CHAIN, TARGET의 요소를 가지고 있다. 
TABLE 분석--------------------------------------------- 
- mangle, nat , filter 3개의 테이블이 있으며, 테이블을 명시하지 않고 사용할 경우에는 filter가 기본값이 된다. 
- 3개의 테이블은 고유한 특성을 가지고 있으며, 정리하면 다음과 같다. 
mangle : 패킷이 맨처음 들어왔을 경우에 제어가 가능하며, 패킷의 차단과 허용을 포함하 
라우팅 전,후에 규칙을 적용할 수 있다. 
nat : 패킷의 해더를 검사하여 소스와 목적지의 아이피 변환을 목적으로 한다. 
filter : mangle과 비슷하나, nat로 나가는 패킷을 제외한 것의 차단과 허용을 목적으로 
한다. 

CHAIN 분석--------------------------------------------------------- 
- 각 테이블마다 체인이 구성되어 있으며, 기본적으로 INPUT, FORWARD, OUTPUT이 있고, nat, mangle에는 PREROUTING, POSTROUTING의 체인이 추가되어 있다. 
- Iptables –L명령어로 체인 리스트를 확인할 수 있으며, 괄호 안에 기본 정책이 명시되어 있다. 

코드:
[admin@router admin]$ iptables -L 
Chain INPUT (policy ACCEPT) 
target     prot opt source               destination 

Chain FORWARD (policy ACCEPT) 
target     prot opt source               destination 
TCPMSS     tcp  --  anywhere             anywhere           tcp flags:SYN,RST/SYN TCPMSS clamp to PMTU 

Chain OUTPUT (policy ACCEPT) 
target     prot opt source               destination


- 각 체인은 한줄로 한가지씩 규칙을 가지고 있으며, 규칙은 무조건적으로 정할 수 있는 것이 아니라 각 체인의 특성에 따라 정할 수 있다. 
체인의 흐름을 보면 
PREROUTING -> INPUT( FORWARD) -> OUTPUT -> POSTROUTING의 순서로 패킷이 이동하면서 규칙에 적용된다. 
FORWARD 체인을 중심으로 왼쪽은 들어오는 패킷을 제어할 수 있으며, 오른쪽은 나가는 패킷을 제어한다. 
만약에 PREROUTING 체인에서 나가는 패킷을 제어하고자 규칙을 작성한다고 해도 규칙이 적용되지 않는다. 
코드:
iptables  -t mangle -A PREROUTING -o eth0 -s 192.168.1.1 -j DROP 
iptables v1.2.7: Can't use -o with PREROUTING

에러가 나면서 적용되지 않는다. 
또한, 체인은 –N옵션을 이용하여 새로 만들고 –X옵션을 이용하여 삭제할 수 있다. 
코드:
iptables -t manlge -N
(일반적으로 대문자를 사용) 

TARGET 분석------------------------------------------------------- 
Chain INPUT (policy ACCEPT) 
target prot opt source destination (빈칸) 

각체인의 규칙은 target을 어떻게 정하는 가가 기본이며, 각 타켓의 특성을 보면 
ACCEPT : 패킷을 허용한다.

DROP : 패킷을 차단한다.
REJECT : 패킷을 거부한다. 
RETURN : 패킷을 맨 아래 규칙으로 내린다. 
MARK : 패킷에 마크를 표시한다. 
LOG : 로그를 남긴다.(/var/log/messages) 
MASQUERADE : 패킷의 출발지를 나가는 장치의 아이피로 바꾼다. 
SNAT : 패킷의 출발지를 지정한 아이피로 바꾼다. 
DNAT : 패킷의 도착지를 지정한 아이피로 바꾼다. 

***타겟은 사용할 수 있는 테이블이 다르며, 테이블에 맞게 사용하여야 한다. 

기타 --------------------------------------------------------------- 
prot : ip 프로토콜( -p) tcp,udp 
opt : 장치 (-o 나가는 장치, -i 들어오는 장치) eth0, ppp0 
source : 출발지 주소 ( -s ) 
destination : 도착지 주소 (-d) 




2. 패킷의 흐름 (그림참조) 


3. NAT 구성방법 

- NAT 구성이라고 함은 일반적으로 아이피를 공유하는 방법이다. 

NAT를 구성하기 전에는 linux 의 시스템 셋팅중에 ip_forward를 활성화 시켜주어야 한다. 
코드:
 echo 1 > /proc/sys/net/ipv4/ip_forward


WAN구간이 eth1 이라고 가정할 때 , 

-- 고정된 아이피가 있는 경우 
코드:
iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to 111.111.111.111


-- 유동 아이피인 경우 
코드:
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE







4. PORT 포워딩 

사설대역에서 외부로 서비스를 하고 싶을 때 라우터에서 특정 포트를 정해진 사설아이피로 보내주어 서비스가 가능하도록 한다. 
또한, 특정포트를 숨기고 싶을 때, 라우터의 loop 아이피로 패킷을 보내 속일수도 있다. 

예) 172.16.100.1 에서 MSSQL 서비스를 하고 싶은 경우 

코드:
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 1433 -j DNAT --to 172.16.100.1



5. iptables를 이용한 방화벽 구축 

POLICY-------------------------------------------------------- 
-각 체인은 정책을 가지고 있으며, 정책에 따라서 적절한 규칙을 적용시켜야 한다. 
(임의로 만든 체인은 정책을 가질 수 없다.) 

-기본적으로 모든 체인은 ACCEPT 를 정책으로 가지고 있으며, 
iptables -P 의 명령으로 정책을 변경시킬 수 있다. 
코드:
iptables -P INPUT DROP


-패킷이 들어와서 각 테이블을 지나가게 되며, 체인규칙을 적용받는다. 

만약 정책이 ACCEPT 이고 특별한 규칙이 정해져있지 않다면, 다음 테이블로 이동하게 된다. 
ACCEPT는 패킷을 허용한다는 의미 보다는 다음 테이블로 이동시킨다는 표현이 더 적절하다. 
DROP 은 다음 테이블로 가는 것을 차단한다. 

예를 들어 우선순위가 먼저인 INPUT의 정책을 DROP 으로 하고 OUTPUT에서 아무리 ACCEP를 한다고 하여도 INPUT에 허용할 예외규칙을 정하지 않는다면 패킷은 DROP 된다. 
예1) 소스가 192.168.1.1을 제외한 모든 패킷은 DROP 된다. 
코드:
iptables -P INPUT DROP 
iptables -A INPUT -s 192.168.1.1 -j ACCEPT


예2) 소스가 192.168.1.1을 제외한 모든 패킷은 ACCEPT 된다. 
코드:
iptables -P INPUT ACCEPT 
iptables -A INPUT -s 192.168.1.1 -j DROP


정책을 DROP으로 하는 경우는 드물며, 특별한 상황하에서 사용할 수 있다. 
예를 들어 DNS서버로만 운영하고 싶을경우 포트 53번 만을 허용하고 나머지는 모두 DROP시켜 불필요한 패킷이 들어오는 것을 막을 수 있다. 

필터링 순서------------------------------------------------------- 
패킷이 체인의 규칙에서 필터링 되는 과정은 맨위의 규칙부터 적용을 받는다. 
- 규칙 중간에 타켓을 ACCEPT, DROP, REJECT 를 만나면, 다음 규칙에 필터링되지 않고 다음 테이블로 건너 뛰게 된다. 

- 규칙 중간에 타켓을 신규로 만든 체인으로 만나면, 그 체인으로 이동하여 필터링 된 다음 다시 점프전의 체인내의 규칙으로 가서 순서대로 필터링 된다. 
- 신규로 만든 체인 내에서 타겟을 ACCEPT, DROP, REJECT를 만나면 다음 규칙에 필터링 되지 않고 , 다음 테이블로 건너뛰게 된다. 
- 규칙중에 MARK 가 중복되어 있을 경우에는 맨 마지막의 MARK 가 적용된다.(주의) 


6. 라우팅 분석 
코드:
root#route 
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface 
210.222.17.176  *                 255.255.255.240     U     0      0        0 eth0 
192.168.100.0    *                255.255.255.0        U     0      0        0 eth1 
127.0.0.0          *                255.0.0.0              U     0      0        0 lo 
default         210.222.17.177  0.0.0.0                UG    0      0        0 eth0


패킷은 위에서 아래로 이동 하면서 규칙에 맞는 라우팅이 있을 경우 바로 이동하여, 
다음 라우팅 룰을 적용받지 않는다. 
만약 맞는 라우팅이 없다면 default 라우팅이 적용되어 이동하게 된다. 

위에서 게이트웨이가 없는 것은 라우터 자신의 인터페이스가 이미 대역을 가지고 있는 경우이며, 라우터의 인터페이스가 가지고 있지 않는 대역을 라우팅 할 경우에는 게이트웨이를 반드시 입력하여야 한다.(gw) 

(네트워크 대역을 추가) 
코드:
route add -net 172.16.100.0/24 gw 210.222.17.177 dev eth1

(172.16.100.1/24 로 네트워크 대역을 다르게 입력하면 라우팅이 올라가지 않는다.) 

(특정 호스트를 추가) 
코드:
route add -host 172.16.100.100 gw 210.222.17.177 dev eth1


route add -net 172.16.100.100/32 gw 210.222.17.177 dev eth1(될까요?) 
(default 라우팅의 추가) 
코드:
route add default gw 210.222.17.177 dev eth0


같은 네트워크 대역이 있을 경우에는 메트릭이 낮은 룰이 적용된다. 
코드:
route add -net 192.168.1.0/24  gw 211.197.13.1 dev ppp0 metric 1 
route add -net 192.168.1.0/24  gw 211.197.13.1 dev ppp0 metric 3

(메트릭을 적용하지 않을 경우 기본 메트릭은 0 이다.) 


7. 트래픽 분산 

route 를 이용한 분산 
WAN 장치가 ppp0, ppp1이 있을 경우에 
코드:
route add -net 0.0.0.0/2 gw 211.211.211.211 dev ppp0 
route add -net 128.0.0.0/2 gw 222.222.222.222 dev ppp1

이라고 했을 경우에 A 클래스 절반은 ppp0, 나머지 절반은 ppp1으로 나가게 된다. 
(실제로는 더 세부적으로 하겠지만,,) 

route 를 이용한 분산은 특정 대역으로 가는 트랙픽을 보장받고 싶을 때 가능하지만, 아이피대역만을 가지고 트래픽을 분산하는 룰을 정교하게 나누가 힘들며, 비효율적이다. 

ip rule 과 MARK 를 이용한 트래픽 분산 

MARK 는 iptables의 타겟으로 프로토콜, 아이피 대역, 장치, 포트, 타입 등을 정교하게 
구상하여 트래픽을 효과적으로 분산시킬 수 있다. 
구성 순서 
ex) 
WAN1 = ppp0 , gw 111.111.111.111 
WAN2 = ppp1 , gw 222.222.222.222 

1) 각각의 WAN 구간의 table을 추가한다. 
코드:
echo "201       ppp0_Rule"        >> /etc/iproute2/rt_tables 
echo "202       ppp1_Rule"        >> /etc/iproute2/rt_tables

2) table에 MARK를 어떤것으로 할지 정한다.(경험적으로 1 ~ 9 까지 마크가 유효하다) 
코드:
ip rule add fwmark 1 table ppp0_Rule priority 98 
ip rule add fwmark 2 table ppp1_Rule priority 99

## priority 는 숫자가 낮을수록 우선순위가 높다 

마크 확인 
root# ip rule ls 
3) table에 라우팅 룰을 추가한다. 
코드:
ip route add default via 111.111.111.111 dev ppp0 table ppp0_Rule 
ip route add default via 222.222.222.222 dev ppp1 table ppp1_Rule 
ip route show table ppp0_Rule


4) iptables의 mangle 테이블에 MARK를 추가하면 완료 
--아이피 대역을 이용한 분산 
코드:
iptables -t mangle -A PREROUTING -s 192.168.0.0/24 -j MARK --set-mark 1 
iptables -t mangle -A PREROUTING -s 172.16.0.0/16 -j MARK --set-mark 2

( 출발지가 192.168.0.0/24 인것은 ppp0 으로 나가라) 
( 출발지가 172.16.0.0/16 인것은 ppp1 로 나가라) 

-- 포트를 이용한 분산 
코드:
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 1 
iptables -t mangle -A PREROUTING -p tcp --dport 20:21 -j MARK --set-mark 2

(웹서비스에 접속하는 것은 ppp0으로 나가라) 
(ftp서비스에 접속하는 것은 ppp1로 나가라) 

--아이피 대역과 포트를 동시에 분산 
코드:
iptables -t mangle -A PREROUTING -s 192.168.1.0/24 -p tcp --dport 80 -j MARK --set-mark 1 
iptables -t mangle -A PREROUTING -s 192.168.1.0/24 -p tcp --dport 20:21 -j MARK --set-mark 2

(출발지가 192.168.1.0/24 이고 웹서비스에 접속하는 것은 ppp0으로 나가라) 
(출발지가 192.168.1.0/24 이고 ftp서비스에 접속하는 것은 ppp1으로 나가라) 

-- 기타 iptables로 제어할수 있는 옵션들을 모두 활용하여 분산이 가능하다. 
### MARK를 할 경우에 알아두어야 할 점 
-route 보다 ip route 가 우선이다. (즉 MARK가 우선이다.) 
-MARK 표시가 없는 것은 route 에 의해 경로가 결정된다. 
-하나의 패킷에 MARK 가 중복되면, 맨 마지막의 MARK에 의해 경로가 결정된다. 
- MARK를 한뒤 다음 MARK에 걸리지 않게 하고 싶을 경우에는 그 패킷을 
ACCEPT 하면 된다. 
ex) 
코드:
iptables -t mangle -A PREROUTING -s 192.168.0.0/24 -p tcp 80 -j MARK --set-mark 1 
iptables -t mangle -A PREROUTING -s 192.168.0.0/24 -j MARK --set-mark 2

위에서 보면 웹서비스로 가는 패킷은 두 규칙에 모두 적용되기 때문에 결국 마지막 규칙에 의해 ppp2로 나가게 된다. 

그러나, 웹서비스를 이용할 경우 ppp0로 보내고 싶다면? 
코드:
iptables -t mangle -A PREROUTING -s 192.168.0.0/24 -p tcp 80 -j MARK --set-mark 1 
iptables -t mangle -A PREROUTING -s 192.168.0.0/24 -p tcp 80 -j ACCEPT 
iptables -t mangle -A PREROUTING -s 192.168.0.0/24 -j MARK --set-mark 2



출처 : yahon.tistory.com



Trackback 0 Comment 2
  1. 2012.10.25 16:07 address edit & del reply

    비밀댓글입니다

  2. Favicon of https://leeyj7141blog.wordpress.com 챠리 2016.06.01 01:12 address edit & del reply

    와! 잘봣습니다.
    설명도 함께 정말 잘해두셧네요 ㅎㅎ
    mark 이해가 잘 안됏는데 여기서 배우고 갑니다.

2009. 11. 19. 15:04

DNS와 GSLB(Global Server Load Balancing)

대학연합LUG (http://www.ulug.or.kr) 2008년 2학기 연합세미나 발표자료

DNS와 GSLB

경희대학교 KHLUG

7기 이준형


 네트워크상의 모든 컴퓨터들은 IP주소를 갖고 있는데 이것은 모든 컴퓨터들을 각각 고유한 식별 값으로 분리해내기 위한 것으로 주소로, 네이버는 222.122.84.200 , 구글은 209.85.171.99 등과 같이 서로가 중복되지 않게 서버 또는 컴퓨터마다 고유하게 1개 또는 다수의 IP주소를 갖고 있다.

(현재 가장 많이 활용되고 있는 IP주소는 IPv4 방식으로 32비트를 8비트 단위로 구분하여 “.” 과 함께 이루어진 주소체계이다)

 우리는 가령 네이버나 구글 같은 홈페이지에 접속하기 위하여 브라우저 창에 네이버의 도메인 주소인 www.naver.com 대신에 222.122.84.200 를 입력하거나 구글의 도메인 주소인 www.google.com 대신에 209.85.171.99 를 입력하여 접속하진 않는다. 이는 사람이 인식하고 외우기 어려운 IP주소대신에 사람이 외우고 사용하기 쉬운 도메인을 이용하여 문자(영어, 근래엔 각국의 언어도 포함)를 통하여 입력하면 특정 서버가 호스트의 IP값을 자동적으로 찾아내어 IP를 직접 알지못해도 접속이 가능하다.

 이러한 역할을 담당하는 것이 DNS(Domain Name Server)로 지금부터 DNS의 동작 원리 및 동작방법을 알아보고, BIND(Berkeley Internet Name Domain)를 통해 이를 직접구성할 것이다. 또한 최근 대두되고 있는 CDN(Content Delivery Network)의 가장 핵심이 된다고 볼수있는 GSLB(Global Server Load Balance)를 BIND의 View를 통하여 간략하게 직접 구성해 보고자 한다.

우선 도메인 주소는 어떠한 체계로 이루어 져 있을까?  

그림 1) DNS의 트리구조와 UNIX시스템의 파일 트리구조

 도메인 주소 체계는 우리가 자주 사용하는 Linux 나 Unix 의 파일 시스템의 트리구조와 비슷하다고 볼 수 있다.

 가장 최상위의 "." 인 루트도메인을 중심으로 .com .net .org .co.kr .kr 등의 1단계, .co .or .pe 등의 2단계, naver , google 같은 3단계, www , ftp 같은 4단계로 구성이 된다.

1단계는 gTLD(Greneric Top Level Domain) 또는 nTLD(National Top Level Domain) 으로 국가코드나 전세계 범용적으로 등록하는 도메인등이 해당되며, 2단계는 조직의 성격에 따라 구분짓는 도메인이며, 3단계는 사용하고자 하는 이름을 나타내며, 4단계는 서비스 성격에 따라 구분짓는 호스트명이다.

(gTLD는 위에 설명된 2단계 대신에 3단계가 바로 나온며, 4단계의 성격이 없다.) 

그림 2) 도메인 해석 과정

도메인을 읽는 과정은 위와 같이 4단계부터 1단계로 거꾸로 표기해나가며, 예를들어 한국의 대학중 경희대학교의 리눅스동아리의 도메인은 khlug.khu.ac.kr 와 같이 표기한다.

그렇다면 이제 khlug.khu.ac.kr 이라는 도메인의 IP주소를 찾기 위하여 어떠한 과정을 거치는지 알아보자.

그림 3) girigiri.gbrmpa.gov.au을 찾아가는 과정

 우선 khlug.khu.ac.kr를 찾기 위하여 “.” 도메인의 네임서버를 찾아가게 된다. “.” 네임서버는 Root Name Server 라고 불리는 서버로, 전 세계 대륙에 Mirror 서버형태로 퍼져있는 서버로 gTLD, nTLD 도메인의 값을 가지고 있다.

 이후 .kr 도메인의 네임서버, .ac 도메인의 네임서버를 거쳐 .khu.ac.kr 도메인의 네임서버를 찾아간다. 이때, .khu.ac.kr 의 네임서버는 도메인을 등록할 때 네임서버를 지정하게 되는데, 이곳의 주소로 찾아가게 되며, 이곳에서 마지막 khlug.khu.ac.kr 이라는 호스트의 IP주소를 받아오게 되어 요청 자에게 그 주소 값을 알려주게 된다. 이것이 도메인의 네임서버로의 DNS의 역할이다.

 그렇다면 흔히 우리가 PC에 DNS주소를 IP주소 형태로 입력하는데 이는 무었일까? 초기에 도메인의 값들이 많지 않았을 때에는 PC상의 “hosts” 파일을 직접 호스트주소와 IP주소를 입력하여 사용하였다. (ex. 리눅스 : /etc/hosts , 윈도우 : C:\Windows\System32\drivers\

etc\hosts ) 하지만 이러한 도메인들이 양이 점차 늘어나게 되면서 수만 개 수억 개의 도메인의 값을 매번 일일이 변경, 추가, 삭제 할수없게 되어 이를 도메인 네임서버에게 질의를 하고 그 값을 받아오는 서버를 두게 되었는데 이것이 DNS 캐싱서버이다.

 캐싱서버는 클라이언트가 도메인의 값을 질의를 하면 이를 자신의 캐시에서 먼저 찾아보고 없으면 그림3 의 방법으로 각 도메인의 네임서버로 찾아가 그 값을 자신의 캐시에 저장 및 클라이언트에게 그 값을 전달해 주는 역할을 한다. 이러한 DNS 캐시서버는 보통 자신이 사용하는 ISP(Internet Service Provider)의 캐싱서버를 주로 사용하는데 이는 각 PC가 직접 도메인의 네임서버에 질의를 한다면, 수많은 컴퓨터들이 도메인의 값을 찾기 위해 도메인의 네임서버에 질의를 한다면 각 도메인의 네임서버에는 엄청한 부하가 걸려 하루에도 몇 차례나 계속해서 다운이 될 것이다. 따라서 이를 방지하기 위한 중간 저장 서버라 볼 수 있다. (DNS의 경우 53번 UDP 프로토컬을 사용, 질의에 대한 거부가 없기 때문에 다수의 PC가 질의를 할 경우 엄청난 DDOS(Distribute Denial of Service attack) 공격으로 변할 것이다.)

 그럼 이제 BIND를 통해 실제 서버를 구성하여 보자.

 사용할 OS는 Centos 5.2 버전으로, BIND 9.3.4-6 버전이 패키지화 되어있다. (현재 ISC에서 배포하는 BIND 최신버젼은 9.5.0 이다.) 물론 http://www.isc.org 에서 직접 소스를 다운받아 설치도 가능하다.

#yum install bind

#yum install caching-nameserver

 Centos(또는 레드햇 계열의 배포판) 에서는 이렇게 간단히 두줄이면, YUM(Yellow dog Updater, Modified)을 통하여 손쉽게 설치가 가능하다.

(*참고 : 현재 BIND는 9버젼 부터 원격 루트 익스플로잇 으로부터 초래되는 문제를 최소화하기 위하여 chroot 환경에서 운영되고 있으며, 본 문서또한 BIND 9 버전에 맞춘 세팅내용을 기술 하도록 하겠다.)

이제 각 세팅파일을 살펴 보도록 하자.

/etc/named.caching-nameserver.conf


/etc/named.rfc1912.zones


 named.caching-nameserver.conf 에는 BIND 에 관한 전반적인 설정을 담고 있으며, named.rfc1912.zones 에는 각 도메인들의 대한 ZONE 파일등을 설정을 할 수 있는 내용을 담고 있음을 알 수 있다.

named.caching-nameserver.conf
#####################################################################
//
// named.caching-nameserver.conf
//
// Provided by Red Hat caching-nameserver package to configure the
// ISC BIND named(8) DNS server as a caching only nameserver
// (as a localhost DNS resolver only).
//
// See /usr/share/doc/bind*/sample/ for example named configuration files.
//
// DO NOT EDIT THIS FILE - use system-config-bind or an editor
// to create named.conf - edits to this file will be lost on
// caching-nameserver package upgrade.
//
acl "autharea" {
        163.180.0.0/16;
        163.180.114.72/32;
};
options {
        directory       "/var/named";
        dump-file       "/var/named/data/cache_dump.db";
        statistics-file "/var/named/data/named_stats.txt";
        allow-transfer { autharea; };
        allow-recursion { autharea; };
        version "KHLUG Name Server";
};
view localhost_resolver {
        include "/etc/named.rfc1912.zones";
};
#####################################################################

 위 설정은 가장 중요한 부분만 설정을 한 것으로 autharea 를 지정하여, 지정한 Network 대역 에서만 zone 파일과 recursive 응답이 가능하도록 한 것이며, BIND Version 정보를 숨기기 위하여 텍스트를 입력해 둔 것이다.

named.rfc1912.zones 
#####################################################################
//
// named.rfc1912.zones:
//
// Provided by Red Hat caching-nameserver package
//
// ISC BIND named zone configuration for zones recommended by
// RFC 1912 section 4.1 : localhost TLDs and address zones
//
// See /usr/share/doc/bind*/sample/ for example named configuration files.
//
zone "." IN {
        type hint;
        file "named.ca";
};

zone "localdomain" IN {
        type master;
        file "localdomain.zone";
        allow-update { none; };
};

************중간 생략************

zone "0.in-addr.arpa" IN {
        type master;
        file "named.zero";
        allow-update { none; };
};

zone "khlug.org" IN {
        type master;
        file "khlug.org-zone";
        allow-update { 163.180.114.72; };
};
#####################################################################

 위 설정은 khlug.org 를 master 1차 네임서버로 각종 레코드 값들을 khlug.org-zone 파일에 저장하여 2차 네임서버 163.180.114.72 로 zone 설정들을 전송이 가능하도록 세팅을 한 것이다. 추가적으로 3차, 4차 다수의 네임서버를 구성시에 allow-update 에 계속해서 써주면 된다. 또한 추가적인 부분은 1차 외에 모든 네임서버에서는 type 을 master 가 아닌 slave 로 지정하고 allow-update 대신에 masters { 163.180.114.71; }; 이렇게 지정하여 사용하면 된다.

 이렇게 간단하게 네임서버를 구성함으로 모든 준비는 끝났고, 이제 zone 파일을 작성하면 된다. 폴더는 /var/named/chroot/var/named 폴더에서 작성하면 된다.

khlug.org-zone
#####################################################################
$TTL 86400
@       IN      SOA     ns1.khlug.org. webmaster.khlug.org. (
                        2008101101
                        10800
                        900
                        604800
                        86400 )
;
        IN      NS      ns1.khlug.org.
        IN      NS      ns2.khlug.org.
        IN      MX      10      mail.khlug.org.
khlug.org.      IN      TXT     "v=spf1 ip4:163.180.114.71 -all"
ns1     IN      A       163.180.114.71
ns2     IN      A       163.180.114.72
mail    IN      A       163.180.114.71
www     IN      A       163.180.114.71
ftp     IN      A       163.180.114.71
#####################################################################

맨 위부터 설정을 간략하게 살펴보도록 하자.

$TTL 86400 ☞ 캐싱 서버가 도메인의 값을 갖고 있을 동안의 시간
@       IN      SOA     ns1.khlug.org. webmaster.khlug.org. ( ☞ 네임서버명, 관리자 메일주소
                        2008101101        ☞ Serial
                        10800             ☞ refresh
                        900               ☞ retry
                        604800            ☞ expire
                        86400 )            ☞ minimum
        IN      NS      ns1.khlug.org.      ☞ 네임서버 정보
khlug.org.      IN      TXT     "v=spf1 ip4:1.1.1.1 -all" ☞ SPF레코드 (http://www.kisarbl.or.kr참고)
www     IN      A       163.180.114.71    ☞ www 에대한 IP주소

 DNS의 레코드 유형에는 위에 간략하게 나온 설정과 그 외에 SOA, NS, A, PTR, CNAME, MX, TXT, RP등의 있다.

 SOA(Start of Authority) 는 위에 나온 네임서버명(FQDN), 관리자 메일 주소 와 시리얼 등이 적혀있다. Serial 은 도메인의 정보가 갱신되었을 때 마지막 값에 +1을 하여 변경된 내용이 다른 네임서버에 전송이 되도록 고유한 값을 저장하는 것이며, 보통 YYYYMMDDxx 같은 날짜형식으로 작성하여, 하루에 많게 99번까지(?) 변경하여도 그 내용이 저장되게 만드는 것이 좋다. 또한 refresh 는 2차 네임서버가 1차 네임서버에게 레코드의 변경여부를 얼마나 자주 확인할 지에 대한 내용을 저장하는 것이며, retry 는 2차 네임서버가 변경 여부를 검사하기 위하여 1차 네임서버에게 접속할 때에 연결 장애 발생 시에 일정 시간만큼 이후 다시 시도할 시간을 작성하는 것이다. expire 는 2차 네임서버에서 가용하는데, 1차 네임서버와 연결을 할 수 없을 때 일정 시간만큼 지난이후 캐싱 데이터의 파기 시간을 지정한다. 또한 마지막 minimum은 1차 네임서버와 연결이 불가능할 때 얼마 이후 데이터를 파기할 지에 대하여 작성한다. 이 정보는 각 도메인 운영 정책에 맞게 작성하면 될 것이다.

 NS(Name Server)는 어떤 네임서버들이 이 도메인에 대하여 관리하고 있는지를 지정하는 것이다.

 A(Address Record)는 호스트의 이름을 IP주소로 대응시키기 위하여 사용한다.

 PTR(Pointer Record)는 역방향 풀이를 위한 것으로, IP주소를 호스트에 매핑하기 위한 것인데 본 문서에서는 Resolve 도메인에 관하여서는 생략한다.

 MX(Mail Exchanger)는 본 도메인에 대한 메일서버를 지정하는데, 메일서버에대하여 가중치로 숫자를 지정하는데, 예를 들어 khlug.org. IN MX 10 163.180.114.71 이렇게 지정을 한다. 이는 메일서버가 장애 시에 가중치가 가장 작은 메일서버부터 하나씩 가중치가 높은 서버로 변경해 가면서 전송을 하기 위한 것으로, 이 부분은 또다시 메일서버에서 가중치 별로 전송처리 방식을 세팅을 해주어야 한다.

 TXT는 관련된 정보나 SPF레코드 등을 작성하기 위한 것이다.

 이제 모든 작성이 끝났으면, BIND 서버를 시작해 보도록 하자

#service named start (또는 /etc/rc.d/init.d/named start)

 도메인의 세팅이 잘 되었는지 알아보기 위해서 dig 나 nslookup 등으로 설정을 확인해 보면 된다. (이때 주의할 점은 named.caching-nameserver.conf 에서 지정한 allow-recursion 에 지정한 Network 대역에서만 정상적으로 설정된 데이터를 체크할 수 있다는 점을 꼭 기억하여 체크하는 것이 좋다.)

DNS에 관련된 기초적인 내용은 마무리 되었고 이제는 GSLB 에 대하여 알아보자. 

그림 4 GSLB 구성도

 위 그림은 GSLB 솔루션으로 구성된 환경에서 Client가 Europe에서 www.work.com 이라는 홈페이지에 접속하는 과정을 나타는 그림이다. Client 는 Local DNS 캐싱 서버에 DNS를 질의하면 도메인의 네임서버는 그 사용자의 Client 위치를 체크하여 United States 에 있는 www.work.com 이 아닌, Client로부터 가장 가까운 Europe 의 www.work.com 에 접속을 유도하게 된다. 이렇게 GSLB는 대륙이나 ISP에 따라 가장 빠른 방법으로 최소한의 라우터만을 거쳐 원하는 정보에 접속이 가능하도록 하는 방법이다.

 일반적으로 GSLB 는 L4 같은 고가의 장비로 구성하여 사용하는데 Cisco의 4492R 나 F5의 3DNS 장비 등이 있다. 하지만 상상이상의 엄청난 고가의 장비이고 실제로도 몇 안 되는 포털 사이트에서 사용할 정도의 장비이기 때문에 본 문서에서 저런 장비를 직접 구성하여 GSLB를 구연하는것은 다소 무리가 있다. 따라서 본 문서에서는 서두에서 밝혔듯 BIND의 View를 이용하여 GSLB를 구성할 것이다.

실제로 지금부터 구성해볼 GSLB는 MaxMind의 GeoIP Country Database 를 이용하여 C Api를 이용하여 BIND를 패치하고 각 나라별 BIND View를 만들어 접속하게 하는 방법이다.

우선 ISC 홈페이지에서 BIND 소스코드를 다운받은 후 http://www.maxmind.com/app/c 에 공개되어있는 C Api를 다운 및 컴파일 이후 BIND 소스에 아래 패치를 적용시킨다.

patch.diff
#####################################################################
diff -ruN bind-9.4.1-P1.orig/lib/dns/acl.c bind-9.4.1-P1/lib/dns/acl.c
--- bind-9.4.1-P1.orig/lib/dns/acl.c      Thu Mar  2 01:37:21 2006
+++ bind-9.4.1-P1/lib/dns/acl.c Tue Aug 14 16:56:34 2007
@@ -21,12 +21,15 @@
 #include <config.h>
+#include <GeoIP.h>
 #include <isc/mem.h>
 #include <isc/string.h>
 #include <isc/util.h>
 #include <dns/acl.h>
+static GeoIP *geoip = NULL;
+
 isc_result_t
 dns_acl_create(isc_mem_t *mctx, int n, dns_acl_t **target) {
        isc_result_t result;
@@ -207,6 +210,27 @@
                                         &e->u.ip_prefix.address,
                                         e->u.ip_prefix.prefixlen))
                        goto matched;
+              break;
+
+      case dns_aclelementtype_ipcountry:
+              /* We only match V4 addresses */
+              if (reqaddr->family == AF_INET) {
+                      /* Country match */
+                      
+                      if (NULL == geoip) {
+                              geoip = GeoIP_new(GEOIP_MEMORY_CACHE);
+                      }
+                      if (NULL != geoip) {
+                              const char *value;
+
+                              value = GeoIP_country_code_by_addr(geoip,inet_ntoa(reqaddr->type.in));
+                              if ((NULL != value) && (2 == strlen(value))) {
+                                      if ((e->u.country[0] == value[0]) && (e->u.country[1] == value[1])) {
+                                              goto matched;
+                                      }
+                              }
+                      }
+              }
                break;
                
        case dns_aclelementtype_keyname:
diff -ruN bind-9.4.1-P1.orig/lib/dns/include/dns/acl.h bind-9.4.1-P1/lib/dns/include/dns/acl.h
--- bind-9.4.1-P1.orig/lib/dns/include/dns/acl.h     Thu Mar  2 01:37:21 2006
+++ bind-9.4.1-P1/lib/dns/include/dns/acl.h       Tue Aug 14 16:58:28 2007
@@ -47,6 +47,7 @@
 typedef enum {
        dns_aclelementtype_ipprefix,
+      dns_aclelementtype_ipcountry,
        dns_aclelementtype_keyname,
        dns_aclelementtype_nestedacl,
        dns_aclelementtype_localhost,
@@ -55,6 +56,7 @@
 } dns_aclelemettype_t;
 typedef struct dns_aclipprefix dns_aclipprefix_t;
+typedef char dns_aclipcountry[3];
 struct dns_aclipprefix {
        isc_netaddr_t address; /* IP4/IP6 */
@@ -66,6 +68,7 @@
        isc_boolean_t negative;
        union {
                dns_aclipprefix_t ip_prefix;
+              dns_aclipcountry   country;
                dns_name_t         keyname;
                dns_acl_t    *nestedacl;
        } u;
diff -ruN bind-9.4.1-P1.orig/lib/isccfg/aclconf.c bind-9.4.1-P1/lib/isccfg/aclconf.c
--- bind-9.4.1-P1.orig/lib/isccfg/aclconf.c  Thu Mar  2 01:37:22 2006
+++ bind-9.4.1-P1/lib/isccfg/aclconf.c    Tue Aug 14 16:51:48 2007
@@ -228,6 +228,12 @@
                        }  else if (strcasecmp(name, "none") == 0) {
                                de->type = dns_aclelementtype_any;
                                de->negative = ISC_TF(! de->negative);
+                      } else if ((0 == (strncmp("country_", name, 8))) && (10 == strlen(name))) {
+                              /* It is a country code */
+                              de->type = dns_aclelementtype_ipcountry;
+                              de->u.country[0] = name[8];
+                              de->u.country[1] = name[9];
+                              de->u.country[2] = '\0';
                        } else {
                                de->type = dns_aclelementtype_nestedacl;
                                result = convert_named_acl(ce, cctx, lctx,
#####################################################################

#patch -p0 < bind-9.*.*-geodns-patch/patch.diff
#cd bind-9.*.*
#CFLAGS="-I/usr/local/geoip/include" LDFLAGS="-L/usr/local/geoip/lib -lGeoIP" ./configure --prefix=/usr/local/bind
#make
#make install

이제 /etc/named.rfc1912.zones 에 각 국가코드별로 Zone 파일을 지정한다.

#####################################################################
view "Korea" {
      match-clients { country_KR; };
      recursion no;
      zone "khlug.org" {
            type master;
            file "khlug.org-korea-zone";
      };
};
view "USA" {
      match-clients { country_US; country_CA; };
      recursion no;
      zone "khlug.org" {
            type master;
            file "khlug.org-usa-zone";
      };
};
view "other" {
      match-clients { any; };
      recursion no;
      zone "khlug.org" {
            type master;
            file "khlug.org-other-zone";
      };
};
#####################################################################

 이후 각 zone 파일을 각 대륙에 있는 서버의 IP로 지정을 하면 한국에서는 한국 쪽 서버로의 접근을 할 것이고, 미국과 캐나다에서는 미국 쪽에 있는 서버로 접근을 하여 불필요 하게 패킷이 태평양 바다를 건너는 일은 없을 것이다.

 만약 국내 ISP 별로 BIND View 를 만들고자 한다면 http://ipstat.nida.or.kr 에서 제공하는 데이터를 기반으로 일일이 BIND View 를 만들면 될 것이다. 하지만 엄청난 양의 IP주소를 입력한다는 건 쉽지 않은 일이 될 듯하다. :)

*참고자료

Cricket Liu & Paul Albitz, ≪DNS and BIND≫, O'reilly, 1998, p.84~106.
ISC, ≪BIND 9 Administrator Reference Manual≫, ISC, 2008, p.35
롭 프리켄저, ≪리눅스 서버관리 Hacks 100≫, O'reilly 한빛미디어, 2005, p.303~316.
Steven Graham & Steve Shah, ≪LINUX 관리자 가이드≫, Mc Graw-Hill 사이텍미디어, 2003, p.230~235.
이소문, ≪이소문의 엔터프라이즈 리눅스≫, 대림, 2007, p.782~787.
Nico, 〈GeoDNS BIND patch〉, http://www.caraytech.com/geodns, 2008년 11월 3일
Cisco,〈Configuring the CSS as a Domain Name System Server〉,
http://www.cisco.com/en/US/docs/app_ntwk_services/data_center_app_services/css11500series/v7.30/configuration/gslb/guide/DNS.html, 2008년 11월 3일

출처 : http://blog.naver.com/kubby72


Trackback 1 Comment 1
  1. Favicon of https://blog.pages.kr 날으는물고기 2009.11.19 15:27 신고 address edit & del reply

    GeoDNS BIND patch : http://www.caraytech.com/geodns/