Linux/iptables

[Linux] iptables 상태 추적 모듈 분석하기

GGkeeper 2021. 11. 13. 06:09


http://hping.org/

방화벽 테스팅 도구

1. hping 다운로드
yum -y install wget unzip gcc
wget https://github.com/antirez/hping/archive/refs/heads/master.zip
unzip master.zip
cd hping-master

yum -y install bind-utils
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 80 -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -j ACCEPT
iptables -A INPUT -j DROP

[root@firewall ~]# iptables -nL

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       all  --  0.0.0.0/0            0.0.0.0/0            state INVALID
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80 state NEW
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22 state NEW
DROP       all  --  0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination


룰 번호 2번이 protocol이 all 이므로 TCP/UDP가 모두 적용되므로 naver.com의 IP 주소를 얻어올 수 있다.
[root@firewall ~]# nslookup naver.com

Server:         192.168.108.2
Address:        192.168.108.2#53

Non-authoritative answer:
Name:   naver.com
Address: 223.130.195.95
Name:   naver.com
Address: 223.130.200.104
Name:   naver.com
Address: 223.130.195.200
Name:   naver.com
Address: 223.130.200.107


룰 번호 2번을 protocol을 all에서 tcp로 변경한다.
[root@firewall ~]# iptables -R INPUT 2 -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
[root@firewall ~]# iptables -nL

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       all  --  0.0.0.0/0            0.0.0.0/0            state INVALID
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80 state NEW
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22 state NEW
DROP       all  --  0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination


룰 번호 2번이 protocol이 tcp이므로 UDP가 허용되지 않으므로 naver.com의 IP 주소를 얻어올 수 없다.
나가는 패킷은 허용이지만 응답해서 들어오는 패킷은 거부되기 때문이다.
[root@firewall ~]# nslookup naver.com

;; connection timed out; no servers could be reached


연결된 UDP 53번 패킷을 허용하는 룰을 3번 룰에 추가한다.
[root@firewall ~]# iptables -I INPUT 3 -p udp --sport 53 -m state --state ESTABLISHED -j ACCEPT
[root@firewall ~]# iptables -nL

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       all  --  0.0.0.0/0            0.0.0.0/0            state INVALID
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
ACCEPT     udp  --  0.0.0.0/0            0.0.0.0/0            udp spt:53 state ESTABLISHED
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80 state NEW
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22 state NEW
DROP       all  --  0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination


룰을 추가했으므로 DNS 쿼리의 결과를 얻어올 수 있다.
[root@firewall ~]# nslookup naver.com

Server:         192.168.108.2
Address:        192.168.108.2#53

Non-authoritative answer:
Name:   naver.com
Address: 223.130.200.107
Name:   naver.com
Address: 223.130.200.104
Name:   naver.com
Address: 223.130.195.95
Name:   naver.com
Address: 223.130.195.200


DNS 쿼리가 어느 룰에 매칭이 되었는지 확인해보면 3번 룰인 udp spt:53 state ESTABLISHED 에 매칭된 것을 볼 수 있다. 
[root@firewall ~]# iptables -nvL

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            state INVALID
  330 23824 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
    2   224 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp spt:53 state ESTABLISHED
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80 state NEW
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22 state NEW
    5   552 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 23 packets, 3894 bytes)
 pkts bytes target     prot opt in     out     source               destination


패킷의 개수를 0으로 초기화시킨 후 다시 분석해본다.
[root@firewall ~]# iptables -Z
[root@firewall ~]# iptables -nvL

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            state INVALID
    6   432 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
    0     0 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp spt:53 state ESTABLISHED
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80 state NEW
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22 state NEW
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 4 packets, 448 bytes)
 pkts bytes target     prot opt in     out     source               destination


 nslookup : 도메인 쿼리 명령어 (old)
 dig : 도메인 쿼리 명령어 (new)
[root@firewall ~]# dig  naver.com

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.7 <<>> naver.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 7858
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; MBZ: 0x0005, udp: 4096
;; QUESTION SECTION:
;naver.com.                     IN      A

