# Is there a rule for iptables to limit the amount of SYN packets a /24 range of IPs can send?

How can I block entire C class IP blocks when they send too many SYN packets to my ubuntu 12.04 server?

Example of what I see during a SYN flood attack:

Each different IP only sends 1 SYN packet, so the firewall doesn't block it. But the range 192.132.209.* all together is sending a lot of SYN packets in a very small time period.

-
I've found references about hashlimit (iptables module) but I'm not sure how it works as almost all examples use per-port limits or per-ip limits, not per C class block limits. –  TheBronx Jan 12 '13 at 14:43
There's a reason for not blocking complete /24 IPv4 blocks directly, imo! You will block too many innocent users in most cases. –  gertvdijk Jan 12 '13 at 14:56
yeah, but that's better than letting the server going down (block for all). It is not a permanent block, and those ranges are usually from different countries where I do not have visitors at all. –  TheBronx Jan 12 '13 at 15:06
Then why not setting the TCP SYN limit globally? The limit itself is a temporary block, effectively. –  gertvdijk Jan 12 '13 at 15:12
globally? how can that help blocking attackers and allowing good users? –  TheBronx Jan 12 '13 at 16:34

Taking 10.0.0.0/24 as an example, something like

iptables -A INPUT -p tcp -s 10.0.0.0/24 --syn -m limit --limit 1/s --limit-burst 3 -j RETURN


should do the job and is quite self-descriptive, so that doesn't need any explanation I guess. Here's a good, easy to read article on how to prevent TCP SYN flood attacks: Linux Iptables Limit the number of incoming tcp connection / syn-flood attacks. It explains more about the options, and provides a more extensive way too (logging, separate chain, etc.).

I can't see the current state of your iptables from here, so you might want to add this at the top of the INPUT chain or integrate it properly in your current scripts.

In the comments you've mentioned you're looking for an automated way of finding these IP blocks. Well, I should just leave out the source address filter in the command (-s 10.0.0.0/8), so the limit will apply to the whole world.

-
Thanks gertvdijk but why 10.0.1.2/24? I want the firewall to detect and block /24 ranges automatically. –  TheBronx Jan 12 '13 at 14:39
@TheBronx 10.0.1.2/24 is an example! I prefer not to put hardcoded public IP ranges in an answer here for future visitors who might apply it blindly. 10.0.0.0/8 is RFC1918, so harmless. Detecting it automatically is not part of your question and shout be in a different one. And this is a question more suitable on ServerFault, I believe. –  gertvdijk Jan 12 '13 at 14:53
ok, thank you gertvdijk, I will post the question in ServerFault then. –  TheBronx Jan 12 '13 at 15:10

I've found a similar solution. Not what I wanted exactly, but very similar:

/sbin/iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 20 --connlimit-mask 24 -j REJECT --reject-with tcp-reset

Limits new tcp connections (port 80) to 20 per C class block. I've found it here:
Example: Class C Limitations

-

Class C IP Address: 192.0.0.0 to 223.255.255.255.

In this case --connlimit-mask option must be 192.0.0.0/3 in CIDR notation.

If you specify a mask of 24, it will apply to Class A and Class B too. You have to use CIDR notation to specify the Class for sure.