SYN-Flooding 공격 방어

by 조쉬 posted Apr 22, 2016
?

단축키

Prev이전 문서

Next다음 문서

ESC닫기

크게 작게 위로 아래로 댓글로 가기 인쇄

[개념 따라 잡기]

SYN-Flooding 공격
- DDOS공격의 한 종류

SYN-Flooding 공격 원리

1단계.  A 클라이언트는 B 서버에 접속을 요청하는 SYN 패킷을 보낸다.
2단계.  B 서버는 요청을 받고 A 클라이언트에게 요청을 수락한다는  SYN 패킷과 ACK 패킷을 발송한다. 
3단계.  A 클라이언트는 B 서버에게 ACK 를 보내고 이후로부터 연결이 이루어지고 본격적으로 데이터가 교환된다.

SYN-Flooding 공격은 A클라이언트가 B서버에게 ACK를 보내지 않기 때문이다.
A클라이언트가 B서버에게 ACK를 보내지 안으면 이 연결은 메모리 공간인 백로그큐(Backlog  Queue)에 계속 쌓이게 된다.

이처럼 백로그큐가 가득찼을 경우에 공격을 당한 해당 포트로만 접속이 이루어지지 않을 뿐 다른 포트에는 영향을 
주지 않고, 또한 서버에 별다른 부하도유발하지 않으므로 관리자가 잘 모르는 경우가 많다.  
또한 다른 DoS 공격과는 달리 많은 트래픽을 유발하는 공격이 아니므로쉽게 파악이 되지 않는 공격 형태이다.

SYN-Flooding 공격 대처
1. syncookies 기능 활용
실무에서의 효과 - 공격을 받는 포트가 죽지는 않는다.
syncookies 기능은 TCP_Syn_Flooding 공격을 차단하기 위한 가장 확실한 방법으로 이 기능을 이용하려면 
일단 커널 컴파일 옵션에서 CONFIG_SYN_COOKIES이 Y 로 선택되어 있어야 한다.

자신의 커널 옵션에 이 기능이 설정되어 있는지 확인하려면 
]#cd /usr/src/linux 
]#make menuconfig 
Networking options  ---> 
[*]   IP: TCP syncookie support (disabled per default) 
만약 설정이 되어 있지 않다면 선택 후 커널 컴파일을 다시 하여야 하지만 대부분 배포판은 기본적으로 
이 옵션이 선택되어 있으므로 걱정할 필요는 없다.

그러나 위와 같이 커널 옵션에 설정되어 있다 하더라도 실제 syncookies 적용은 꺼져 있으므로 
이 값을 다음과 같은 방법으로 활성화해야 한다.

]# cat /proc/sys/net/ipv4/tcp_syncookies
0
0 으로 설정되어 있으므로  현재 syncookies는 적용되지 않는다. 
따라서 아래와 같이 1을 설정하여 syncookies 기능을 활성화하도록 한다. 

]# sysctl -w net.ipv4.tcp_syncookies=1
or
]#echo 1 > /proc/sys/net/ipv4/tcp_syncookies

syncookies는 백로그큐가 가득 찼을 경우에도 정상적인 접속 요구를 계속 받아들일 수 있도록 해 주므로  SYN_Flooding 공격에 대비한 가장 효과적인 방법중 하나이다.

2. iptables 활용

[기본 정보]

* centos 의 커널이 적재 되는 곳은 "/lib/modules" 이다


[시나리오]

connlimit 모듈을 설치하고 connlimit 옵션을 사용하여 SYN-Flooding 공격을 방어해 보자


[해결 방법]

1. 커널 패치(p-o-m)파일과 iptables 상위버전 다운로드
[root@localhost ~]# cd /usr/src
[root@localhost src]# lftpget http://ftp.netfilter.org/pub/patch-o-matic-ng/snapshot/patch-o-matic-ng-20080923.tar.bz2

[root@localhost src]# lftpget http://ftp.netfilter.org/pub/iptables/iptables-1.3.8.tar.bz2

*patch-o-matic-ng-20080923.tar.bz2 날짜순으로 업데이트 되는 자료

2. 압축 해제 및 export

