Heesung Yang

[명령어] iptables

기본 개념

  • 순서대로 규칙이 적용되기 때문에 설정 순서가 중요하다.

  • 기본적으로 INPUT, OUTPUT, FORWAD Chain이 존재한다.

  • 각 Chain에 대한 기본 정책 설정

    ~$ sudo iptables -P INPUT DROP
    ~$ sudo iptables -P OUTPUT ACCEPT
    

설정 확인

  • 알려진 호스트나 포트는 사람이 알아보기 쉬운 이름으로 바꿔서 출력한다.

    ~$ sudo iptables -L
    
    Chain INPUT (policy DROP)
    target     prot opt source   destination
    ACCEPT     tcp  --  anywhere  anywhere    tcp dpt:snmp
    
  • -n 옵션을 붙이면 숫자로 출력된다. 이름 변환 과정이 없어서 출력이 더 빠르다.

    ~$ sudo iptables -nL
    
    Chain INPUT (policy DROP)
    target     prot opt source    destination
    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:161
    
  • --line-numbers 옵션을 붙이면 각 규칙 번호가 함께 출력된다. 이 번호를 이용하여 해당 규칙을 삭제하거나, 새로운 규칙을 기존 규칙 사이에 끼워넣는게 가능하다.

    ~$ sudo iptables -nL --line-numbers
    
    Chain INPUT (policy DROP)
    num  target     prot opt source    destination
    1    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:161
    2    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:80
    3    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:443
    

기본 설정법

규칙 추가

# 목적지 포트 번호가 161 인 tcp 패킷 허용
~$ sudo iptables -A INPUT -p tcp --dport 161 -j ACCEPT

# 192.168.10.0/24 에서 오는 tcp 패킷 중 목적지 포트가 161인 패킷 허용
~$ sudo iptables -A INPUT -p tcp -s 192.168.10.0/24 --dport 161 -j ACCEPT

#  특정 network interface(eth0)에서 수신하는 모든 패킷 허용
~$ sudo iptables -A INPUT -i eth0 -j ACCEPT

# 목적지 포트번호가 8000 ~ 8010 사이인 udp 패킷 허용
~$ sudo iptables -A INPUT -p udp --dport 8000:8010 -j ACCEPT

# icmp(ping) 허용
~$ sudo iptables -A INPUT -p icmp --icmp-type any -j ACCEPT

# multicast 패킷 드랍
~$ sudo iptables -A INPUT -p udp -m pkttype --pkt-type multicast -d 239.1.1.0/24 -j DROP

규칙 추가 (특정 라인)

~$ sudo iptables -nl --line-numbers
Chain INPUT (policy DROP)
num  target     prot opt source    destination
1    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:161
2    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:80
3    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:443
# 2번째 라인에 추가
~$ sudo iptables -I INPUT 2 -p tcp --dport 22 -j ACCEPT
Chain INPUT (policy DROP)
num  target     prot opt source    destination
1    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:161
2    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:22
3    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:80
4    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:443

규칙 수정

정확히 말하자면 수정이 아닌 교체다.

아래 예시의 INPUT Chain의 2번째 라인 (80번 포트) 내용을 바꿔보자.

  1. 바꿀 규칙 번호 확인

    ~$ sudo iptables -nL --line-numbers
    
    Chain INPUT (policy DROP)
    num  target     prot opt source    destination
    1    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:161
    2    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:22
    3    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:80
    4    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:443
    
  2. 2번 규칙 변경(교체)

    ~$ sudo iptables -R INPUT 3 -p tcp --dport 8080 -j ACCEPT
    
  3. 확인

    ~$ sudo iptables -nL --line-numbers
    
    Chain INPUT (policy DROP)
    num  target     prot opt source    destination
    1    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:161
    2    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:22
    3    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:8080
    4    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:443
    

규칙 삭제

아래 규칙을 삭제해보겠다.

Chain INPUT (policy DROP)
target     prot opt source     destination
ACCEPT     tcp  --  0.0.0.0/0   0.0.0.0/0   tcp dpt:161

삭제하는 방법에는 2가지가 있다.

  • -D 옵션과 삭제할 규칙 설정을 그대로 쓰는 방법 (귀찮다. 다음 방법이 더 간단하다.)

    ~$ sudo iptables -D INPUT -p tcp --dport 161 -j ACCEPT
    
  • -D 옵션과 삭제할 규칙의 순서 번호를 쓰는 방법

    Chain INPUT (policy DROP)
    num  target     prot opt source    destination
    1    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:161
    2    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:80
    3    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:443
    
    ~$ sudo iptables -D INPUT 1
    
    Chain INPUT (policy DROP)
    num  target     prot opt source    destination
    1    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:80
    2    ACCEPT     tcp  --  0.0.0.0/0  0.0.0.0/0   tcp dpt:443
    
  • 모든 규칙 삭제

    ~$ sudo iptables -F
    

설정 저장/복원

  • Ubuntu
    • iptables-persistent 라는 패키지에 의해 관리됨
    • config file : /etc/iptables/rules.v4

설정 저장

# CentOS 7
~$ sudo iptables-save > /etc/sysconfig/iptables

# Ubuntu 20.04
~$ sudo iptables-save > /etc/iptables/rules.v4

설정 복원

# CentOS 7
~$ sudo iptables-restore < /etc/sysconfig/iptables

# Ubuntu 20.04
~$ sudo iptables-restore /etc/iptables/rules.v4

로그 설정

rsyslog

  1. iptables 로깅 룰에 prefix 지정

    ~$ sudo iptables -A INPUT -j LOG --log-prefix "iptables:INPUT:DROP:" --log-level 6
    
  2. /etc/rsyslog.d/iptables.conf

    :msg, startswith, "iptables:INPUT:DROP:" -/var/log/iptables.log
    & ~
    
    • 우분투인 경우 /etc/rsyslog.d/10-iptables.conf 파일 생성한 후 설정

      기본설정 파일인 50-default.conf 보다 먼저 읽어들이기 위해 50 보다 작은 값을 파일명 앞에 써줘야 함

      :msg, contains, "iptables:INPUT:DROP:" {
      *.* /var/log/iptables.log
      stop
      }
      
  3. rsyslog 재시작

    ~$ systemctl restart rsyslog