[IT 알아보기]/IT 소식

[그린IDC]리눅스 시스템의 소프트레벨 커널 튜닝

이호스트ICT 2011. 5. 17. 14:27

###############################################################################

  리눅스 시스템의 소프트레벨 커널 튜닝
  ------------------------------------

  리눅스에서 syn flooding 등 각종 공격에 대응하기 위하여 시스템의 kernel 튜닝을
  하는 것이 좋다.
  다음의 기능이 작동하도록 커널 튜닝을 하여라.

  * ping 요청에 반응하지 않도록 설정한다.
  * 소스 라우팅을 차단한다.
  * synflooding 에 대응하기 위해 syncookie를 설정한다.
  * ICMP Redirect를 차단한다.
  * 스푸핑, 소스 라우팅 및 리다이렉트된 패킷은 로그에 남긴다.
  * 패킷 포워딩을 차단한다.

################################################################################
---]]]
syncookies 기능을 켠다

Syncookies ("신쿠키"라고 발음한다)는 "Three-way handshake"진행과정을 다소 변경 하는 것으로 Alex Yuriev와 Avi Freedman에 의해 제안되었는데, TCP 헤더의 특정한 부분을 뽑아내어 암호화 알고리즘을 이용하는 방식으로 Three-way Handshake가 성공적으로 이루어지지 않으면 더 이상 소스 경로를 거슬러 올라가지 않는다. 따라서 적절한 연경 요청에 대해서만 연결을 맺기 위해 리소스를 소비하게 되는 것이다.

syncookies 기능은 TCP_Syn_Flooding 공격을 차단하기 위한 가장 확실한 방법으로 이 기능을 이용하려면 일단 커널 컴파일 옵션에서 CONFIF_SYN_COOKIES이 Y로 선택되어 있어야 한다. 자신의 커널 옵션에 이 기능이 설정되어 있는지 /usr/src/linux 디렉토리로 이동 후 make menuconfig 후 다음과 같이 확인하면 된다.

Networking options ---> [*] IP: TCP syncookies support (disabled per default)

만 약 설정이 되어 있지 않다면 선택 후 커널 컴파일을 다시 하여야 하지만 대부분 배포본은 기본적으로 이 옵션이 선택되어 있으므로 걱정할 필요는 없다. 그러나 위와 같이 커널 옵션에 설정되어 있다 하더라도 실제 syncookies 적용은 꺼져 있으므로 이 값을 다음과 같은 방법으로 활성화해야 한다.

[root@control src]# sysctl -a | grep syncookienet.ipv4.tcp_syncookies = 0

0으로 설정되어 있으므로 현재 syncookies는 적용되지 않는다. 따라서 다음과 같이 1을 설정하여 syncookies 기능을 활성화도록 한다.

[root@control src]# sysctl -w net.ipv4.tcp_syncookies=1

syncookies 는 백로그큐가 가득 찼을 경우에도 정상적인 접속요구를 계속 받아들일수 있도록 해주므로 SYN_Flooding 공격에 대비한 가장 효과적인 방법중 하나다. 만약 공격을 당해 syncookies가 작동할 때에는 /var/log/message 파일에 아래와 같이 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로 네트워크를 재설정해 보거나 리부트해야 한다.

----------------------------------------------------------------------
기타 시스템의 네트워크 설정을 최적화한다

다음 설정은 비단 TCP Syn_Flooding 공격뿐만 아니라 다른 여타 DoS공격에도 효과적으로 방어하므로 적절히 설정할 것을 권장한다.

sysctl -w net.ipv4.icmp_destunereach_rate=1
# 1/100초 동안 받아들일 수 있는 "dest unreach (type 3) icmp"의 개수

sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1
# Broadcast로부터 오는 핑을 차단함(Smurt 공격을 차단함).

sysctl -w net.ipv4.icmp_echoreply_rate=1
# 1/100초에 반응하는 핑의 최대 숫자

sysctl -w net.ipv4.icmp_echo_ignore_all=1
# 모든 핑을 차단함

