본문 바로가기

지식/Network

iptables 사용하기

1. iptables의 개요
리눅스커널 2.4버전에서 사용하는 방화벽이다. 리눅스커널 2.2버전에서는 ipchains를 사용하였는데
원리와 구조 등 전반적으로 비슷하다.


2. iptables 사용하기
(1) 개요: iptables는 구버전의 ipchains와 같이 사용할 수 없으므로 확인하여 ipchains가 모듈로
          올라와 있으면 모듈을 제거해야 한다.
(2) 모듈의 확인
   [root@mybestone /root]# lsmod
   Module                  Size  Used by
   autofs                 11296   1  (autoclean)
   8139too                16512   2  (autoclean)
   ipchains               39360   0  (unused)
   usb-uhci               20752   0  (unused)
   usbcore                49728   1  [usb-uhci]
     => 현재 ipchains의 모듈이 올라와 있다. 이 경우에는 iptables를 사용할 수 없다.
(3) 모듈의 제거 및 iptables의 실행
   [root@mybestone /root]# rmmod ipchains
     => 모듈을 제거한다.
   [root@mybestone /root]# lsmod
   Module                  Size  Used by
   autofs                 11296   1  (autoclean)
   8139too                16512   2  (autoclean)
   usb-uhci               20752   0  (unused)
   usbcore                49728   1  [usb-uhci]
    => 모듈이 제거되었음을 알 수 없다.
   [root@mybestone /root]# iptables -L
   Note: /etc/modules.conf is more recent than /lib/modules/2.4.2-3/modules.dep
   Chain INPUT (policy ACCEPT)
   target     prot opt source               destination

   Chain FORWARD (policy ACCEPT)
   target     prot opt source               destination

   Chain OUTPUT (policy ACCEPT)
   target     prot opt source               destination
    => iptables 명령이 실행된다.

3. iptables의 기본구조
(1) 개요: iptables는 크게 2개의 테이블로 나눌 수 있다. 하나는 필터링을 하는 filter라는 테이블
          이고, 또 다른 하나는 nat 라는 테이블이다. filter라는 테이블을 기본적으로 생략가능하
          고, nat는 네트워크의 주소를 변환할 때 사용하는 테이블을 -t 옵션을 이용하면 명기해야
          한다. 기본 필터링은 논리적인 3개의 사슬(chains)으로 구성되어 있고, 각각 INPUT,
          OUTPUT, FORWOARD 라는 이름을 가지고 있다. 또한 사용자가 정의하여 새로운 사슬도 생성
          할 수 있다.(기본 사슬의 이름은 대문자이다.)
(2) 구성
   1) INPUT 사슬  : 리눅스박스를 향해 들어오는 패킷들이 거치는 체인
   2) FORWARD 사슬: 리눅스박스를 거쳐 output체인을 향하는 체인
   3) OUTPUT 사슬 : 리눅스박스를 나가는 패킷들이 들어가는 체인
(3) 기본문법
   1) 기본문법
     iptables [-t table] action chain pattern [-j target]
   2) 항목설명
    ㄱ. table : 크게 nat와 filter로 나누며, 기본값일 filter이므로 filter인 경우에는 생략한다.
    ㄴ. action : 전체 사슬에 대한 정책을 지정한다. -A, -L, -D, -F 등 대문자 옵션이 이에 해당
                한다.
    ㄷ. chain: 일반적인 필터링에 속하는 INPUT, OUTPUT, FORWARD가 있으며, nat 테이블에는 POST
              ROUTING, PREROUTING, OUTPUT 이 있다.
    ㄹ. pattern: 세부규칙을 지정하는 것으로 소문자 옵션(-s, -p, -d 등)이 이에 해당한다.
    ㅁ. target: 정책을 지정하는 것으로 DROP, ACCEPT, LOG 등이 해당한다.

4. iptables의 정책
(1) 개요: iptables의 정책이라는 것은 패킷을 어떻게 처리할 것인지를 말한다. 패킷의 처리는 크게
          거부할 것이냐 허가할 것이냐 두가지이지만, 세부적으로는 ACCEPT, DENY, DROP으로 관리한
          다.