;; ANSWER SECTION:
naver.com.              5       IN      A       223.130.195.200
naver.com.              5       IN      A       223.130.195.95
naver.com.              5       IN      A       223.130.200.107
naver.com.              5       IN      A       223.130.200.104

;; Query time: 4 msec
;; SERVER: 192.168.108.2#53(192.168.108.2)
;; WHEN: 금 11월 05 20:51:19 KST 2021
;; MSG SIZE  rcvd: 102


분석해보면 udp spt:53 state ESTABLISHED 부분에 패킷이 1개가 들어온 것을 볼 수 있다.
외부 DNS 서버에서 응답한 패킷이다.
[root@firewall ~]# iptables -nvL

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            state INVALID
   50  3728 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
      130 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp spt:53 state ESTABLISHED
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80 state NEW
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22 state NEW
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 32 packets, 5290 bytes)
 pkts bytes target     prot opt in     out     source               destination


dig을 한번 더 실행한다.
[root@firewall ~]# dig  naver.com +short
223.130.195.95
223.130.195.200
223.130.200.104
223.130.200.107

다시 확인하면 패킷 카운트가 2인 것을 확인할 수 있다.
[root@firewall ~]# iptables -nvL

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            state INVALID
   76  5600 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
      260 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp spt:53 state ESTABLISHED
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80 state NEW
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22 state NEW
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 49 packets, 8316 bytes)
 pkts bytes target     prot opt in     out     source               destination


OUTPUT 정책을 분석한다.
[root@firewall ~]# iptables -A OUTPUT -m state --state INVALID -j DROP
[root@firewall ~]# iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
[root@firewall ~]# iptables -A OUTPUT -j DROP

[root@firewall ~]# iptables -nvL OUTPUT

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            state INVALID
   72  7616 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp spt:22
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0


[root@firewall ~]# nslookup naver.com
;; connection timed out; no servers could be reached

나가는 패킷의 UDP 53번을 허용한다.
[root@firewall ~]# iptables -I OUTPUT 3 -p udp --dport 53 -j ACCEPT
[root@firewall ~]# iptables -nvL OUTPUT

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            state INVALID
  157 17800 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp spt:22
    0     0 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:53
    4   241 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0


[root@firewall ~]# dig  naver.com +short
223.130.195.95
223.130.200.104
223.130.200.107
223.130.195.200

[root@firewall ~]# iptables -nvL OUTPUT

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            state INVALID
  345 42504 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp spt:22
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80
   30  1926 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:53
   32  1921 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0


yum으로 패키지를 설치하기 위해서는 OUTPUT 체인에 아래 두 개의 룰은 반드시 있어야 한다.
yum : DNS(udp 53) + http(tcp 80)

[root@firewall ~]# yum -y install mc
  :
  :(생략)

Installed:
  mc.x86_64 1:4.8.7-11.el7

Complete!

  
웹서버를 허용하기 위해서는 출발지 80을 허용해야 한다.

[root@firewall ~]# iptables -I OUTPUT 2 -p tcp --sport 80 -j ACCEPT
[root@firewall ~]# iptables -nvL OUTPUT

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            state INVALID
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp spt:80
  719  103K ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp spt:22
   47  5341 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22
  150  6717 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80
   38  2406 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:53
   39  2357 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0


Host OS에서 접속하면 접속이 성공된다.
http://192.168.108.103
Hello 192.168.108.103!

웹서버를 허용한 출발지 80을 삭제하면 웹서비스를 할 수 없다.
[root@firewall ~]# iptables -D OUTPUT 2
[root@firewall ~]# iptables -nvL OUTPUT

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            state INVALID
  745  106K ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp spt:22
   47  5341 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22
  150  6717 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80
   38  2406 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:53
   39  2357 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0


Host OS에서 접속하면 접속이 거부된다.
http://192.168.108.103

사이트에 연결할 수 없음192.168.108.3에서 응답하는 데 시간이 너무 오래 걸립니다.
다음 방법을 시도해 보세요.

연결 확인
프록시 및 방화벽 확인
Windows 네트워크 진단 프로그램 실행
ERR_CONNECTION_TIMED_OUT