sysctl -w net.ipv4.icmp_ignore_bogus_error_responses=1
# IP 나 TCP 헤더가 깨진 bad icmp packet을 무시한다.

sysctl -w net.ipv4.icmp_paramprob_rate=1
# 1/100 초에 받아들이는 param probe packet의 수

sysctl -w net.ipv4.icmp_timeexceed_rate=1
# 1/100 초에 받아들이는 timeexceed 패킷의 수(traceroute와 관련)

sysctl -w net.ipv4.igmp_max_memberships=1
# 1/100초에 받아들이는 igmp "memberships"의 수

sysctl -w net.ipv4.ip_default_ttl=64
# 매우 복잡한 사이트에서는 이 값을 늘리는 것도 가능하지만 64로 두는
  것이 적당하며 더 늘렸을 경우에는 큰 문제가 발생할 수도 있다.

sysctl -w net.ipv4.ip_forward=0
# 게이트웨이 서버가 아닌 이상 패킷을 포워딩 할 필요는 없다.

sysctl -w net.ipv4.ipfrag_time=15
# fragmented packet이 메모리에 존재하는 시간을 15초로 설정한다.

sysctl -w net.ipv4.tcp_syn_retries=3
# 일정한 시간과 IP별로 보내고 받는 SYN 재시도 횟수를 3회로 제한한다.
  이 옵션은 스푸핑된(위조된) 주소로 오는 SYN 연결의 양을 줄여준다.
  기본 값은 5이며 255를 넘지 않아야 한다.

sysctl -w net.ipv4.tcp_retries1=3
# 무언가 문제가 있을 때 연결을 위해 재시도 할 횟수,
  최소 값과 기본 값은 3이다.

sysctl -w net.ipv4.tpc_retries2=7
# TCP 연결을 끊기 전에 재시도할 횟수.

sysctl -w net.ipv4.conf.eth0.rp_filter=2
sysctl -w net.ipv4.conf.lo.rp_filter=2
sysctl -w net.ipv4.conf.default.rp_filter=2
sysctl -w net.ipv4.conf.all.rp_filter=2
# 이 설정은 자신의 네트워크가 스푸핑된 공격지의 소스로 쓰이는 것을
  차단한다. 모든 인터페이스에서 들어오는 패킷에 대해 reply를 하여
  들어오는 인터페이스로 나가지 못하는 패킷을 거부한다.

sysctl -w net.ipv4.conf.eth0.accept_redirect=0
sysctl -w net.ipv4.conf.lo.accept_redirect=0
sysctl -w net.ipv4.conf.default.accept_redirect=0
sysctl -w net.ipv4.conf.all.accept_redirect=0
# icmp redirects를 허용하지 않는다.
  만약 ICMP Redirect를 허용할 경우에는 공격자가 임의의 라우팅 테이블을
  변경할 수 있게 되어 자신이 의도하지 않는 경로, 즉 공격자가 의도한
  경로로 트래픽이 전달될 수 있는 위험이 있다.

sysctl -w net.ipv4.conf.eth0.accept_source_route=0
sysctl -w net.ipv4.conf.lo.accept_source_route=0
sysctl -w net.ipv4.conf.default.accept_source_route=0
sysctl -w net.ipv4.conf.all.accept_source_route=0
# 스푸핑을 막기 위해 source route 패킷을 허용하지 않는다.
  소스 라우팅을 허용할 경우 악의적인 공격자가 IP 소스 라우팅을
  사용해서 목적지의 경로를 지정할 수도 있고, 원래 위치로 돌아오는
  경로도 지정할 수 있다. 이러한 소스 라우팅이 가능한 것을 이용해 공격
  자가 마치 신뢰받는 호스트나 클라이언트인 것처럼 위장할수 있는것이다.
sysctl -w net.ipv4.conf.eth0.bootp_relay=0
sysctl -w net.ipv4.conf.lo.bootp_relay=0
sysctl -w net.ipv4.conf.default.bootp_relay=0
sysctl -w net.ipv4.conf.all.bootp_relay=0
# bootp 패킷을 허용하지 않는다.