(2) 기본정책
   1) ACCEPT : 패킷을 허용하는 옵션이다.
   2) DENY   : 패킷을 허용하지 않는다는 메시지를 보내면서 거부한다. 사슬 전체정책설정(-P)에서
              는 사용할 수 없다.
   3) DROP   : 패킷을 완전히 무시한다.

5. iptables 사용하기(1) - 사슬에 대한 사용
(1) 개요: iptables는 조작하는 방법은 크게 두가지로 나눌 수 있다. 첫번째는 전체 사슬에 대한
          설정이고 두번째는 각 사슬에 대한 규칙을 조작하는 방법이다. 참고로 사슬에 대한 동작
          설정은 대문자옵션(-P, -L 등)을 사용하고 사슬에 대한 세부규칙은 소문자옵션( -s,-p 등)
          을 사용한다.
(2) 사용법
   1) 전체사슬에 대한 작동
     -N: 새로운 사슬을 만든다.
     -X: 비어있는 사슬을 제거한다. (3개의 기본 사슬은 제거할 수 없다.)
     -P: 사슬의 정책을 설정한다.
     -L: 현재 사슬의 규칙을 나열한다.
     -F: 사슬으로부터 규칙을 제거한다.
     -Z: 사슬내의 모든 규칙들의 패킷과 바이트의 카운트를 0으로 만든다.
   2) 사슬 내부의 규칙에 대한 작동
     -A: 사슬에 새로운 규칙을 추가한다.(--append) 해당 사슬에 맨 마지막 규칙으로 등록된다.
        -사슬과 규칙
         INPUT, FORWARD: -t가 filter인 경우 사용가능
         POSTROUTING, PREROUTING: -t가 nat인 경우 사용가능
         OUPTUT: 양쪽 다 사용가능
     -I: 사슬에 규칙을 맨 첫부분에 삽입한다.
     -R: 사슬의 규칙을 교환한다.
     -D: 사슬의 규칙을 제거한다.

6. iptables 사용하기(2)- 필터링지정

(1) 개요: 세부옵션을 사용하여 좀더 자세한 규칙을 정할 수 있다.
(2) 옵션과 관련된 규칙
   1) -s(발신지) -d(도착지)의 사용
    ㄱ. 개요: 발신지('-s','--source','--src')와 도착지('-d','--destination','--dst')를 지정한
             다. 보통 IP주소를 표현하는 방법은 4가지가 있다.
    ㄴ. 표현법
      a. 도메인으로 표기하기
        예) -s www.linux.ac.kr, -d localhost
      b. IP주소를 표기하기
        예) -s 192.168.0.2
      c. Netmast값을 이용한 표기(1)
        예) -s 192.168.1.0/24 : 192.168.1.0 ~ 192.168.1.255
            -s 192.168.0.0/16 : 192.168.0.0 ~ 192.168.255.255
      d. Netmast값을 이용한 표기(2)
        예) -s 192.168.1.0/255.255.255.0
            -s 192.168.0.0/255.255.0.0
    ㄷ. 사용예
       iptables -A INPUT -s 0/0 -j DROP
        => 모든 IP주소(0/0) 로부터 들어오는 패킷들을 모든 DROP한다.
   2) -j의 사용
    ㄱ. 개요: 특정한 정책(ACCEPT, DROP, DENY, REDIRECT 등)을 설정한다.
    ㄴ. 사용예
       iptables -A INPUT -s 192.168.1.20 -j DROP
        => 192.168.1.20으로 부터 들어오는 모든 패킷에 대해 거부한다.
   3) !('not'을 의미)의 사용
    ㄱ. 개요: 아닌 NOT의 의미로 사용된다.
    ㄴ. 사용예
       -s ! localhost
        => localhost로부터 오는 패킷이 아닌경우를 나타낸다.
   4) -p(프로토콜)의 사용
    ㄱ. 개요: 프로토콜을 지시할 때 사용한다. 보통 TCP, UDP, ICMP같은 이름들이 사용된다. 대소문
             자를 구별하지 않는다. '!'(not)과도 같이 사용된다.
    ㄴ. 사용예
       -p ! TCP
        => TCP 프로토콜이 아닌경우를 나타낸다.
   5) -i 사용
    ㄱ. 개요: '-i'('--in-interface')는 패킷이 들어오는 인터페이스를 지정하는데 사용된다. 즉
             -i는 INPUT과 FORWARD 사슬에 사용된다.
    ㄴ. 참고: -t가 nat이면 PREROUTING에서만 지정가능하고 인터페이스명 앞에 "!"를 추가하면 그
             장치는 제외한다는 의미가 된다. 뒤에 "+"를 추가하면 그 이름으로 시작하는 모든 장치
             를 의미한다. 디폴트가 +이다.
   6) -o의 사용
    ㄱ. 개요: '-o'('--out-interface')는 패킷이 나가는 네트워크장치를 지정한다. 보통 OUTPUT,
             FORWARD사슬에 사용된다.
    ㄴ. 참고: -t nat이면 POSTROUTING에서만 지정가능하다. "!"과 "+"은 -i와 동일하다.
   7) -t(--table)
    ㄱ. 개요: table을 선택한다. filter, nat, mangle 세가지 선택이 있다. 커널에 해당 테이블을
             지원하는 코드가 들어 있어야 한다. 모듈 자동적재를 선택하면 그와 관련된 커널 모듈
             이 적재된다. 디폴트는 filter이므로 nat를 사용하려면 필히 nat라고 지정해야 한다.
    ㄴ. 사용예
       -t nat

