안녕하세요, SATAz입니다.
이번 포스팅은 IPTables에 대해서 소개드리는 열한 번째 내용입니다.
지난 포스팅에서는 다양한 매치를 이용한 DOS Flooding 공격 방어에 대해서 다루었는데요,
이번 포스팅은 IPTables의 PREROUTING 체인을 이용해서 DDOS를 방어하는 방법에 대해서 알려드리고자 합니다.
지난 포스팅보기
[IPTables] 1.공짜방화벽 IPTables 설치하기 - CentOS 6/7 - 2017.06.24
[IPTables] 2.특정 아이피의 차단과 허용 [INPUT] - 2017.06.25
[IPTables] 3.특정 서비스 포트의 차단과 허용 [INPUT] - 2017.07.02
[IPTables] 4. -m 옵션의 사용 방법 [INPUT] - 2017.07.08
[IPTables] 5. IPTables에 의해 FTP가 차단되는 경우를 확인하자 [INPUT] - 2017.07.22
[IPTables] 6. IPTables를 사용해서 접속이 느려진다면? [INPUT] - 2017.07.23
[IPTables] 7. IPTables로 Flooding 공격을 막아보자! - 1 [INPUT / connlimit] - 2017.07.29
[IPTables] 8. IPTables로 Flooding 공격을 막아보자! - 2 [INPUT / recent] - 2017.07.30
[IPTables] 9. IPTables로 Flooding 공격을 막아보자! - 3 [INPUT / hashlimit] - 2017.08.05
[IPTables] 10. IPTables로 Flooding 공격을 막아보자! - 4 [INPUT / limit] - 2017.08.05
▣주의!!! : 이 블로그에 작성된 IPTables 포스팅들은 교육용으로 작성된 내용입니다.
서비스 중인 서버에 아래의 내용만 갖고 바로 적용하지 마시고, 서버에 적용 전에 반드시 테스트를 거치시기 바랍니다. IPTables도 방화벽인지라, 무턱대고 서버에 적용했다가는 서비스 중단되는 사태가 발생할 수 있습니다. 필히 주의하셔야합니다!!!
#IPTables 설정를 위한 환경
- 테스트 머신 : VMware WorkStation 12 Player
- 운영체제 : CentOS/RHEL 7 - 64bit ( Minimal 설치 )
- 메모리 : 2GB
- IPTables Version : iptables v1.4.21
- 서버 아이피 : 192.168.0.18
# 공격을 위한 서버 설정 환경
- 공격자 테스트 머신 : VMware WorkStation 12 Player
- 공격자 운영체제 : CentOS/RHEL 6 - 64bit ( Minimal 설치 )
- 공격자 메모리 : 2GB
- 공격자 서버 아이피 : 192.168.0.19
1. DOS/DDOS 공격을 방어하기 전에 SYN-Flooding이 무엇인지 짚고넘어가자.
Flooding 공격을 방어하기 위해서는, 어떠한 방식으로 Flooding 공격이 이뤄지는지에 대해서 먼저 알고가셔야 합니다.
다른 카테고리의 포스팅을 먼저 읽어 보신 뒤에, 방어하는 방법에 대해서 읽어주시기 바랍니다.
클릭하여 포스팅보기> [DOS/DDOS] SYN Flooding 공격에 대해서 알아보자. <클릭하여 포스팅보기
2. SYN PROXY는 무엇인가?
"[DOS/DDOS] SYN Flooding 공격에 대해서 알아보자." 포스팅에서도 설명드렸다싶이, 방화벽에서 3-way-handshake가 정상적으로 이루어진 연결인지 먼저 확인하고 -> Server에게 그 과정을 다시 재현해주는 방법입니다.
이를 iptables에서 간단하게 구현할 수가 있죠.
3. Iptables SYN PROXY 설정 명령어
# SYN PROXY 구현 명령어
iptables -I INPUT -d 192.168.0.18 -p tcp -m tcp --dport 80 -m state --state INVALID -j DROP
iptables -I INPUT -d 192.168.0.18 -p tcp -m tcp --dport 80 -m state --state INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
iptables -t raw -I PREROUTING -d 192.168.0.18 -p tcp -m tcp --syn --dport 80 -j CT --notrack
/sbin/sysctl -w net/netfilter/nf_conntrack_tcp_loose=0
/sbin/sysctl -w net/ipv4/tcp_timestamps=1
/sbin/sysctl -w net/netfilter/nf_conntrack_max=2000000
sh -c 'echo 2000000 > /sys/module/nf_conntrack/parameters/hashsize'
드디어!!! PREROUTING에서 설명드릴 시간이 되었습니다. 패킷의 흐름이 아래의 순서로 진행된다고 보시면 됩니다.
PREROUTING -> INPUT (FORWARD) -> OUTPUT -> POSTROUTING
패킷 들어옴 ----------------------------> 나감
PREROUTING 체인은 INPUT 체인으로 들어오기 전에, 패킷이 한번 거쳐가는 체인입니다.
iptables 명령어에 -I 옵션을 적용하면 명령어 입력 순서와, 명령어가 적용된 후의 룰 순서가 달라서,
이해를 돕기 위해 하나하나 나누어서 설명드리도록 하겠습니다.
3-1. SYN PROXY 설정 명령어 설명 - 1
# SYN PROXY 구현 명령어
iptables -I PREROUTING -d 192.168.0.18 -p tcp -m tcp --dport 80 --tcp-flags FIN,SYN,RST,ACK SYN -j CT --notrack
해석:
PREROUTING 단계에서 192.168.0.18 서버의 80포트로 들어오는 패킷들의 내용 중에, FIN,SYN,RST,ACK 플래그 중에서 SYN이 있는지 확인한다. SYN 패킷이 있으면, target (목적지)는 "CT"이다. 그리고 연결추적(conntracking)을 하지 않는다.
CT target이 무엇인지 설명을 드려야겠군요.
CT는 conntrack을 줄여놓은 단어입니다. conntrack은 connection track을 줄여놓은 말이며, 한글로 해석하면 "연결 추적" 입니다.
즉, CT target은 패킷에 연결 추적용 템플릿을 덧붙여서, conntrack 코어가 패킷을 추적할 수 있게 도와주는 타겟입니다.
하지만!! 위의 명령어는 "--notrack" 옵션으로 연결추적을 하지 않도록 설정했습니다.
그 이유는 다음 명령어 줄(command line)을 보고 설명드리겠습니다.
3-2. SYN PROXY 설정 명령어 설명 - 2
# SYN PROXY 구현 명령어
iptables -I INPUT -d 192.168.0.18 -p tcp -m tcp --dport 80 -m state --state INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
해석:
INPUT 단계에서 192.168.0.18 서버의 80포트로 들어오는 패킷들 중에, INVALID하고 UNTRACKED된 패킷들은 SYNPROXY 타겟으로 보낸다. (이 명령어로 SYN PROXY가 구현되었음)
상태(--state)에서 나타난 INVALID, UNTRACKED는 각각 아래와 같이 의미합니다.
● INVALID : 3-way-handshake에 의해서 들어오는 Client의 ACK 패킷
● UNTRACKED : SYN 패킷 ("3-1. SYN PROXY 구현명령어 설명"에서 "--tcp-flags FIN,SYN,RST,ACK SYN" 옵션으로 syn을 걸러내고, --notrack으로 추적하지 않겠다고 설정했었음)
--sack-perm, --timestamp, --wscale 7, -mss 1460은 각각 아래와 같이 의미합니다.
● --sack-perm : 클라이언트의 선택적인 acknowlegement 옵션을, 그 다음에 있는 방화벽 룰로 넘깁니다.
● --timestamp : 클라이언트의 timestamp(시간값)을, 그 다음에 있는 방화벽 룰로 넘깁니다.
● --wscale 7 : Firewall이 클라이언트에게 알려준 window size (전송 가능 크기) 입니다.
● --mss 1460 : Firewall이 클라이언트에게 알려준 최대 segment 크기입니다. (segment = tcp의 데이터 단위 ≒ PDU<Process Data Unit>)
3-3. SYN PROXY 설정 명령어 설명 - 3
# SYN PROXY 구현 명령어
iptables -I INPUT -d 192.168.0.18 -p tcp -m tcp --dport 80 -m state --state INVALID -j DROP
이 명령어는 SYN PROXY와는 무관하게, 비정상적인 패킷이 들어오게 되면 차단하는 역할을 합니다.
SYN Flood는 SYN PROXY로 막고, 나머지 ACK Flood, SYN-ACK Flood, FIN Flood 등을 차단합니다.
3-4. SYN PROXY 설정 명령어 설명 - 4
# SYN PROXY 구현 명령어
/sbin/sysctl -w net/netfilter/nf_conntrack_tcp_loose=0
/sbin/sysctl -w net/ipv4/tcp_timestamps=1
/sbin/sysctl -w net/netfilter/nf_conntrack_max=2000000
sh -c 'echo 2000000 > /sys/module/nf_conntrack/parameters/hashsize'
● nf_conntrack_tcp_loose=0 : SYN PROXY에서, 3-way-handshake에 의해 들어오는 ACK 패킷을 허용하기 위해 0으로 설정합니다.
원래 용도 : 이미 연결이 성립되어있는 패킷들을, iptables에서 잡아낼 지 말지를 설정하는데 사용됨 (0=disable / the other=enable)
● tcp_timestamps=1 : SYN PROXY에서, TCP 옵션으로 SYN Cookie를 사용하기 위해 1로 설정합니다.
원래 용도 : RFC1323 규약에 정의된 TIMESTAMP를 사용하는데 랜덤하게 TIMESTAMP를 찍을 것인지, 현재 시간을 TIMESTAMP 찍을 것인지 설정하는데 사용됨 (0=disable / 1=enable as RFC1323 to random offset / 2=enable as RFC1323 without random offset <current time>)
● nf_conntrack_max=2000000 : conntrack(연결 추적)의 개수를 2백만개 까지 제한합니다.
원래 용도 : 설정 용도와 같습니다. (메모리 계산법 = 288 bytes * 2,000,000 = 576.0MB)
기본값 : 65536 (시스템에 따라 다를 수 있음)
● echo 2000000 > /sys/module/nf_conntrack/parameters/hashsize : conntrack 파라미터의 해시 테이블의 사이즈를 2백만 bucket으로 제한한다.
원래 용도 : 설정 용도와 같습니다. (메모리 계산법 = Hash 8 bytes * 2,000,000 = 16MB)
기본값 : nf_conntrack_max의 값 / 4 = 16384 (시스템에 따라 다를 수 있음)
4. 명령어의 적용
# 명령어의 적용
[root@localhost ~]# iptables -I INPUT -d 192.168.0.18 -p tcp -m tcp --dport 80 -m state --state INVALID -j DROP
[root@localhost ~]# iptables -I INPUT -d 192.168.0.18 -p tcp -m tcp --dport 80 -m state --state INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
[root@localhost ~]# iptables -t raw -I PREROUTING -d 192.168.0.18 -p tcp -m tcp --syn --dport 80 -j CT --notrack
[root@localhost ~]#
[root@localhost ~]# /sbin/sysctl -w net/netfilter/nf_conntrack_tcp_loose=0
net.netfilter.nf_conntrack_tcp_loose = 0
[root@localhost ~]# /sbin/sysctl -w net/ipv4/tcp_timestamps=1
net.ipv4.tcp_timestamps = 1
[root@localhost ~]# /sbin/sysctl -w net/netfilter/nf_conntrack_max=2000000
net.netfilter.nf_conntrack_max = 2000000
[root@localhost ~]# sh -c 'echo 2000000 > /sys/module/nf_conntrack/parameters/hashsize'
[root@localhost ~]#
[root@localhost ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
SYNPROXY tcp -- 0.0.0.0/0 192.168.0.18 tcp dpt:80 state INVALID,UNTRACKED SYNPROXY sack-perm timestamp wscale 7 mss 1460
DROP tcp -- 0.0.0.0/0 192.168.0.18 tcp dpt:80 state INVALID
ACCEPT tcp -- 0.0.0.0/0 192.168.0.18 tcp dpt:80
ACCEPT all -- 0.0.0.0/0 192.168.0.18 state RELATED,ESTABLISHED
ACCEPT tcp -- 192.168.0.2 192.168.0.18 tcp dpt:22
ACCEPT all -- 192.168.0.1 192.168.0.18
ACCEPT all -- 8.8.8.8 192.168.0.18
DROP all -- 0.0.0.0/0 192.168.0.18
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
정상적인 패킷과 SYN Flood 패킷이 모두, SYNPROXY 타겟을 거친 다음에 80 ACCEPT로 들어오게 됩니다.
따라서 SYN PROXY 설정을 하고나서 80을 차단되게끔 설정하시면, 웹서비스가 안될 것입니다.
즉, SYN PROXY 설정 밑에 80포트를 허용할 수 있도록 방화벽 룰을 구성해야한다는 의미이죠.
이제 공격을 한번 해보도록 하겠습니다.
5. DoS/DDoS 공격을 받았을 때의 상황.
# SYN PROXY를 적용한 후에, DoS/DDoS 공격을 받았을 때의 상황
[root@localhost ~]# iptables -nL -v
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
123K 5515K SYNPROXY tcp -- * * 0.0.0.0/0 192.168.0.18 tcp dpt:80 state INVALID,UNTRACKED SYNPROXY sack-perm timestamp wscale 7 mss 1460
0 0 DROP tcp -- * * 0.0.0.0/0 192.168.0.18 tcp dpt:80 state INVALID
0 0 ACCEPT tcp -- * * 0.0.0.0/0 192.168.0.18 tcp dpt:80
141 9872 ACCEPT all -- * * 0.0.0.0/0 192.168.0.18 state RELATED,ESTABLISHED
0 0 ACCEPT tcp -- * * 192.168.0.2 192.168.0.18 tcp dpt:22
0 0 ACCEPT all -- * * 192.168.0.1 192.168.0.18
0 0 ACCEPT all -- * * 8.8.8.8 192.168.0.18
204 13872 DROP all -- * * 0.0.0.0/0 192.168.0.18
[root@localhost ~]#
[root@localhost ~]# netstat -anp | more
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1186/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1919/master
tcp 0 52 192.168.0.18:22 192.168.0.2:56679 ESTABLISHED 2160/sshd: root@pts
tcp6 0 0 :::80 :::* LISTEN 2912/httpd
tcp6 0 0 :::22 :::* LISTEN 1186/sshd
tcp6 0 0 ::1:25 :::* LISTEN 1919/master
udp 0 0 127.0.0.1:323 0.0.0.0:* 477/chronyd
udp 0 0 0.0.0.0:40921 0.0.0.0:* 572/dhclient
udp 0 0 0.0.0.0:68 0.0.0.0:* 572/dhclient
udp6 0 0 ::1:323 :::* 477/chronyd
udp6 0 0 :::4525 :::* 572/dhclient
차단이 아주 잘 되어, netstat 명령어 상에서 httpd 서비스로 붙은 Client가 없는 것이 확인됩니다.
차단이 잘 되는지 확인하기 위해서는 어디를 확인해야하냐구요?
바로 요부분입니다.
# 패킷의 변화량을 비교해보자. - 집중해야할 부분
[root@localhost ~]# iptables -nL -v
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
123K 5515K SYNPROXY tcp -- * * 0.0.0.0/0 192.168.0.18 tcp dpt:80 state INVALID,UNTRACKED SYNPROXY sack-perm timestamp wscale 7 mss 1460
...
0 0 ACCEPT tcp -- * * 0.0.0.0/0 192.168.0.18 tcp dpt:80
...
SYN PROXY 타겟의 pkts(패킷 개수)와 bytes(패킷 용량)은 엄청나게 증가하고 있는 반면에,
tcp dpt:80 ACCEPT 타겟의 pkts(패킷 개수)와 bytes(패킷 용량)은 0을 유지하고 있습니다.
만약 정상적인 접근이 있을 경우에는 tcp dpt:80 ACCEPT 타겟의 pkts와 bytes가 증가할 것입니다.
아래의 화면은, 정상적인 웹서비스 접근이 발생했을 때의 상황입니다.
# 공격이 들어오는 중에, 정상적인 웹서비스 연결이 있을 때의 상황
[root@localhost ~]# iptables -nL -v
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
156K 7000K SYNPROXY tcp -- * * 0.0.0.0/0 192.168.0.18 tcp dpt:80 state INVALID,UNTRACKED SYNPROXY sack-perm timestamp wscale 7 mss 1460
0 0 DROP tcp -- * * 0.0.0.0/0 192.168.0.18 tcp dpt:80 state INVALID
25 6118 ACCEPT tcp -- * * 0.0.0.0/0 192.168.0.18 tcp dpt:80
195 14288 ACCEPT all -- * * 0.0.0.0/0 192.168.0.18 state RELATED,ESTABLISHED
0 0 ACCEPT tcp -- * * 192.168.0.2 192.168.0.18 tcp dpt:22
0 0 ACCEPT all -- * * 192.168.0.1 192.168.0.18
0 0 ACCEPT all -- * * 8.8.8.8 192.168.0.18
0 0 DROP all -- * * 0.0.0.0/0 192.168.0.18
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 156K packets, 6245K bytes)
pkts bytes target prot opt in out source destination
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# netstat -anp | more
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 192.168.0.18:80 192.168.0.2:50541 SYN_RECV -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1186/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1919/master
tcp 0 52 192.168.0.18:22 192.168.0.2:56679 ESTABLISHED 2160/sshd: root@pts
tcp6 0 0 :::80 :::* LISTEN 9148/httpd
tcp6 0 0 :::22 :::* LISTEN 1186/sshd
tcp6 0 0 ::1:25 :::* LISTEN 1919/master
tcp6 0 0 192.168.0.18:80 192.168.0.2:50540 ESTABLISHED 9149/httpd
udp 0 0 127.0.0.1:323 0.0.0.0:* 477/chronyd
udp 0 0 0.0.0.0:40921 0.0.0.0:* 572/dhclient
udp 0 0 0.0.0.0:68 0.0.0.0:* 572/dhclient
udp6 0 0 ::1:323 :::* 477/chronyd
udp6 0 0 :::4525 :::* 572/dhclient
6. SYN PROXY를 적용하지 않았을 때, 공격이 들어온다면?'
# SYN PROXY를 적용하지 않고, DoS공격을 받았을 때의 상황
[root@localhost ~]# iptables -nL -v
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
145K 6541K ACCEPT tcp -- * * 0.0.0.0/0 192.168.0.18 tcp dpt:80
463 33360 ACCEPT all -- * * 0.0.0.0/0 192.168.0.18 state RELATED,ESTABLISHED
0 0 ACCEPT tcp -- * * 192.168.0.2 192.168.0.18 tcp dpt:22
0 0 ACCEPT all -- * * 192.168.0.1 192.168.0.18
0 0 ACCEPT all -- * * 8.8.8.8 192.168.0.18
0 0 DROP all -- * * 0.0.0.0/0 192.168.0.18
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 941 packets, 77772 bytes)
pkts bytes target prot opt in out source destination
[root@localhost ~]# netstat -anp | more
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 192.168.0.18:80 192.168.0.19:1026 SYN_RECV -
tcp 0 0 192.168.0.18:80 192.168.0.19:9132 SYN_RECV -
tcp 0 0 192.168.0.18:80 192.168.0.19:5476 SYN_RECV -
tcp 0 0 192.168.0.18:80 192.168.0.19:1756 SYN_RECV -
tcp 0 0 192.168.0.18:80 192.168.0.19:1999 SYN_RECV -
tcp 0 0 192.168.0.18:80 192.168.0.19:4055 SYN_RECV -
tcp 0 0 192.168.0.18:80 192.168.0.19:2001 SYN_RECV -
tcp 0 0 192.168.0.18:80 192.168.0.2:50112 SYN_RECV -
tcp 0 0 192.168.0.18:80 192.168.0.19:1234 SYN_RECV -
tcp 0 0 192.168.0.18:80 192.168.0.19:2873 SYN_RECV -
tcp 0 0 192.168.0.18:80 192.168.0.19:6000 SYN_RECV -
tcp 0 0 192.168.0.18:80 192.168.0.19:3055 SYN_RECV -
tcp 0 0 192.168.0.18:80 192.168.0.19:1739 SYN_RECV -
tcp 0 0 192.168.0.18:80 192.168.0.19:9000 SYN_RECV -
tcp 0 0 192.168.0.18:80 192.168.0.19:20000 SYN_RECV -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1186/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1919/master
tcp 0 52 192.168.0.18:22 192.168.0.2:56679 ESTABLISHED 2160/sshd: root@pts
tcp6 0 0 :::80 :::* LISTEN 8710/httpd
tcp6 0 0 :::22 :::* LISTEN 1186/sshd
tcp6 0 0 ::1:25 :::* LISTEN 1919/master
tcp6 0 0 192.168.0.18:80 192.168.0.2:50111 FIN_WAIT2 -
udp 0 0 127.0.0.1:323 0.0.0.0:* 477/chronyd
udp 0 0 0.0.0.0:40921 0.0.0.0:* 572/dhclient
udp 0 0 0.0.0.0:68 0.0.0.0:* 572/dhclient
udp6 0 0 ::1:323 :::* 477/chronyd
udp6 0 0 :::4525 :::* 572/dhclient
# SYN PROXY를 적용하지 않고, DDoS공격을 받았을 때의 상황
[root@localhost ~]# iptables -nL -v
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
26826 1207K ACCEPT tcp -- * * 0.0.0.0/0 192.168.0.18 tcp dpt:80
51 3756 ACCEPT all -- * * 0.0.0.0/0 192.168.0.18 state RELATED,ESTABLISHED
0 0 ACCEPT tcp -- * * 192.168.0.2 192.168.0.18 tcp dpt:22
0 0 ACCEPT all -- * * 192.168.0.1 192.168.0.18
0 0 ACCEPT all -- * * 8.8.8.8 192.168.0.18
0 0 DROP all -- * * 0.0.0.0/0 192.168.0.18
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 27372 packets, 1207K bytes)
pkts bytes target prot opt in out source destination
[root@localhost ~]#
[root@localhost ~]# netstat -nap | more
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 192.168.0.18:80 213.220.211.216:2001 SYN_RECV -
tcp 0 0 192.168.0.18:80 221.212.212.218:5476 SYN_RECV -
tcp 0 0 192.168.0.18:80 222.212.228.212:1026 SYN_RECV -
tcp 0 0 192.168.0.18:80 218.215.211.227:3055 SYN_RECV -
tcp 0 0 192.168.0.18:80 212.217.226.223:1739 SYN_RECV -
tcp 0 0 192.168.0.18:80 222.216.213.213:1756 SYN_RECV -
tcp 0 0 192.168.0.18:80 217.219.219.213:9132 SYN_RECV -
tcp 0 0 192.168.0.18:80 217.216.216.219:1234 SYN_RECV -
tcp 0 0 192.168.0.18:80 214.228.226.224:1234 SYN_RECV -
tcp 0 0 192.168.0.18:80 222.226.210.225:1756 SYN_RECV -
tcp 0 0 192.168.0.18:80 217.228.212.225:5476 SYN_RECV -
tcp 0 0 192.168.0.18:80 214.217.213.218:2873 SYN_RECV -
tcp 0 0 192.168.0.18:80 216.220.210.217:1234 SYN_RECV -
tcp 0 0 192.168.0.18:80 219.213.221.215:1026 SYN_RECV -
tcp 0 0 192.168.0.18:80 217.229.218.224:2873 SYN_RECV -
tcp 0 0 192.168.0.18:80 219.228.219.221:9000 SYN_RECV -
tcp 0 0 192.168.0.18:80 215.216.216.211:2873 SYN_RECV -
tcp 0 0 192.168.0.18:80 220.227.214.226:6000 SYN_RECV -
tcp 0 0 192.168.0.18:80 219.223.210.222:3055 SYN_RECV -
tcp 0 0 192.168.0.18:80 211.228.216.224:1999 SYN_RECV -
tcp 0 0 192.168.0.18:80 212.215.227.225:9132 SYN_RECV -
tcp 0 0 192.168.0.18:80 222.227.221.222:3055 SYN_RECV -
tcp 0 0 192.168.0.18:80 223.228.212.228:20000 SYN_RECV -
tcp 0 0 192.168.0.18:80 223.218.228.220:1999 SYN_RECV -
tcp 0 0 192.168.0.18:80 211.213.229.213:1999 SYN_RECV -
tcp 0 0 192.168.0.18:80 222.213.210.221:5476 SYN_RECV -
tcp 0 0 192.168.0.18:80 216.224.215.229:20000 SYN_RECV -
tcp 0 0 192.168.0.18:80 223.215.220.213:1026 SYN_RECV -
tcp 0 0 192.168.0.18:80 221.213.210.226:6000 SYN_RECV -
netstat를 보면 참으로 처참합니다...
7. SYN PROXY 설정의 한계를 알고 방화벽에 적용하자.
어딜가나... 모든 설정에 대해서는 한계가 있습니다. 물론 시스템 자원적인 상황에서는 CPU와 메모리를 확인해봐야 하지만,
더 큰 한계가 있습니다.
1) CentOS7 이후에서만 지원이 가능하다.
CentOS 6에서 위의 설정을 적용하게 되면, 아래와 같은 에러메시지가 출력됩니다.
# CentOS 6 IPTables에서의 에러메시지
[root@localhost ~]# iptables -t raw -I PREROUTING -i ens33 -p tcp -m tcp --syn --dport 80 -j CT --notrack
iptables v1.4.7: unknown option `--notrack'
Try `iptables -h' or 'iptables --help' for more information.
[root@localhost ~]# iptables -I INPUT -d 192.168.0.18 -p tcp -m tcp --dport 80 -m state --state INVALID -j DROP
[root@localhost ~]# iptables -I INPUT -d 192.168.0.18 -p tcp -m tcp --dport 80 -m state --state INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460
iptables v1.4.7: unknown option `--sack-perm'
Try `iptables -h' or 'iptables --help' for more information.
이 메시지는, IPTables v1.4.7에서는 --notrack과 --sack-perm 옵션을 지원하지 않기 때문입니다.
이러한 설정을 사용하기 위해서는 환경이 아래와 같이 갖추어져야 합니다.
리눅스 커널 버전 : kernel 3.10 이상
IPTables 버전 : v1.4.27
<<커널 버전은 "uname -a" 명령어, IPTables 버전은 "iptables -V" 명령어로 확인 가능합니다.>>
위의 사용 환경을 기본적으로 지원하는 것이 CentOS 7입니다.
혹시 CentOS 6에서도 사용하고 싶으시면... 아래의 글을 참고해보시는 것도 괜찮을 듯 합니다만... 저는 비추하겠습니다.
# CentOS 6에서 사용하는 방법 (비추함, 그냥 이런것도 있구나... 하고 넘겨주세요)
Exactly... you need iptables v1.4.21, you can run the commands below: wget http://www.netfilter.org/projects/iptables/files/iptables-1.4.21.tar.bz2 tar xvf iptables-1.4.21.tar.bz2 cd iptables-1.4.21/ ./configure && make sudo make install Remember you also need a newer kernel... minimum kernel 3.13, but preferably the upcoming nf-next kernel, for the conntrack scaling: https://git.kernel.org/cgit/linux/kernel/git/pablo/nf-next.git/ git clone git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git cd nf-next/ make menuconfig #(select all netfilter modules) make -j24 make install #(depend on your distro) #On Debian perhaps also run these: export VER=`cat include/config/kernel.release` depmod -a ${VER} mkinitramfs -o /boot/initrd.img-$VER $VER update-grub2 # (reboot and select kernel) Good luck, fighting your DDoS... --Jesper 출처 : https://www.spinics.net/lists/netfilter/msg55181.html
개인적으로 source 패키지로 컴파일 하는 것을 무지 싫어하는 성격인데다가,
RedHat Linux의 기본 repository에서 지원하지 않는 커널을 설치해야한다는 것이 너무 극혐입니다.
글쓴이가 순정을 워낙 좋아하는 성격이다보니... 그런 것일 수도 있습니다.
8. SYN PROXY 설정을 사용할 때 주의할 점.
IPTables 서비스를 재시작하게 되면, 설정들이 모두 날라가게됩니다.
conntrack_max 크기와 conntrack_bucket 크기 등등.. 모든 설정들이 날라갑니다.
따라서 IPTables 서비스를 재시작하거나, 시스템을 재부팅해야할 일이 있으면 위의 명령어를 수동으로 입력해주어야 한다는 점입니다.
뭐... 그런 부분은 "/etc/rc.local"에다가 명령어를 추가하시거나, 스크립트를 만들어서 관리하시는 것이 좋을 것으로 사료됩니다.
생각 외로 글이 길어졌습니다... 긴 글 읽어주셔서 감사합니다.
다음 포스팅은 GeoIP를 이용한 국가별 아이피대역을 차단하는 방법에 대해 소개해드리도록 하겠습니다^^
'보안 Story > IPTables' 카테고리의 다른 글
[IPTables] 13. IPTables에서 국가별 아이피대역을 차단하는 방법 [GeoIP] (5) | 2017.08.20 |
---|---|
[IPTables] 12. IPTables에 GeoIP를 설치해보자. [GeoIP ][CentOS 6/CentOS 7] (3) | 2017.08.19 |
[IPTables] 10. IPTables로 Flooding 공격을 막아보자! - 4 [INPUT / limit] (27) | 2017.08.06 |
[IPTables] 9. IPTables로 Flooding 공격을 막아보자! - 3 [INPUT / hashlimit] (9) | 2017.08.05 |
[IPTables] 8. IPTables로 Flooding 공격을 막아보자! - 2 [INPUT / recent] (0) | 2017.07.30 |