syn 공격 기본 방어 CentOS



출처 : http://www.ysy2080.com/uribury/1193

1. 백로그 큐를 늘려준다.
직관적으로 보았을 때 서비스 거부에 돌입하게 되는 것은 백로그큐(Backlog Queue)가 가득
차서 다른 접속 요구를 받아들이지 못하기 때문이므로 백로그 큐의 크기를 늘려주면 될 것이다. 실제로 리눅스를 포함해서 많은 운영체제들의 백로그큐값을 조사해 보면 이 값이 필요 이상으로 작게 설정되어 있어 적절히 늘려주는 것이 좋다.
현재 시스템에 설정된 백로그큐의 크기는
[root@net /root]# sysctl -a|grep syn_backlog
net.ipv4.tcp_max_syn_backlog = 128
또는
[root@net /root]# cat /proc/sys/net/ipv4/tcp_max_syn_backlog
128
로 확인가능하며 128kb 인 것을 확인할 수 있다.
일반적으로 시스템의 RAM 이 128M 일 경우에는 128 을 설정하고 그 이상일 경우에는 1024 정도로 설정해 주는 것이 좋다. 이 때 주의할 점은 이 값을 무작정 크게 설정한다고 좋은 것은 아니며 1024 이상으로 설정할 경우는 /usr/src/linux/include/net/tcp.h 소스에서 TCP_SYNQ_SIZE 변수를 수정 후 커널을 재컴파일하여야 한다. 이 변수를 설정시 TCP_SYNQ_HSIZE에 16을 곱한 값이 tcp_max_syn_backlog 보다는 작거나 같아야 하는데, 그렇지 않을 경우에는 시스템에 문제가 발생할 수 있으니 1024 보다 높은 값으로 설정하지 말기 바란다. 그리고 이 값을 너무 크게 설정하였을 경우에는 경험적으로 아래 설명할 syncookies 기능이 잘 적용되지 않는 현상이 가끔 확인되었다.
이와는 별개로 시스템의 부하가 많이 걸릴 경우에도 백로그큐를 늘려주면 일정 정도의 효과를 볼 수 있는 것으로 알려져 있다.
백로그큐의 값을 설정하는 방법은 다음과 같다.
[root@net /root]# sysctl -w net.ipv4.tcp_max_syn_backlog=1024
또는
[root@net /root]# echo 1024 > /proc/sys/net/ipv4/tcp_max_syn_backlog
로 해도 된다.
그러나 이 방법은 임시적인 대책일 뿐, 지속적으로 많은 TCP SYN Flooding 공격을 당할 때는 결국 백로크큐가 가득 차게 되므로 근본적인 해결 방안은 아니다.
2. syncookies 기능을 켠다.
Syncookies(“신쿠키” 라고 발음한다.) 는 "Three-way handshake" 진행 과정을 다소 변경하는 것으로 Alex Yuriev 와 Avi Freedman 에 의해 제안되었는데, TCP header 의 특정한 부분을 뽑아내어 암호화 알고리즘을 이용하는 방식으로 Three-way Handshake 가 성공적으로 이루어지지 않으면 더 이상 소스 경로를 거슬러 올라가지 않는다. 따라서 적절한 연결 요청에 대해서만 연결을 맺기 위해 리소스를 소비하게 되는 것이다.
syncookies 기능은 TCP_Syn_Flooding 공격을 차단하기 위한 가장 확실한 방법으로 이 기능을 이용하려면 일단 커널 컴파일 옵션에서 CONFIG_SYN_COOKIES이 Y 로 선택되어 있어야 한다.
자신의 커널 옵션에 이 기능이 설정되어 있는지 확인하려면
/usr/src/linux 디렉토리로 이동후 make menuconfig 후
Networking options --->
[*] IP: TCP syncookie support (disabled per default)
와 같이 확인하면 된다.
만약 설정이 되어 있지 않다면 선택 후 커널 컴파일을 다시 하여야 하지만 대부분 배포판은 기본적으로 이 옵션이 선택되어 있으므로 걱정할 필요는 없다.
그러나 위와 같이 커널 옵션에 설정되어 있다 하더라도 실제 syncookies 적용은 꺼져 있으므로 이 값을 다음과 같은 방법으로 활성화해야 한다.
[root@control src]# sysctl -a|grep syncookie
net.ipv4.tcp_syncookies = 0
0 으로 설정되어 있으므로 현재 syncookies는 적용되지 않는다.
따라서 아래와 같이 1을 설정하여 syncookies 기능을 활성화하도록 한다.
[root@control src]# sysctl -w net.ipv4.tcp_syncookies=1 or echo 1 > /proc/sys/net/ipv4/tcp_syncookies