7. iptables의 확장
(1) 개요: ipchains에서 간단하게 적용되던 -p같은 프로토콜관련 옵션들의 기능들이 세부적인 사항
          들을 설정할 수 있도록 추가적인 옵션이 제공된다.
(2) tcp의 확장
   1) 설명: 기본 -p tcp(또는 --protocol tcp)가 지정되고 추가로 사용할 수 있는 옵션이 제공된다.
   2) 사용법
     -p tcp [옵션]
   3) 옵션
     --source-port: 발신지에서의 하나의 포트나 포트범위를 지정한다. 보통 /etc/services에 기록
                   된 것과 같은 포트 이름이 사용될 수 있고 숫자로 나타낼 수 있다. 범위를 표시
                   하기 위해 '-'를 사용할 수 있다.
     --sport: --source-port 옵션과 같다.
     --destination-port: 도착지 포트를 지정한다.
     --dport: --destination-port 옵션과 같다.
     --tcp-flags : tcp에서 발생하는 flag를 지정하는 옵션이다. 보통 두개의 단어를 사용하는
                  첫번째 것은 검사하고자 하는 지시자 리스트를 적고, 두번째 단어는 지시자에게
                  어떤 것이 설정될 것인지를 지정한다.
       예) iptables -A INPUT --protocol tcp --tcp-flag ALL SYN, ACK -j DENY
          => 모든 flag들이 검사되지만 (여기서 ALL은 SYN, ACK, FIN, RST, URG, PSH와 같다.) SYN
            과 ACK만 거부로 설정된다.
     --syn : --tcp-flags SYN, RST, ACK를 줄여서 사용하는 옵션이다. ! 가 앞에 선행될 수 있다.
     --tcp-option 숫자 : 숫자와 tcp옵션이 같은 경우의 패킷을 검사한다. tcp옵션을 검사하려 할때
                        완전한 TCP 헤더를 갖지않는 것은 자동으로 DROP된다.
   4) 참고
     TCP 프로토콜은 두 시스템간의 접속을 위해서 3-way handshaking이라는 것을 한다. 즉 A라는
    시스템이 B라는 시스템에 접속을 요청(SYN패킷)하면 B라는 시스템은 응답패킷(ACK)을 보내고
    다시 A라는 시스템이 응답패킷(ACK/SYN)을 보내면 접속을 이루어진다. 이러한 기법을 이용하면
    특정한 곳으로 부터 오는 접속 시도를 패킷만 불가능하게 만듬으로써 접속이나 요청등을 거부할
    수 있다.
      예) -p tcp -s 192.168.1.3 --syn
         => 192.168.1.3으로부터 오는 SYN패킷을 의미한다.
