NAT 를 linux 에서

from My Life/한 일 2007. 2. 25. 23:14

커 널 2.4에서 IP 공유(ip masquerade), 서버 부하분산(port forwarding), 투명 프락시(redirection)를 사용하려면 iptables 프로그램을 사용해야 한다. 물론 커널 쪽 세팅도 필요하다. 2.2에서는 ipchains와 ipmasqadm으로 분리되어 있었는데 이를 하나로 통합했을 뿐 아니라 사용법도 훨씬 쉬워졌다. 또한 확장성을 고려해서 설계되었다는 장점이 있다.

iptables는 NAT 기능뿐 아니라 filtering 기능도 들어 있다. filtering은 패킷을 걸러 내는 즉 없애는(거부하는) 기능을 담당하므로 주로 방화벽을 구축하는데 사용한다. NAT는 패킷의 내용 즉 주소, 포트번호 등을 변경한다. 한 개의 IP 주소를 여러 대의 피시에서 공유하여 인터넷을 사용하는 데는 NAT 기능을 사용해야 한다.(2.2에서의 ip masquerade) 한 개의 도메인 네임에 대해 여러 대의 서버가 서비스를 제공하는 서버 부하분산에도 역시 NAT가 사용된다.(2.2에서의 port forwarding)

이 글에서는 커널 2.4에서 IP 공유와 서버 부하분산을 구현하는 방법을 설명한다.


I. 참고자료


II. 준비작업

    커널 2.4에서 NAT를 구현하려면 커널에 해당 코드를 올리고(모듈로도 가능) 사용자 프로그램 (iptables)을 설치해야 한다. 아래의 모든 작업은 데비안 2.2(potato)에서 테스트하였다. 커널은 2.4.2를 사용했다.

    1. iptables 프로그램 설치

      1) 파일 다운로드

      iptables의 최신버전은 1.2이다. Netfilter Project 사이트(http://netfilter.kernelnotes.org/ )에서 다운받아 설치한다. 위 사이트에서 아래 파일을 다운 받는다.

      -rwxr--r--    1 bae      root       151774 Feb 24 18:00 iptables-1.2.tar.bz2

      2) 압축 해제

      bunzip2 iptables-1.2.tar.bz2
      tar xvf iptables-1.2.tar

      iptables-1.2 디렉토리가 만들어지고 그 안에 소스가 위치한다.

      3) cd iptables-1.2

      4) 2.4 커널 소스를 /usr/src/linux에 설치한다.

      5) make

      ·2.4 커널 소스가 다른 디렉토리에 있으면 아래 명령이 필요하다.
        make KERNEL_DIR=<<커널 디렉토리명>>

      6) make install

      실행파일은 /usr/local/sbin/iptables 이다. 라이브러리도 동시에 설치된다. 다른 곳에서 iptables 파일만 복사해서는 NAT를 사용할 수 없다. 라이브러리도 같이 설치해야 하므로 컴파일하거나 rpm으로 설치해야 한다.

    2. 커널 코드 올리기

    filtering이나 NAT를 사용하려면 필히 커널에 해당 코드가 올라가야 한다. 모듈로 올리는 방법과 컴파일해서 코드에 포함시키는 방법이 있다.

    여기서는 커널을 컴파일해서 코드를 설치하는 경우의 make menuconfig(make config, make xconfig) 에서  필요한 선택사항을 설명한다.(커널 2.4.2) NAT와 직접 관련된 선택사항만 설명했다. 네트워크나 랜카드에 관련된 부분은 자신의 시스템에 맞게 선택해야 한다.

      1) 메인 메뉴의 “Networking options  “ 에서 아래 부분을 선택한다.

      [*]Network packet filtering
      [*]Socket Filtering
      [*]Unix domain sockets
      [*]Unix domain sockets
      [*]TCP/IP networking

      IP: Netfilter Configuration  --->

      <*> Connection tracking (required for masq/NAT)
      <*> FTP protocol support
      <*> IP tables support (required for filtering/masq/NAT)

      아래 항목 중에서 일반적인 IP 공유나 서버부하분산을 구현하려면 <*> 표시가 있는 항목을 선택한다. 나머지는 패킷 필터링을 사용하거나 특수한 NAT 기능 구현시만 필요하다.

            < >   limit match support
      < >   MAC address match support
      < >   netfilter MARK match support
      < >   Multiple port match support
      < >   TOS match support
      < >   Connection state match support
      < >   Unclean match support (EXPERIMENTAL)
      < >   Owner match support (EXPERIMENTAL)
      < >   Packet filtering
      <*>   Full NAT
      <*>   MASQUERADE target support : 유동 IP 사용시 필요하다.
      < >   REDIRECT target support     : 투명프락시 사용시 필요하다.
      < >   Packet mangling
      < >   LOG target support

      2) 아래 메뉴를 선택하면 NAT 기능을 사용할 수 없다.

      "Networking options"에서 "Fast switching (read help!)"