syncookies는 백로그큐가 가득 찼을 경우에도 정상적인 접속 요구를 계속 받아들일 수 있도록 해 주므로 SYN_Flooding 공격에 대비한 가장 효과적인 방법중 하나이다.
만약 공격을 당해 syncookies 가 작동할 때에는 /var/log/messages 파일에 아래와 같이 SynFlooding 공격이 진행중이라는 메시지가 출력된다.
Jun 11 18:54:08 net kernel: possible SYN flooding on port 80. Sending cookies.
SYN_Flooding 공격이 지속적으로 매우 심하게 진행중일 때에는 syncookies 기능이 작동한다 하더라도 네트워크가 다운되는 현상이 가끔 확인되었다. 따라서 syncookies 기능 외에 몇 가지 설정도 함께 적용하는 것이 시스템의 안정성을 위해 권장하는 방법이다. 아울러 네트워크가 다운되었을 경우에는 /etc/rc.d/init.d/network restart 로 network 를 재설정해 보거나 reboot 를 하여야 한다.

SYN Flooding조치법
http://cafe.naver.com/dnspro.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=9651
connlimit모듈 설치 후 iptables에 설정
iptables -A INPUT -p tcp --dport 80 --syn -m connlimit --connlimit-above 10 -j DROP

1초동안 80포트에 똑같은 IP가 10번 이상의 SYN패킷이 들어오면 드랍시킨다. 즉 정상적인 요청이 아닌 웹서비스 공격으로 간주하여 요청패킷을 폐기시켜 응답하지 않도록 한다.
iptables -A INPUT -p tcp --dport 80 -m recent --update --seconds 1 --hitcount 10 --name HTTP -j DROP

DDOS공격에 대비하기 위한 캐시구성
다수의 위조된 source ip에서 syn flooding 공격이 발생할 때 아래와 같은 메세지가 나오면서 시스템이 정지되는 경우가 있음

#dmesg
kernel : dst cache overflow
kernel : dst cache overflow
kernel : dst cache overflow

리눅스에서는 각각의 소스의ip에 대해 라우팅캐시로 저장해두는데, syn flooding 공격시에는 이 갯수가 미리 지정된 값을 초과하여 접속이 되지 않는 것으로 현재 수치가 높여져 있지만 더 수치를 조정할 필요가 있습니다.

#route -Cn <-- 현재 라우팅 캐시정보

/proc/sys/net/ipv4/route/max_size = 2097152 => 인식 가능한 라우팅 개수
/proc/sys/net/ipv4/route/secret_interval = 600 => 라우팅을 캐시하는 시간 (600초 10분)
2097152/600=3495   => 초당 신규 라우팅 캐시를 3495개까지 인식 가능
따라서, 위의 경우 초당 4000개 이상의 소스ip에서 접속이 들어오면 시스템이 멈추게 됩니다.
따라서, 공격에 대비하여 아래와같이 설정하는것을 권장합니다.

##대응방법
(1) net.ipv4.route.max_size의 값을 최대한 늘리고 (예:8000000)
(2) net.ipv4.route.secret_interval의 값을 줄인다 (예10)
(3) 또는 ip route flush cache로 캐쉬를 즉시 clear시킨다.

get flooding확인
tcpdump -nn -A | grep GET

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

출처 : 마이위트(miwit.com)

가장 원초적인 리눅스 서버 보안세팅입니다..
결론부터 말하면, 이 설정으로 DDoS 공격 막을수는 없습니다..최소한의 서버 취약점이나 정보 노출을 막는데 의의가 있을 것입니다.
원래는 /etc/sysctl.conf를 하나 하나 추가해줘야 하는 내용임

#기존 sysctl.conf 백업
cp -afp /etc/sysctl.conf /etc/sysctl.conf_save
# sysctl.conf 안의 내용을 초기화
cat /dev/null > /etc/sysctl.conf