(3) udp의 확장: -p udp(또는 --protocol udp)로 지정하고 '--source-port','--sport','--destinati
                on-port','-dport'를 지원한다.
(4) icmp의 확장
   1) 설명: -p icmp(또는 --protocol icmp) 뒤에 --icmp-type만 추가옵션으로 지원한다.
   2) 사용법
     -p icmp --icmp-type [추가명령]
   3) 참고
     icmp-type관련 추가명령은 iptables -p icmp --help하면 볼 수 있다.
   

8. iptables 간단한 실습하기
(1) 정책세우기
   예) 127.0.0.1(loopback) 이라는 IP주소로부터 오는 ping패킷(ICMP패킷) 무시하기
     => (분석)
       프로토콜: ICMP
       발신주소: 127.0.0.1
       목표(target): DROP
(2) 현재 정책의 확인
   [root@mybestone /root]# iptables -L
   Chain INPUT (policy ACCEPT)
   target     prot opt source               destination

   Chain FORWARD (policy ACCEPT)
   target     prot opt source               destination

   Chain OUTPUT (policy ACCEPT)
   target     prot opt source               destination
    => 현재 어떠한 정책도 설정되어 있지 않다.
(3) 정책설정하기
   1) ping 테스트하기
     [root@mybestone /root]# ping localhost
     PING localhost.localdomain (127.0.0.1) from 127.0.0.1 : 56(84) bytes of data.
     Warning: time of day goes back, taking countermeasures.
     64 bytes from localhost.localdomain (127.0.0.1): icmp_seq=0 ttl=255 time=86 usec
      => 현재 ping이 된다.
   2) 정책설정하기
     [root@mybestone /root]# iptables -A INPUT -s 127.0.0.1 -p icmp -j DROP
     [root@mybestone /root]# ping -c 1 localhost
     PING localhost.localdomain (127.0.0.1) from 127.0.0.1 : 56(84) bytes of data.

     --- localhost.localdomain ping statistics ---
     1 packets transmitted, 0 packets received, 100% packet loss
      => ping이 되지 않는다.
   3) 현재 정책의 확인
     [root@mybestone /root]# iptables -L
     Chain INPUT (policy ACCEPT)
     target     prot opt source               destination
     DROP       icmp --  localhost.localdomain  anywhere

     Chain FORWARD (policy ACCEPT)
     target     prot opt source               destination

     Chain OUTPUT (policy ACCEPT)
     target     prot opt source               destination
(4) 정책지우기
   1) 번호로 지우기
    ㄱ. 개요: iptables -L 했을 때 리스트를 보면 각 정책(현재는 INPUT만 설정)의 리스트번호가
             위에서부터 차례로 1,2,3,.번호가 설정되었다고 생각하면 된다. 그러므로 현재는
             INPUT중에서 1번만 설정되었다.
    ㄴ. 사용예
       [root@mybestone /root]# iptables -D INPUT 1
         => INPUT사슬의 1번규칙을 삭제한다.
   2) 전체명령으로 지우기
    ㄱ. 개요: 원래 설정한 명령에서 -A 대신에 삭제옵션인 -D를 사용하면 된다.
    ㄴ. 사용예
       [root@mybestone /root]# iptables -D INPUT -s 127.0.0.1 -p icmp -j DROP
    ㄷ. 정책의 확인
       [root@mybestone /root]# iptables -L
       Chain INPUT (policy ACCEPT)
       target     prot opt source               destination

       Chain FORWARD (policy ACCEPT)
       target     prot opt source               destination

       Chain OUTPUT (policy ACCEPT)
       target     prot opt source               destination
   3) -F 옵션이용하기
    ㄱ. 설명: -F옵션은 전체 사슬에 대한 규칙을 제거하거나 특정사슬의 규칙을 전부 제거할 수
             있다.
    ㄴ. 사용예
      a. [root@mybestone /root]# iptables -F
           => 전체 사슬에 대한 규칙을 제거한다.
      b. [root@mybestone /root]# iptables -F INPUT
           => INPUT사슬에 부여된 규칙을 전부제거한다.