[root@localhost src]# tar xjf iptables-1.3.8.tar.bz2
[root@localhost src]# tar xjf patch-o-matic-ng-20080923.tar.bz2
[root@localhost src]# cd patch-o-matic-ng-20080923
[root@localhost patch-o-matic-ng-20080923]# export export KERNEL_DIR=/usr/src/kernels/2.6.18-92.1.10.el5-i686/
[root@localhost patch-o-matic-ng-20080923]# export IPTABLES_DIR=/usr/src/iptables-1.3.8/
[root@localhost patch-o-matic-ng-20080923]# ./runme --download

Successfully downloaded external patch geoip
Successfully downloaded external patch condition
Successfully downloaded external patch IPMARK
Successfully downloaded external patch ROUTE
Successfully downloaded external patch connlimit
Successfully downloaded external patch ipp2p
Successfully downloaded external patch time
./patchlets/ipv4options exists and is not external
./patchlets/TARPIT exists and is not external
Successfully downloaded external patch ACCOUNT
Successfully downloaded external patch pknock
Loading patchlet definitions......................... done


Excellent! Source trees are ready for compilation.

[에러 발생]

에러 메세지 : "/usr/src/kernels/2.6.18-92.1.10.el5-i686/ doesn't seem to be a directory"

커널의 위치가 아니라는 메세지 입니다.

[해결 방법]

]#yum install -y kernel-devel.i686

실행이 완료되면 /usr/src/kernels/2.6.18-XX.X.XX.el5-i686/ 생성된다.


3. connlimit 컴파일

[root@localhost patch-o-matic-ng-20080923]# ./runme connlimit

Loading patchlet definitions......................... done
Welcome to Patch-o-matic ($Revision$)!

Kernel:   2.6.18, /usr/src/kernels/2.6.18-92.1.10.el5-i686/
Iptables: 1.3.8, /usr/src/iptables-1.3.8/
Each patch is a new feature: many have minimal impact, some do not.
Almost every one has bugs, so don't apply what you don't need!
-------------------------------------------------------
Already applied:
Testing connlimit... not applied
The connlimit patch:
   Author: Gerd Knorr <kraxel@bytesex.org>
   Status: ItWorksForMe[tm]

This adds an iptables match which allows you to restrict the
number of parallel TCP connections to a server per client IP address
(or address block).

Examples:

# allow 2 telnet connections per client host
iptables -p tcp --syn --dport 23 -m connlimit --connlimit-above 2 -j REJECT

# you can also match the other way around:
iptables -p tcp --syn --dport 23 -m connlimit ! --connlimit-above 2 -j ACCEPT

# limit the nr of parallel http requests to 16 per class C sized
# network (24 bit netmask)
iptables -p tcp --syn --dport 80 -m connlimit --connlimit-above 16 \
        --connlimit-mask 24 -j REJECT
-----------------------------------------------------------------
Do you want to apply this patch [N/y/t/f/a/r/b/w/q/?] y

Excellent! Source trees are ready for compilation.


4. 컴파일 환경설정 추가 

[root@localhost patch-o-matic-ng-20080923]# cd /usr/src/kernels/2.6.18-92.1.10.el5-i686/
[root@localhost 2.6.18-92.1.10.el5-i686]# make oldconfig
HOSTLD  scripts/kconfig/conf
scripts/kconfig/conf -o arch/i386/Kconfig
*
* Linux Kernel Configuration
*
*
* Code maturity level options
*
Prompt for development and/or incomplete code/drivers (EXPERIMENTAL) [Y/n/?] y
*
* General setup
*
...중략...
    Connections/IP limit match support (IP_NF_MATCH_CONNLIMIT) [M/n/?] m
...중략...

#
# configuration written to .config
#
[에러 발생]
/bin/sh: gcc: command not found
make[1]: *** [scripts/basic/fixdep] 오류 127
make: *** [scripts_basic] 오류 2
[해결 방법]
]# yum install -y gcc