III. NAT에 대한 이해

    iptables를 정확히 사용하려면 iptables에서 정의하는 NAT의 개념을 알아야 한다.

    1. NAT 사용 예

    아래 그림을 기준으로 설명한다. 아래 그림에서 리눅스C에는 두 개의 랜카드가 설치되어 있고 인터넷 쪽의 랜카드(eth0) 에는 공인 IP(고정) 가 부여되어 있다.(211.217.xxx.yyy) 두번째 랜카드에는 내부어드레스(192.168.1.1)가 부여되어 있고 내부 랜(192.168.1.0/24)에 연결되어 있다.

         <그림 1>

      1) 여러 대의 피시에서 한 개의 IP를 공유하여 인터넷을 사용

      adsl 이나 케이블모뎀으로 인터넷을 연결하는 경우 보통은 1개의 IP 주소를 받는다. (여러 개를 받을 수 있는 서비스가 있으나 비용이 많이 든다.) 이때 한 개의 IP주소를 여러 대의 피시에서 공유하여 인터넷을 사용하려 할 경우 NAT가 사용된다.  우리가 IP Masquerade라 불러왔다. 그림 1] 에서 윈도우A, 윈도우B 두 대의 피시에서 리눅스C의 공인 IP(211.217.xxx.yyy)를 공유해서 인터넷을 사용하게 설정하는 경우이다.

      2) 한 개의 IP 주소(도메인네임)에 여러 대의 서버를 연결하는 경우

      부하분산을 위해 한 개의 도메인네임(FQDN)에 대해 여러 대의 서버를 운영하는 경우도 NAT를 사용한다.  즉 www.linuxlab.co.kr 도메인 한 개에 웹서버, 메일서버, FTP 서버를 따로 운영하는 경우이다. 부하평준화(load balance) 기능도 구현이 가능하다. 즉 www.linuxlab.co.kr 도메인에 대한 웹서비스를 여러 대의 서버가 담당하게 하는 경우이다. 2.2에서는 port forwarding이라 불리웠다.

      (커널 2.2에서 port forwarding 사용법은 리눅스 월드 2000년 3월호에 있다.)

      그림 1] 에서 윈도우C에서 bae@www.linuxlab.co.kr로 메일을 보내면 메일은 192.168.1.10 서버로 전달되고 웹을 검색하면(http://www.linuxlab.co.kr) 192.168.1.11 서버가 응답하게 설정하는 것이다.

      3) 투명 프락시

      학원에서 인터넷 강의를 하는 경우는 동일 네트워크에 연결된 여러 대의 피시에서 동시에 같은 사이트를 연결한다. 이 경우 프락시 서버를 설치하면 모든 피시는 우선 프락시 서버에서 방문하려는 사이트의 페이지가 있는지를 확인하고 여기에 없을 경우는 프락시서버에서 해당 사이트를 연결해 페이지를 가져다 피시에게 준다.

      프락시 서버를 사용하려면 피시의 웹브라우저에 프락시서버를 지정해 주어야 한다. 그런데 투명프락시의 경우는 클라이언트 피시의 웹브라우저에 프락시서버를 지정할 필요가 없다.

      리눅스에 투명프락시를 설정하면 리눅스를 통과하는 패킷은 자동으로 리눅스에 설치된 프락시서버 프로그램(예: squid)으로 연결된다.(리눅스를 각 피시의 디폴트게이트로 지정하면 모든 패킷은 리눅스를 통과한다.) 예전에는 리다이렉션이라고 불리웠다.

      그림 1]에서 윈도우A에서 www.debian.org의 페이지를 검색하면 리눅스C에 설치된 프락시서버프로그램(squid)이 www.debian.org를 연결해 대신 데이터를 가져다 윈도우A에 넘겨주는 설정이다. 이 글에서는 투명프락시 설정은 설명하지 않는다. Transparent Proxy with Squid mini-HOWTO를 참고 하라.

    2. iptables에서 NAT 의 분류

    iptables에서는 크게 두 부류의 NAT로 분류한다. 위의 1) 의 경우를 SNAT(Source NAT) 위의 2) , 3)의 경우는 DNAT(Destination NAT) 라 분류한다.

    SNAT는 패킷의 소스 어드레스를 변경한다는 의미이다. 즉 내부 어드레스인 192.168.1.100 윈도우A 에서 www.debian.org 리눅스서버를 연결하면 debian 서버에서 볼 때 패킷의 소스가 192.168.1.100이 아닌 211.217.xxx.yyy로 나타나기 때문이다.

    SNAT는 라우팅(경로) 결정 이후에 이루어진다.(post-routing) 패킷의 목적지 주소는 이미 정해져 있으므로(www.debian.org) 라우팅 경로는 결정되어 있고 패킷의 소스 주소가 리눅스를 떠나기 직전에 변경된다.(192.168.1.100 -> 211.217.xxx.yyy)

    DNAT는 이와는 반대다. 리눅스C에서 패킷의 목적지 주소를 변경한다. 윈도우C에서 bae@www.linuxlab.co.kr 주소로 메일을 보내면 리눅스C에 도착한 패킷의 목적지가 리눅스 B의 주소로 변경된다. 즉 패킷의 목적지 주소가 먼저 변경되고(211.217.xxx.yyy -> 192.168.1.10) 그 변경된 주소에 의거하여 새로운 라우팅 경로가 찾아진다. 즉 DNAT는 라우팅 이전 단계에서 작용한다.(pre-routing)

    post-routing와 pre-routing 은 무척 혼동된다. 즉 내가 왼쪽이라 하면 상대에서 나를 볼 때는 오른쪽이다. 결국 NAT 가 routing 보다 전에 작용하느냐 후냐의 구분으로 보면 된다. (iptables 파라메터 지정에서 이 둘을 혼동하면 에러가 난다.)


