# ngrep -qi port 80 > cap.txt 을 실행하면
공격 분석 시 만약 특정 IP에서 공격한다면 간단히 해당 IP를 차단하면 되겠지만, 공격 IP가 많은 경우 일일이 확인해서 차단하는 것이 쉽지 않을 것이다.
이런 경우에는 (그림 3)와 같이 iptables를 활용한 브리지 파이어월을 이용해 적절한 정책을 설정하면 어느 정도의 효과를 기대할 수 있을 것이다. 물론 각종 DOS 방지 관련 모듈을 이용해 차단할 수도 있겠지만, 일단 공격이 웹 서버까지 도달하면 공격이 성공할 가능성이 높으므로 애플리케이션 수준에 이르기 전에 커널 레벨에서 차단해야 대응 효과를 볼 수 있을 것이다.
다음은 공격을 받을 때 사전에 준비된 브리지 파이어월을 활용하는 예다. 공격을 받는 서버가 윈도우나 리눅스 등 운영제체와는 관계없지만, 만약 리눅스 서버가 공격을 당한다면 해당 서버에서 직접 iptables를 실행해 차단해도 된다.
한 IP당 동시 접속량 제한과 자동차단
많은 IP에서 비정상적인 다량의 접속을 시도하므로 한 IP에서의 접속량을 제한하고, 이후에 접속량이 과다한 해당 IP를 자동차단하도록 할 수 있다.
# iptables -A FORWARD -m recent --name badguy --rcheck --seconds 300 -j DROP
# iptables -A FORWARD -p tcp --syn --dport 80 -m connlimit --connlimit-above 30 -m recent --name badguy --set -j DROP
# iptables -A FORWARD -p tcp --syn --dport 80 -m connlimit --connlimit-above 30 -j DROP
이렇게 3가지 규칙만 실행하면 되늗데, 단순히 3번째 규칙만 실행하면, 한 IP에서의 동시접속이 30회만 허용되고 그 이상 접속을 하지 못하지만, 앞의 두 가지 규칙과 함께 사용하면 동시접속이 30회 이상 초과하는 IP를 동적으로 300초(5분)동안 차단한다. 동시접속수 제한이나 차단시간은 각자의 환경에 따라 적절히 설정하면 된다.
이때 과다접속으로 차단된 IP에 대한 정보는 다음과 같이 실시간으로 확인할 수 있다.
# cat /proc/net/ipt_recent/badguy
src=100.123.65.15 ttl: 63 last_seen: 1174481 oldest_pkt: 2 last_pkts: 1174481, 1174481
국가별 차단(한국만 접속 가능)
좀비들은 국가에 관계없이 특정 바이러스에 감염된 PC나 서버를 이용하므로 공격 시 해외에서의 접속이 많을 수 있다. 정상적인 경우 대부분 국내에서의 접속이 대부분이므로 공격을 당할 경우 해외에서의 접속을 차단한다면 일정 정도의 효과를 기대할 수 있다.
# iptables -A FORWARD -p tcp --dport 80 -m geoip ! --src-cc KR -j DROP
이 규칙은 접속국가가 KR, 즉 한국이 아닌 것은 차단하겠다는 의미이다. 만약 “-p tcp --dport 80”을 삭제하면 웹 뿐만 아니라 모든 해외에서의 접속을 차단하게 된다.
iptables를 이용한 국가별 차단 방법에 대해서는 예전에 살펴본 바가 있는데, 여기에서는 국가DB를 최신 정보로 업데이트하는 방법에 대해 살펴보도록 하자.
먼저 csv 파일을 db 파일로 변환해 주는 프로그램을 다운로드하여 설치하도록 하자.
# wget http://people.netfilter.org/peejix/geoip/tools/csv2bin-20041103.tar.gz
# tar zxfp csv2bin-20041103.tar.gz
# cd csv2bin
이후 국가별 IP DB 파일을 다운로드해 압축해제한다.
# wget http://www.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip
# unzip GeoIPCountryCSV.zip
이제 다음과 같이 실행하면 현재 디렉토리에 geoipdb.bin과 geoipdb.idx 파일이 생성되는데, 이 파일을 /var/geoip 디렉토리로 옮기기만 하면 된다.
# ./csv2bin GeoIPCountryWhois.csv
문자열 차단 (도메인이 아닌 IP 등으로 직접 접속시)
일부 공격의 경우 공격의 효과를 높이기 위해 도메인이 아닌 IP로 접속하는 경우가 있다. 정상적인 경우 도메인으로 접속하므로 IP로 접속하는 시도를 차단할 경우 일정 정도 효과를 기대할 수 있다. 다음은 http 접속시 http://1.1.1.1/과 같이 공격하는 것을 차단할 수 있다.
# iptables -A FORWARD -p tcp -m string --string "Host: 1.1.1.1" --algo kmp -j DROP
네트워크 수준의 공격의 경우
서버 수준의 공격이라면 피해가 크지 않으므로 그나마 다행이겠지만, 네트워크에 장애를 유발할 수 있는 대규모의 공격이라면 상황이 달라진다. 서버의 문제가 아니라 스위치 등 네트워크 장비의 장애가 유발되며 설사 장애가 나지 않더라도 회선 대역폭이 가득 차 서비스 자체가 불가능해지는 것이다.
네트워크를 운영하는 기관이나 조직에서는 기본적인 네트워크 모니터링을 하고 있을 것이다. 따라서 장애 발생 시 가장 먼저 취해야 할 조치는 공격의 유형을 파악하는 것이다.
여 기에서 의미하는 ‘공격의 유형’이란 대용량 트래픽을 유발하는 소스 IP와 공격 대상 목적지 IP 또는 도메인, 그리고 이때 사용되는 프로토콜(tcp나 udp, icmp 등) 과 80 등 공격에 사용되는 포트 등이다. 이런 정보를 가장 손쉽게 그리고 효과적으로 파악할 수 있는 방법은 바로 netflow를 이용한 flowscan을 사용하는 것이다. 대부분 많이 사용하는 기존의 mrtg만으로는 이들 정보를 파악하는 데 한계가 있으므로 반드시 flowscan 등을 활용해야 한다.
공격과 관련된 소스 IP 및 목적지 IP가 확인됐다면, 해당 IP를 차단하는 것이 가장 손쉬운 방법이다. 만약 공격의 소스 IP가 1.1.1.1 이고 대상 IP가 2.2.2.2라면 다음과 같이 블랙홀 라우팅을 이용해 차단할 수 있다.
블랙홀 라우팅은 Null0 라우팅 또는 Null0 필터링이라고도 하는데, 라우터 본연의 기능인 라우팅을 이용하는 것이므로 ACL보다는 장비의 자원을 적게 소모하면서 쉽게 설정이 가능하다. 이는 마치 /dev/null처럼 특정 IP 또는 IP 대역을 가상의 쓰레기 인터페이스로 강제로 보냄으로써 접속을 차단하는 기술이다.
ROUTER# conf t
ROUTER(config)# ip route 1.1.1.1 255.255.255.255 Null0
이 경우 공격지 IP인 1.1.1.1을 목적지로 한 패킷을 차단하는 예를 보여주고 있다. 라우팅은 소스를 제어하는 것이 아니라 목적지 IP를 제어하는 것이므로 일단 1.1.1.1을 소스로 한 트래픽은 라우터를 통과하며, 단지 공격에 대한 응답 트래픽이 차단되는 것이다.
ROUTER# conf t
ROUTER(config)# ip route 2.2.2.2 255.255.255.255 Null0
이 방법은 공격의 대상이 되는 사이트를 차단하는 예다. 이는 공격이 발생했을 때 네트워크 장애에 대비해 공격의 피해를 최소화하기 위해 임시방편으로 공격의 대상이 되는 특정 IP를 차단하는 것이다. 이 경우 공격 대상지인 2.2.2.2로 향하는 공격 트래픽이 역시 Null0 인터페이스로 보내져 사라지게 된다.
다음으로 취할 수 있는 방법은 CAR(Commit Access Rate)라고 불리는 것으로 대역폭 제한을 이용한 일종의 QoS 설정 방법인데, 앞서 살펴본 iptables의 connlimit와 같이 일정 정도의 트래픽만 허용하고 나머지는 차단하는 기술이다. 사용하는 방법은 ACL의 설정 방법과 매우 유사하다. 먼저 IP나 프로토콜 또는 포트 등 제한 설정을 적용할 트래픽을 정의한 후 해당 인터페이스에 적용하면 된다. 설정 문법은 다음과 같다.
rate-limit {input | output} bps burst-normal burst-max conform-action action exceed-action action
이때 적용되는 각 옵션의 의미는 다음과 같다.
burst-normal : 초과 허용 대역폭(bytes)
burst-max : 초과 정책을 적용할 대역폭 한계(bytes)
conform-action : 한계를 넘지 않을 때 취할 행동. 주로 단순 패킷 전달(transmit)
exceed-action : 초과시 취할 정책. 이를테면 패킷 드롭
이제, 실제로 규칙을 설정해 보도록 하자.
int GigabitEthernet 3/0
rate-limit input access-group 150 2000000 8000 8000 conform-action transmit exceed-action drop
rate-limit input access-group 160 2000000 8000 8000 conform-action transmit exceed-action drop
access-list 150 permit ip any host 2.2.2.2
access-list 160 permit udp any host 3.3.3.3
먼저, 첫 번째 rate-limit의 경우 access-list 150에 대한 규칙이므로, acl 150번을 보면 목적지 IP가 2.2.2.2인 트래픽을 뜻하는 것을 알 수 있다. 따라서 첫 번째 rate-limit 정책은 2.2.2.2로 향하는 모든 트래픽에 대해 트래픽을 2M로 제한하며, 만약 2M를 초과할 경우에는 차단한다는 것을 알 수 있다. 이는 2.2.2.2로 대량의 트래픽을 유발하는 형태의 공격에 유용할 것이다. 만약 access-list를 다음과 같이 설정한다면 2.2.2.2를 소스로 한 트래픽을 2M로 제한하는 것이므로 2.2.2.2가 공격을 하는 소스 IP일 경우에 유용할 것이다.
access-list 150 permit ip host 2.2.2.2 any
두 번째 규칙은 access-list 160번에 대한 룰이므로 목적지 IP가 3.3.3.3으로 향하는 트래픽 중 tcp나 icmp 등은 제한하지 않고 udp에 대해서만 2M로 제한하는 것을 알 수 있다. 이는 대량의 UDP 트래픽을 유발하는 형태의 공격인 경우에 유용할 것이다.
그러나 만약 상위 네트워크와 연동된 회선의 대역폭이 1Gbps인데, 정상적인 트래픽과 함께 1Gbps 이상의 공격 트래픽이 들어온다면 앞서 살펴본 방법은 아무 소용이 없을 것이다.
이 경우에는 어쩔 수 없이 상위(upstream) ISP 또는 IDC에 협조를 요청해 공격의 소스 또는 대상 IP에 대해 원천적으로 차단해야 할 것이다. 여러 문서에서도 언급하고 있는 것처럼 DDoS공격은 근본적으로 차단할 수 있는 묘책은 없지만, 상위 네트워크 관리자와 협조하여 공격의 양상에 따라 적절히 대처한다면 피해를 최소화할 수 있을 것이다.