4. 모듈 준비 및 환경 설정
[root@localhost 2.6.18-92.1.10.el5-i686]# make modules_prepare
scripts/kconfig/conf -s arch/i386/Kconfig
CHK     include/linux/version.h
CHK     include/linux/utsrelease.h
HOSTLD  scripts/genksyms/genksyms
MKELF   scripts/mod/elfconfig.h
HOSTCC  scripts/mod/file2alias.o
HOSTCC  scripts/mod/modpost.o
HOSTCC  scripts/mod/sumversion.o
HOSTLD  scripts/mod/modpost

[root@localhost 2.6.18-92.1.10.el5-i686]# cp net/ipv4/netfilter/Makefile net/ipv4/netfilter/Makefile.orig
[root@localhost 2.6.18-92.1.10.el5-i686]# vim net/ipv4/netfilter/Makefile
[추가 소스]

obj-m := ipt_connlimit.o

KDIR := /lib/modules/$(shell uname -r)/build
PWD   := $(shell pwd)

default:
$(MAKE) -C $(KDIR) M=$(PWD) modules

[root@localhost 2.6.18-92.1.10.el5-i686]# make M=net/ipv4/netfilter/
CC [M]  net/ipv4/netfilter/ipt_connlimit.o
Building modules, stage 2.
MODPOST
CC      net/ipv4/netfilter/ipt_connlimit.mod.o
LD [M]  net/ipv4/netfilter/ipt_connlimit.ko


5. 모듈 복사 및 권한 설정

[root@localhost 2.6.18-92.1.10.el5-i686]# cp net/ipv4/netfilter/ipt_connlimit.ko /lib/modules/2.6.18-92.1.10.el5/kernel/net/ipv4/netfilter/
[root@localhost 2.6.18-92.1.10.el5-i686]# chmod 744 /lib/modules/2.6.18-92.1.10.el5/kernel/net/ipv4/netfilter/ipt_connlimit.ko

6. 추가 모듈 확인
[root@localhost 2.6.18-92.1.10.el5-i686]# depmod -a
[root@localhost 2.6.18-92.1.10.el5-i686]# ls /lib/modules/2.6.18-92.1.10.el5/kernel/net/ipv4/netfilter/
arp_tables.ko               ip_nat_irc.ko         ipt_TTL.ko
arpt_mangle.ko              ip_nat_pptp.ko        ipt_ULOG.ko
arptable_filter.ko          ip_nat_sip.ko         ipt_addrtype.ko
ip_conntrack.ko             ip_nat_snmp_basic.ko  ipt_ah.ko
ip_conntrack_amanda.ko      ip_nat_tftp.ko        ipt_connlimit.ko
ip_conntrack_ftp.ko         ip_queue.ko           ipt_dscp.ko
ip_conntrack_h323.ko        ip_tables.ko          ipt_ecn.ko
ip_conntrack_irc.ko         ipt_CLUSTERIP.ko      ipt_hashlimit.ko
ip_conntrack_netbios_ns.ko  ipt_DSCP.ko           ipt_iprange.ko
ip_conntrack_netlink.ko     ipt_ECN.ko            ipt_owner.ko
ip_conntrack_pptp.ko        ipt_LOG.ko            ipt_recent.ko
ip_conntrack_proto_sctp.ko  ipt_MASQUERADE.ko     ipt_tos.ko
ip_conntrack_sip.ko         ipt_NETMAP.ko         ipt_ttl.ko
ip_conntrack_tftp.ko        ipt_REDIRECT.ko       iptable_filter.ko
ip_nat.ko                   ipt_REJECT.ko         iptable_mangle.ko
ip_nat_amanda.ko            ipt_SAME.ko           iptable_nat.ko
ip_nat_ftp.ko               ipt_TCPMSS.ko         iptable_raw.ko
ip_nat_h323.ko              ipt_TOS.ko


7. 모듈 실행 및 connlimit 옵션 활용

[root@localhost 2.6.18-92.1.10.el5-i686]# modprobe ipt_connlimit
[root@localhost 2.6.18-92.1.10.el5-i686]# lsmod |grep ip
ipt_connlimit           7680  0
ip_conntrack_ftp       11697  0
ip_conntrack_netbios_ns     6977  0
ipt_REJECT              9537  1
ip_conntrack           53025  4 ipt_connlimit,ip_conntrack_ftp,ip_conntrack_netbios_ns,xt_state
nfnetlink              10713  1 ip_conntrack
iptable_filter          7105  1
ip_tables              17029  1 iptable_filter
x_tables               17349  5 ipt_connlimit,ipt_REJECT,xt_state,xt_tcpudp,ip_tables
dm_multipath           22089  0
dm_mod                 61661  2 dm_mirror,dm_multipath
ipv6                  258145  16
xfrm_nalgo             13765  1 ipv6
ipw2200               137641  0
ieee80211              33289  1 ipw2200


