Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I was wondering if I could prevent small (D)DoS attacks with a simple IP tables rule?

By small I mean that they are flooding my web server with about 400+ requests from one or two IP addresses. I can drop the IP addresses after I notice that they have started hitting my web server, but it normally takes a few minutes for IP tables to kick in against that IP, and start dropping it completely so that it doesn't impact that web server.

I drop the IP with the following command:

iptables -I INPUT -s "IP HERE" -j DROP

And then obviously save it:

/etc/init.d/iptables save

I normally find out the attacking IP address(es) with the following command:

netstat -plan|grep :80|awk '{print $5}'|cut -d: -f 1|sort|uniq -c|sort -n

The issue with doing it that way is that I have to be there, and it requires me to act after the fact. Is there an IP tables rule that I could use to drop an IP address right after it hits 150 connections? That way I don't have to worry about it overwhelming the web server, and I also don't have to be there at the time to block it.

By the way, I'm using Apache on CentOS if that matters.

Thank you for your time.

share|improve this question
1  
1  
    
That netstat command does not necessarily list "attacking" IP addresses. The main problem is that grep :80 doesn't care whether you are connecting to someone or if they are connecting to you. The second problem is that it doesn't care what state the connections are in. Try this: netstat -plan | awk '$4 ~ /:80/ {print $6,$5}' | cut -d: -f1,3 | sort | uniq -c | sort -n Also, verify that the IP addresses are malicious before you block them. Companies like Websense and CloudFlare can funnel a lot of users through a single IP address. –  Ladadadada Dec 31 '11 at 13:15
add comment

2 Answers

up vote 8 down vote accepted

For something that offers flexibility, look into the recent (and limit) module(s). Recent will keep a track of the number of connections made by an IP, over a given time frame, and can be used to trigger a specific rule. The recent module is (relatively) CPU heavy - but when compared to loading a dynamic page, can be quite acceptable.

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p tcp -m multiport --dports 80,443 -m recent --update --seconds 3600 --name BANNED --rsource -j DROP
-A INPUT -p tcp -m multiport --dports 80,443 -m state --state NEW -j ATTK_CHECK

-A ATTACKED -m limit --limit 5/min -j LOG --log-prefix "IPTABLES (Rule ATTACKED): " --log-level 7
-A ATTACKED -m recent --set --name BANNED --rsource -j DROP
-A ATTK_CHECK -m recent --set --name ATTK –-rsource
-A ATTK_CHECK -m recent --update --seconds 600 --hitcount 150 --name ATTK --rsource -j ATTACKED
-A ATTK_CHECK -m recent --update --seconds 60 --hitcount 50 --name ATTK --rsource -j ATTACKED
-A ATTK_CHECK -j ACCEPT

Essentially, the above amounts to:

  • Accept connections that have been established already (i.e. they have passed our rules)
  • Drop all connections on ports 80 and 443 (SSL) from banned IPs - if they keep trying to connect, extend the time - wait an hour (without any connection attempts) before unblocking them.
  • Check new connections against our rules:
    • Consider more than 150 connections in 10 minutes an attack
    • Consider more than 50 connections in 1 minute an attack
    • Log the attack (but not more than 5 entries per minute - don't want to flood our logs); and block the connection

For a more detailed explanation, and a tiered version of the above, which I use, see this article

Keep in mind that ipTables will not help with network congestion at all, and is fairly ineffective against any distributed attacks - its advantage is in security and reducing the load on your server.

share|improve this answer
    
This applies to the other answer too: you additionally need to remove the blocks after some time. This attacks usually com from systems with dynamic assigned IP's. Otherwise your block tables will fill up to a limit, otoh someone else, that gets the IP newly assigned, cannot reach your site. –  ott-- Dec 31 '11 at 10:35
    
Definitely something to keep in mind - however, the implementation above actually already does this. In the example above, the address is blocked for 1 hour (3600 in line 2) as long as no further connection attempts are made (the 'update' parameter in line 2). –  cyberx86 Jan 1 '12 at 0:19
    
My answer also automatically removes the blocks that are added, @ott--. hashlimit automatically "recharges" if the threshold hasn't been exceeded over the last period. –  Sean Reifschneider Jan 1 '12 at 22:26
add comment

You can use iptables to block an abuser like this, but you have to be careful because iptables is very CPU-intensive. Every packet is checked against every rule, so adding rules can quickly cause the server to run out of cycles. I had a client once that would add a new rule every time they wanted to block someone, and then one day they had slightly higher than normal traffic and the system fell over. Tables can reduce the number of rules looked at, but you can't just throw a lot of rules at iptables.

Another alternative is to black-hole routing:

ip route add blackhold $IP_HERE
ip route flush cache

The routing table is hashed, where iptables rules have to be looked at sequentially, so you can have hundreds of thousands of routes without a problem, where thousands of iptables rules would be.

As far as your second question, you can use the hashlimit module to create an automatic blacklist for abusers. See my post about preventing a DDoS attack for more details, but the short form is:

iptables -A INPUT -p tcp --dport 80 -m hashlimit --hashlimit-upto 50/min \
    --hashlimit-burst 500 --hashlimit-mode srcip --hashlimit-name http -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j DROP
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.