9. 응용예
(1) 들어오는 패킷 모두 거부하고 192.168.0.2로 부터 들어오는 모든 패킷들에 대해서만 허가하기
    iptables -P INPUT DROP
      => 전체 사슬중에 INPUT에 대한 전체정책(-P)를 DROP하면 된다.
    iptables -A INPUT -s 192.168.0.2 -j ACCEPT
      => 도착지에 대한 명기를 하지 않으면 현재서버를 말하며, 프로토콜을 명기하지 않으면 모든
        프로토콜이라고 여긴다.
(2) 들어오는 모든 패킷들 허가하고 192.168.1.18로 부터 들어오는 모든 패킷들에 대해서 거부하기
    iptables -P INPUT ACCEPT
    iptables -A INPUT -s 192.168.1.18 -j DROP
(3) 192.168.4.40으로 들어오는 패킷중에서 tcp프로토콜관련 패킷만 거부하기
    iptables -A INPUT -s 192.168.4.40 -p tcp -j DROP
      => tcp기반 서비스인 텔넷등을 이용할 수 없다. 그러나 ping같은 icmp프로토콜을 사용하는
        패킷은 허가된다.
(4) 포트번호 22번부터 30번까지를 목적지로 들어오는 패킷들을 막고 텔넷포트인 23번포트만 허용
    하기
     iptables -A INPUT -p tcp --dport 22:30 -j DROP
     iptables -A INPUT -p tcp --dport 23 -j ACCEPT
       => iptables에서 세부규칙은 먼저 등록된 것이 효력을 발생한다. 즉 현재의 정책설정은
         포트에 대한 거부를 먼저 설정하였기 때문에 다음행에 23번포트를 허가해도 효력이 없다.
         제대로 설정하려면 다음과 같이 순서를 바꿔야 한다.
     iptables -A INPUT -p tcp -dport 23 -j ACCEPT
     iptables -A INPUT -p tcp --dport 22:30 -j DROP

10. iptables의 규칙 저장하고 불러오기
(1) 개요: 원하는 대로 방화벽 사슬을 설정해 놓은 후, 그 설정을 저장하여 설정된 내용을 불러올
          수 있다. 이 때 저장하는 명령이 iptabless-save라는 스크립트이고, 불러오는 명령은
          iptables-restore이다.
(2) iptables-save
   1) 설명: 설정한 내용을 저장하는 스크립트이다.
   2) 사용법
     iptables-save > 파일명
   3) 사용예
    ㄱ. iptables-save >firewall.txt
       => 현재 설정을 firewall.txt라는 파일로 저장한다.
    ㄴ. iptables-save -v
       => 저장한 내용을 화면에 출력한다.
(3) iptables-restore
   1) 설명: iptables-save로 저장한 사슬을 복구하는 스크립트이다.
   2) 사용법
     iptables-restore < 파일명


11. iptables와 ipchains의 차이점
(1) 미리 생성되어 있는 3개의 체인이름이 소문자에서 대문자로 바뀌었다.
   input, output, forward => INPUT, OUTPUT, FORWARD
(2) -i 지시자는 들어오는 인터페이스만 의미하고 입력과 포워드 체인에서만 작동한다. 포워드나
   출력체인에 사용되었던 -i는 -o로 바꿔야 한다.
(3) 기존에 단독으로 사용되었던 -p tcp 등이 --source-port등의 추가옵션과 함께 사용된다.
(4) TCP -y 옵션은 --syn으로 바뀌었고, '-p tcp' 다음에 와야 한다.
(5) DENY target이 DROP으로 바뀌었다.
(6) 만들어진 체인을 '0'으로 하면 정책카운터도 지워진다.
(7) REJECT와 LOG는 확장된 target이다.
(8) 체인 이름이 16자 까지 가능하다.
(9) MASQ와 REDIRECT는 더 이상 target이 아니다. iptables는 패킷을 변화시키지 않는다. 이것은
    NAT라는 하부구조가 있다.