IV. IPTABLES 설정

    1. Source NAT 는 아래와 같이 지정한다.(기존의 IP Masquerade를 말함.)

    iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4

    iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4-1.2.3.6
    iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to 1.2.3.4:1-1023

    -t -A 는 위의 글(2)을 읽으면 이해가 되리라고 본다. -o 는 패킷을 보내는 인터페이스 장치이다. SNAT 에서는 패킷을 내 보내는 장치(랜카드)를 지정할 수 있다.  --to 는 나가는 패킷에 부여할  소스 주소이다. IP 공유라면 --to 는 인터넷 쪽의 공인 IP 를 지정하면 된다.(지정 않아도 상관없다.)
     

    주의]

    리눅스에 NAT를 설치하는 경우 리눅스는  게이트웨이로 작용하므로 IP Forwarding이
    필요하다.
    아래 명령을 포함하는 스크립트를 /etc/rc.boot/ 디렉토리에 넣는다.(데비안)

    #!/bin/bash
    echo “IP forwarding setting..”
    echo “1” > /proc/sys/net/ipv4/ip_forward

    IP forwarding 이 활성화되었는지를 확인하려면 아래 명령을 준다.

    churlsu:/etc/rc.boot# cat /proc/sys/net/ipv4/ip_forward
    1

    값이 1이면 활성화(enable) 되어 있다.


    1.1 실제 사용 예

      1) 한국통신 ADSL을 리눅스에 연결해 인터넷을 공유(IP MASQUERADING)하는
          경우의 설정은 아래와 같다.(라이트나 프리미엄처럼 유동 IP를 받는 서비스의
          경우에만 해당한다.)

          iptables  -t  nat  -A  POSTROUTING  -o  ppp0  -j  MASQUERADE

      2) 그림1] 에서 리눅스C의 eth0에 부여된 IP(고정)를 윈도우 A,B에서 공유하여
          인터넷을 사용하게 설정하려면 아래와 같다. 전용선 또는 ADSL My IP, Multi IP
          사용시에 해당한다.

          iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to
          211.217.xxx.yyy

          * -s 192.168.1.0/24는 지정 않아도 된다.

      3) 그림 1] 에서 리눅스 C의 eth0가 케이블모뎀에 연결되어 있다면 아래처럼
          지정한다.(유동 IP)

          iptables  -t  nat  -A  POSTROUTING  -o  eth0  -j  MASQUERADE

    1.2 확인

      - iptables 설정 내용을 확인하려면 아래 명령을 준다.

         iptables -t nat -L

      - 192.168.1.0 네트워크에서 211.217.xxx.yyy 공인 IP를 공유하도록 설정한 경우
         (위의 1.1의 2) 의 출력
       

      Chain PREROUTING (policy ACCEPT)
      target     prot opt source               destination

      Chain POSTROUTING (policy ACCEPT)
      target     prot opt source             destination
      SNAT       all  --  192.168.1.0/24  anywhere       to:211.217.xxx.yyy

      Chain OUTPUT (policy ACCEPT)
      target     prot opt source            destination


    2. DNAT

    DNAT 는 부하분산이나 평준화에만 사용하는게 아니다. 간단한 방화벽으로도 꽤 유용하다. 즉 위의 리눅스C에 DNAT를 설정하여 웹서버와 메일서버를 내부 주소인 리눅스 A와 B에서 서비스 하도록 지정하고 인터넷에서 다른 연결은 리눅스C로 지정하면 리눅스 C가 간단한 방화벽 구실을 담당한다.

    2.1 사용 예

    -  그림1]에서 처럼 윈도우C에서 www.linuxlab.co.kr 의 홈페이지를 검색하려 할 때 이를
        리눅스A에서 담당하게 하려면 아래처럼 설정한다.

        iptables -A PREROUTING -t nat -p tcp  -d 211.217.xxx.yyy  --dport 80 \
        -j DNAT --to  192.168.1.11:80

      1)  -A PREROUTING  : DNAT 는 먼저 목적지 주소를 변경하고(211.217.xxx.yyy를
           192.168.1.11로) 다음에 라우팅이 이루어진다.

      2)  -t nat  : 부하분산도 nat 기능이다.

      3)  -p tcp  : 웹(www)은 tcp 를 사용한다.

      4)  -d 211.217.xxx.yyy  --dport 80 : 들어오는 패킷의 목적지 주소가
           211.217.xxx.yyy 이고 포트번호가 www(80번) 인 경우만 이 규칙을 적용한다.

      5)  -j DNAT : destination Nat

      6)  --to  192.168.1.11:80 : 패킷의 목적지 주소를 192.168.1.11 포트번호를 80번으로
          설정하라는 뜻. 따라서 192.168.1.11 서버에는 80번 포트에서 웹서버 프로그램이
          가동 되야 한다.

    - 메일서버를 리눅스B (192.168.1.10)로 설정하려면 아래처럼 지정한다.

    iptables -A PREROUTING -t nat -p tcp  -d 211.217.xxx.yyy  --dport 25 \
    -j DNAT --to  192.168.1.10:25

    - DNS 서버를 192.168.1.10으로 변경하려면 아래처럼 지정한다.

    iptables -A PREROUTING -t nat -p udp  -d 211.217.xxx.yyy  --dport 53 \
    -j DNAT --to  192.168.1.10:53

    주의]  DNS 는 udp 를 사용한다.

    2.2 DNAT 설정 확인

    웹을 192.168.1.11 로 DNAT 설정을 하면 아래처럼 나온다.(리눅스C에서 아래 명령을 준다.)

    churlsu:~# iptables -t nat -L
    Chain PREROUTING (policy ACCEPT)
    target     prot opt  source      destination
    DNAT     tcp  --  anywhere   churlsu.linuxlab.co.krtcp dpt:www to:192.168.1.11:80

    3. iptables 설정 해제

    - 기존에 설정돼 있는 모든 nat 설정을 지우려면 아래 명령을 준다.

      iptables -t nat -F

    - iptables 의 모든 설정이 해제된 경우는 아래와 같다.

    churlsu:~# iptables -t nat -L
    Chain PREROUTING (policy ACCEPT)
    target     prot opt source               destination

    Chain POSTROUTING (policy ACCEPT)
    target     prot opt source               destination

    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination


V.  iptables  옵션

    아래는 nat 에서 사용하는 중요한 옵션만 설명했다. 나머지는 man 페이지를 참고 하라.

    1) -t  : --table

    table 을 선택한다. filter, nat, mangle 세가지 선택이 있다. 커널에 해당 테이블을 지원하는 코드가 들어 있어야 한다. 모듈 자동적재를 사용한다면 해당 테이블을 선택하면 그와 관련된 커널 모듈이 적재된다.  디폴트는 filter 이므로 nat를 사용하려면 필히 nat 를 지정해야 한다.

    2) -A  : --append

    규칙을 추가한다.

    INPUT, FORWARD :  -t가 filter인 경우 사용 가능
    POSTROUTING, PREROUTING: -t가 nat인 경우 사용 가능
    OUTPUT: 양쪽 다 사용

    3) -i :   --in-interface

    패킷이 들어오는(incoming) 인터페이스(장치)를 지정한다. (-t 가 nat 이면 PREROUTING에서만 지정 가능하다.) 인터페이스명 앞에 “!” 을 추가하면 그 장치는 제외한다는 의미가 된다. 뒤에 “+”를 추가하면 그 이름으로 시작하는 모든 장치를 의미한다. 디폴트는 +이다.

    4) -o :  --out-interface

    outgoing 인터페이스 즉 패킷이 나가는 네트워크 장치를 지정한다. (-t가 nat이면 POSTROUTING 에서만 지정 가능하다) “!” 과 “+” 은 -i 와 동일한다.

    5) -s  :  --source

    소스 어드레스/netmask 를 지정한다. SNAT에서 밖으로 나가는 패킷의 소스어드레스에 따라 규칙을 적용하려 할 때 지정한다.  주소는 호스트네임, 네트워크네임, IP 주소 등을 사용할 수 있다. 아래 형식이 가능하다. 앞에 “!”을 넣으면 반대의 개념이 된다.

            - 192.168.1.100
            - 192.168.1.0/24
            - 192.168.1.0/255.255.255.0

    6) -d :  --destination

    목적지 주소/netmask 를 지정한다. DNAT 에서 들어오는 패킷의 목적지 주소에 따라 규칙을 적용하려 할 때 지정한다. 위의 -s 와 사용법이 같다.

    7) -p :  --protocol

    tcp 나 udp 를 지정한다.

    8) --to :  --to-source,  --to-destination,  

    --to 는 SNAT  에서는 --to-source의 의미이다. 즉 내보내는 패킷에 새로 부여할 소스 IP 주소를 지정한다.  보통은 인터넷 쪽에 연결된 랜카드의 주소이다.

    DNAT 에서는 --to-destination 의 의미이다. 즉 패킷의 새로운 목적지 주소이다. Port forwarding 에서 는 내부 랜에 설치된 서버의 주소이다.

    9) --dport :

    -p 와 같이 사용된다. DNAT에서 들어오는 패킷의 목적지 포트에 따라 규칙을 적용하려 할 때 지정한다.


    출처 : http://www.schkorea.zc.bz/bbs/view.php?id=programming_unix&no=42

,