sysctl -w net.ipv4.conf.eth0.log_martians=0
sysctl -w net.ipv4.conf.lo.log_martians=0
sysctl -w net.ipv4.conf.default.log_martians=0
sysctl -w net.ipv4.conf.all.log_martians=0
# 스푸핑된 패킷이나 소스라우팅, Redirect 패킷에 대해 로그파일에 정보를 남긴다.

sysctl -w net.ipv4.conf.eth0.secure_redirects=0
sysctl -w net.ipv4.conf.lo.secure_redirects=0
sysctl -w net.ipv4.conf.default.secure_redirects=0
sysctl -w net.ipv4.conf.all.secure_redirects=0
# 게이트웨이로부터의 redirect를 허용하지 않음으로써 스푸핑을 막기 위해 설정한다.

sysctl -w net.ipv4.conf.eth0.send_redirects=0
sysctl -w net.ipv4.conf.lo.send_redirects=0
sysctl -w net.ipv4.conf.default.send_redirects=0
sysctl -w net.ipv4.conf.all.send_redirects=0
# icmp redirects를 보내지 않는다.

sysctl -w net.ipv4.conf.eth0.proxy_arp=0
sysctl -w net.ipv4.conf.lo.proxy_arp=0
sysctl -w net.ipv4.conf.default.proxy_arp=0
sysctl -w net.ipv4.conf.all.proxy_arp=0
# proxy arp를 설정하지 않는다. 이 값이 1로 설정되었을 경우
  proxy_arp가 설정된 인터페이스에 대해 arp 질의가 들어왔을 때
  모든 인터페이스가 반응하게 된다.

sysctl -w net.ipv4.tcp_keealive_time=30
# 이미 프로세스가 종료되어 불필요하게 남아 있는 연결을 끊는 시간을 줄이도록 한다.

sysctl -w net.ipv4.tcp_fin_timeout=30
# 연결을 종료시 소요되는 시간을 줄여준다(기본 설정값: 60).

sysctl -w net.ipv4.tcp_tw_buckets=720000
# 동시에 유지 가능한 timewait 소켓의 수이다. 만약 지정된 숫자를 초과하였을 경우에는 timewait 소켓이 없어지며 경고 메시지가 출력된다. 이 제한은 단순한 DoS 공격을 차단하기 위해 존재하는데, 임의로 이 값을 줄여서는 안되며 메모리가 충분하다면 적절하게 늘려주는 것이 좋은데, 64M 마다 180000으로 설정하면 된다. 따라서 256M일 경우에는 256/4=4 4*180000=720000

sysctl -w net.ipv4.tcp_keepalive_probes=2
sysctl -w net.ipv4.tcp_max_ka_probes=100
# 간단한 DoS 공격을 막아준다.

위 의 모든 설정은 재부팅 후에 원래의 값으로 다시 초기화되므로 /etc/rc.d/rc.local 에 두어 부팅시마다 실행하도록 하여야 한다. 그리고 리눅스의 버전이 낮아 sysctl 명령어가 없는 경우에는 echo 0 or 1 > /proc/sys/net/*와 같이 직접 /proc 이하의 값을 직접 설정해 주어도 된다. echo 명령어 역시 재부팅되면 초기화되므로 /etc/rc.d/rc.local 에 설정해 두어야 재부팅후에도 적용이 된다. 아울러 레드헷 6.2 이상일 경우에는 /etc/sysctl.conf 파일에 net.ipv4.tcp_syncookies=1과 같이 설정한 후 네트워크를 재시작하는 방법도 있다.


[[[---G
net.ipv4.conf.all.rp_filter=1
net.ipv4.ip_always_defrag = 0
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.tcp_max_syn_backlog=1280
net.ipv4.icmp_echo_ignore_all=1
net.ipv4.icmp_echo_ignore_broadcasts=1
net.ipv4.conf.all.accept_source_route=0
net.ipv4.tcp_syncookies=1
net.ipv4.conf.all.accept_redirect=0
net.ipv4.conf.all.accept_source_route=0
net.ipv4.conf.all.secure_redirects=0
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.all.log_martians=1
net.ipv4.ip_forward=0