Sunday, August 2, 2009

DDOS protection using iptables (recent module)

This article related to iptable recent module. which can be used to defend against the DDOS attack. This setup tested in bridged mode.
Recent working with DDOS mitigation for one of the customer had give some interesting capabilities "recent module" of iptables.
One of the website came under attack with extensive sync and "GET" request from distributed zombies. we could identify around 4000 - 5000 unique hosts.
to define the attack pattern we have captured some traffic it had only sync and GET request nothing else to define the pattern. therefore I've conceptualized if the one host create more than 20 session during 100 seconds drop the packet.
iptables -I FORWARD -p tcp --dport 80 -i bridge0 -m state --state NEW -m recent --set
iptables -I FORWARD -p tcp --dport 80 -i bridge0 -m state --state NEW -m recent --update --seconds 100 --hitcount 20 -j DROP

Initially i applied these rules but no traffic reduction. When i checked the source code
static unsigned int ip_list_tot = 100;
static unsigned int ip_pkt_list_tot = 20;

(http://www.il.is.s.u-tokyo.ac.jp/lxr-xp/source/net/netfilter/xt_recent.c)
Therefore only 100 unique source ips can be in the list. this was not capable to handle more then 4000 hosts.
Therefore i've removed module and changed the default value.
iptables -F
rmmod xt_recent
modprobe ipt_recent ip_list_tot=5000 ip_pkt_list_tot=100 

reapplied the rules that filtered the massive traffic. when i'm writing this post still the attack is going on :( . But still the web sever able to handle the load :)

-- notes --
following script as cron with the combination of XT_RECENT can help a bit. But be aware this may block the normal user .

#!/bin/bash
mv /home/gobi/new_ips.txt /home/gobi/old_ips.txt
awk '{ if ($7 > 100) print $1 }' /proc/net/xt_recent/DEFAULT | sort > /home/gobi/new_ips.txt
sort /home/gobi/new_ips.txt /home/gobi/old_ips.txt | uniq -u | awk -F '=' '{print $2}' > /home/gobi/ips
sh /home/gobi/add_iptables.sh

---add_iptables.sh
#!/bin/bash
for WORD in `cat /home/gobi/ips`
do
iptables -I FORWARD -p tcp --dport 80 -s $WORD -i bridge1 -j DROP
done

1 comment:

Anonymous said...

Thanks for sharing your work. I was working on xt_recent solution to an unintentional denial of service that some large entities were imposing on some web servers I maintain.

I wanted to rate limit abusers, that were using various automation tech, while not punishing human users that would submit packets much more slowly.

Your work showed that I was on the right track, and gave me additional ideas.