# icmp redirects를 보내지 않는다.
net.ipv4.conf.eth0.accept_redirects=0
net.ipv4.conf.lo.accept_redirects=0
net.ipv4.conf.default.accept_redirects=0
net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.eth0.send_redirects = 0
net.ipv4.conf.lo.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.send_redirects = 0
# proxy arp를 설정하지 않는다.
net.ipv4.conf.eth0.proxy_arp=0
net.ipv4.conf.lo.proxy_arp=0
net.ipv4.conf.default.proxy_arp=0
net.ipv4.conf.all.proxy_arp=0
# 게이트웨이로부터의 redirect를 허용하지 않음으로써 스푸핑을 막기 위해 설정한다.
net.ipv4.conf.eth0.secure_redirects=0
net.ipv4.conf.lo.secure_redirects=0
net.ipv4.conf.default.secure_redirects=0
net.ipv4.conf.all.secure_redirects=0
# 스푸핑을 막기 위해 source route 패킷을 허용하지 않는다.
# 소스 라우팅을 허용할 경우 악의적인 공격자가 IP 소스 라우팅을 사용해서 목적지의
# 경로를 지정할 수도 있고, 원래 위치로 돌아오는 경로도 지정할 수 있다. 이러한 소스 라우팅이
# 가능한 것을 이용해 공격자가 마치 신뢰받는 호스트나 클라이언트인 것처럼 위장할 수 있는 것이다.
net.ipv4.conf.eth0.accept_source_route=0
net.ipv4.conf.lo.accept_source_route=0
net.ipv4.conf.default.accept_source_route=0
net.ipv4.conf.all.accept_source_route=0
# Broadcast로부터 오는 핑을 차단함(Smurt 공격을 차단함).
net.ipv4.icmp_echo_ignore_broadcasts=1
# IP 나 TCP 헤더가 깨진 bad icmp packet을 무시한다.
net.ipv4.icmp_ignore_bogus_error_responses = 1
# 자신의 네트워크가 스푸핑된 공격지의 소스로 쓰이는 것을 차단한다.
# 모든 인터페이스에서 들어오는 패킷에 대해 reply를 하여 들어오는 인터페이스로 나가지 못하는 패킷을 거부한다.
net.ipv4.conf.eth0.rp_filter=2
net.ipv4.conf.lo.rp_filter=2
net.ipv4.conf.default.rp_filter=2
net.ipv4.conf.all.rp_filter=2
# bootp 패킷을 허용하지 않는다.
net.ipv4.conf.eth0.bootp_relay=0
net.ipv4.conf.lo.bootp_relay=0
net.ipv4.conf.default.bootp_relay=0
net.ipv4.conf.all.bootp_relay=0
# 스푸핑된 패킷이나 소스라우팅, Redirect 패킷에 대해 로그파일에 정보를 남긴다.
net.ipv4.conf.eth0.log_martians=1
net.ipv4.conf.lo.log_martians=1
net.ipv4.conf.default.log_martians=1
net.ipv4.conf.all.log_martians=1
# 1/100초에 받아들이는 igmp "memberships"의 수
net.ipv4.igmp_max_memberships=1
# 매우 복잡한 사이트에서는 이 값을 늘리는 것도 가능하지만 64로 두는 것이 적당하며
# 더 늘렸을 경우에는 큰 문제가 발생할 수도 있다.
net.ipv4.ip_default_ttl=64
# 게이트웨이 서버가 아닌 이상 패킷을 포워딩 할 필요는 없다.
net.ipv4.ip_forward=0
# fragmented packet이 메모리에 존재하는 시간을 15초로 설정한다.
net.ipv4.ipfrag_time=15
# SYN_Flooding 공격에 대한 대비로 백로그큐(Backlog Queue)가 가득차면 다른 접속 요구를 받아들이지 못한다.
net.ipv4.tcp_max_syn_backlog = 1024
# TCP 연결에서 Three-way Handshake가 성공적으로 이루어지지 않으면 더 이상 소스 경로를 거슬러 올라가지 않도록
# 한다.
# 따라서 적절한 연결 요청에 대해서만 연결을 맺는다.
# syncookies가 작동할 때 SYN Flooding 공격이 있으면 messages 파일에 아래와 같은 내용이 출력된다.
# possible SYN flooding on port 80. Sending cookies.
net.ipv4.tcp_syncookies = 1
# 일정한 시간과 IP별로 보내고 받는 SYN 재시도 횟수를 3회로 제한한다.
# 이 옵션은 스푸핑된(위조된) 주소로 오는 SYN 연결의 양을 줄여준다.
# 기본 값은 5(180 초에 대응)이며 255를 넘지 않아야 한다.
net.ipv4.tcp_syn_retries = 3
# passive TCP 접속시도가 재접속을 하기 위한 SYNACKs의 값을 정한다. 255 보다 높
# 게 지정할 수 없다. 기본값은 5이며, 180초에 대응이 된다.
net.ipv4.tcp_synack_retries = 3
# 무언가 문제가 있을 때 연결을 위해 재시도 할 횟수, 최소 값과 기본 값은 3이다.
net.ipv4.tcp_retries1=3
# TCP 연결을 끊기 전에 재시도할 횟수.
net.ipv4.tcp_retries2=7
# 연결을 종료시 소요되는 시간을 줄여준다(기본 설정값: 60).
net.ipv4.tcp_fin_timeout=20
# 동시에 유지 가능한 timewait 소켓의 수이다.
# 만약 지정된 숫자를 초과하였을 경우에는 timewait 소켓이 없어지며 경고 메시지가 출력된다.
# 이 제한은 단순한 DoS 공격을 차단하기 위해 존재하는데, 임의로 이 값을 줄여서는 안되며
# 메모리가 충분하다면 적절하게 늘려주는 것이 좋은데, 64M 마다 180000으로 설정하면 된다.
# 따라서 256M일 경우에는 256/4=4 4*180000=720000
# 64M -> 180000
# 128M -> 360000
# 256M -> 720000
# 512M -> 1440000
# 1G -> 2880000
# 2G -> 5760000
#net.ipv4.tcp_max_tw_buckets = 180000
#
# 연결이 끊어졌다고 판단할 때까지, 얼마나 keepalive probe 를 보낼지 결정. 기본값 9회
# 간단한 DoS 공격을 막아준다.
net.ipv4.tcp_keepalive_probes=2
# keepalive 가 활성되 되어 있을 경우, 얼마나 자주 TCP 가 keepalive 메세지를 보
# 내게 할 것인지를 설정.
net.ipv4.tcp_keepalive_time=30
# keepalive_probes 를 보낼 간격을 정함. probe 를 보낸 후, probes * intvl 의 시
# 간이 지나도록 응답이 없으면 연결이 해제된 것으로 간주하게 됨. 기본 값의 사용
# 시 11분 15초 동안 재시도를 하고 연결을 취소함. 값은 초단위
net.ipv4.tcp_keepalive_intvl = 10
# 서버 쪽에서 닫은 TCP 연결을 끊기 전에 확인하는 횟수를 정한다. 기본 값은 7 로
# RTO 50 초에서 16 분 사이에 해당한다. 웹 서버가 운영 중 이라면 이 값을 줄여서
# 소켓 등이 귀한 리소스를 소비하지 않도록 할 수도 있다.
net.ipv4.tcp_orphan_retries = 2
# SYN 패킷을 전송한 후에 로스가 발생을 하여 ACK 를 일부 받지 못했을 경우, 선택
# 적으로 (selected) 받지못한 ACK 만 받도록 요청하는 것을 허락한다. 로스가 많은
# 네트워크에서는 상당히 중요한 역할을 한다.
net.ipv4.tcp_sack = 1
#설정끝

#sysctl -p

#iptables설정
# 한 ip에서 20개 이상의  syn 요청이 올경우 차단(connlimit설정은 커널에서 모듈이 로드되어 있어야됨)
#/sbin/iptables -A INPUT -p tcp --syn -m connlimit --connlimit-above 20 -j DROP

# syn 20번연결후 초당 10회연결제한
/sbin/iptables -N syn-flood1
/sbin/iptables -A INPUT -p tcp --syn -j syn-flood1
/sbin/iptables -A syn-flood1 -m limit --limit 10/s --limit-burst 20 -j RETURN
/sbin/iptables -A syn-flood1 -j DROP

#한사용자가 열수 있는 파일 수 제한 “too many open files” 오류 예방
ulimit -n 32768

 

# IP당 count수 확인(로그참조)
cat /usr/local/apache/logs/도메인-access_log | grep "list.html"| cut -d" " -f1|sort -n |uniq -c|sort -n |tail -n 100


덧글

댓글 입력 영역