[root@localhost 2.6.18-92.1.10.el5-i686]# iptables -A INPUT -p tcp --dport 80 --syn -m connlimit --connlimit-above 10 -j DROP
[root@localhost 2.6.18-92.1.10.el5-i686]# /etc/init.d/iptables save
[root@localhost 2.6.18-92.1.10.el5-i686]# cat /etc/sysconfig/iptables

# Firewall configuration written by system-config-securitylevel
# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
-A RH-Firewall-1-INPUT -i eth0 -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT
-A RH-Firewall-1-INPUT -p 50 -j ACCEPT
-A RH-Firewall-1-INPUT -p 51 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp --dport 5353 -d 224.0.0.251 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

-A INPUT -p tcp --dport 80 --syn -m connlimit --connlimit-above 10 -j DROP

-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 25 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT


[root@localhost 2.6.18-92.1.10.el5-i686]# /etc/init.d/iptables stop
방화벽 규칙을 삭제하는 중:                                 [  OK  ]
chains를 ACCEPT 규칙으로 설정함: filter                    [  OK  ]
iptables 모듈을 제거하는 중:                               [  OK  ]

[root@localhost 2.6.18-92.1.10.el5-i686]# /etc/init.d/iptables start
iptables 방화벽 규칙들을 적용하는 중:                      [  OK  ]
추가 iptables 모듈을 읽어오는 중: ip_conntrack_netbios_ns i[  OK  ]ack_ftp


[root@localhost 2.6.18-92.1.10.el5-i686]# lsmod | grep ip
ip_conntrack_ftp       11697  0
ip_conntrack_netbios_ns     6977  0
ipt_connlimit           7680  1
ip_conntrack           53025  4 ip_conntrack_ftp,ip_conntrack_netbios_ns,xt_state,ipt_connlimit
nfnetlink              10713  1 ip_conntrack
iptable_filter          7105  1
ip_tables              17029  1 iptable_filter
ipt_REJECT              9537  1
x_tables               17349  5 xt_state,ipt_connlimit,ip_tables,ipt_REJECT,xt_tcpudp
dm_multipath           22089  0
dm_mod                 61661  2 dm_mirror,dm_multipath
ipv6                  258145  16
xfrm_nalgo             13765  1 ipv6
ipw2200               137641  0
ieee80211              33289  1 ipw2200

[root@localhost 2.6.18-92.1.10.el5-i686]# iptables -L

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
RH-Firewall-1-INPUT  all  --  anywhere             anywhere
DROP       tcp  --  anywhere             anywhere            tcp dpt:http flags:FIN,SYN,RST,ACK/SYN #conn/32 > 10

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
RH-Firewall-1-INPUT  all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain RH-Firewall-1-INPUT (2 references)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
ACCEPT     icmp --  anywhere             anywhere            icmp any
ACCEPT     esp  --  anywhere             anywhere
ACCEPT     ah   --  anywhere             anywhere
ACCEPT     udp  --  anywhere             224.0.0.251         udp dpt:mdns
ACCEPT     udp  --  anywhere             anywhere            udp dpt:ipp
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ipp
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:smtp
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:http
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ftp
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:https
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited

3. 서버 증설
실무에서 가장 효과를 많이 보고 있다.

동일한 웹서버를 한개더 셋팅한 다음 DNS에서 분산처리해 준다.
SYN-Flooding 공격의 경우 처음 접속을 맺은 ip에만 공격을 한다.

1번 서버에 syncookies 기능 활용을 활용하여 아무리 많은 SYN-Flooding공격이 와도 서비스가 
중지되지 않게 설정해 놓고 DNS에 의해 분산처리를 하면 최소한 서비스가 중지 되는것을 막을 수 있다.