Linux Iptables Limit the number of incoming tcp connection / syn-flood attacks

by on June 26, 2005 · 17 comments· LAST UPDATED October 14, 2007

in , ,

A SYN flood is a form of denial-of-service attack in which an attacker sends a succession of SYN requests to a target's system. This is a well known type of attack and is generally not effective against modern networks. It works if a server allocates resources after receiving a SYN, but before it has received the ACK.

if Half-open connections bind resources on the server, it may be possible to take up all these resources by flooding the server with SYN messages. Syn flood is common attack and it can be block with following iptables rules:

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

All incoming connection are allowed till limit is reached:

  • --limit 1/s: Maximum average matching rate in seconds
  • --limit-burst 3: Maximum initial number of packets to match

Open our iptables script, add the rules as follows:

# Limit the number of incoming tcp connections
# Interface 0 incoming syn-flood protection
iptables -N syn_flood
iptables -A INPUT -p tcp --syn -j syn_flood
iptables -A syn_flood -m limit --limit 1/s --limit-burst 3 -j RETURN
iptables -A syn_flood -j DROP
#Limiting the incoming icmp ping request:
iptables -A INPUT -p icmp -m limit --limit  1/s --limit-burst 1 -j ACCEPT
iptables -A INPUT -p icmp -m limit --limit 1/s --limit-burst 1 -j LOG --log-prefix PING-DROP:
iptables -A INPUT -p icmp -j DROP
iptables -A OUTPUT -p icmp -j ACCEPT

First rule will accept ping connections to 1 per second, with an initial burst of 1. If this level crossed it will log the packet with PING-DROP in /var/log/message file. Third rule will drop packet if it tries to cross this limit. Fourth and final rule will allow you to use the continue established ping request of existing connection.
Where,

  • ‐‐limit rate: Maximum average matching rate: specified as a number, with an optional ‘/second’, ‘/minute’, ‘/hour’, or ‘/day’ suffix; the default is 3/hour.
  • ‐‐limit‐burst number: Maximum initial number of packets to match: this number gets recharged by one every time the limit specified above is not reached, up to this number; the default is 5.

You need to adjust the –limit-rate and –limit-burst according to your network traffic and requirements.

Let us assume that you need to limit incoming connection to ssh server (port 22) no more than 10 connections in a 10 minute:

iptables -I INPUT -p tcp -s 0/0 -d $SERVER_IP --sport 513:65535 --dport 22 -m state --state NEW,ESTABLISHED -m recent --set -j ACCEPT
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 600 --hitcount 11 -j DROP
iptables -A OUTPUT -p tcp -s $SERVER_IP -d 0/0 --sport 22 --dport 513:65535 -m state --state ESTABLISHED -j ACCEPT

See also:

More information on recent patch can be found here

TwitterFacebookGoogle+PDF versionFound an error/typo on this page? Help us!
1 John October 31, 2006 at 3:58 pm

The example for limiting the number of connections to ssh doesn’t work on RHEL AS 4. The “recent” match extension doesn’t exist. Also beware when typing in these commands. The font choice disguises the double hyphen on some of the flags like –sport and –dport for example.

2 payam May 30, 2008 at 4:14 am

Hi There,

I was trying out the –limit of iptables and i noticed that it cannot go over 1000 packets/sec for the limit (although the syntax accepts up to 10,000 packets/sec). Has anyone come across this and if so, is there a fix or a solution around this? I assume this has something to do with the way limit.c algorithm is setup… which is based on Hz and such…

thanks
Payam

3 Aljosha October 11, 2008 at 2:04 pm

I have this script running, it works fine, but after that, with that iptables rules i cannot do ssh on box.any help?
just with this options about syn flood and icmp reply

4 The Mikeness March 16, 2009 at 9:44 pm

don’t use such tight restrictions to packet rate if you’re planning on running a site that many people can access, esp. if those users are behind proxies, like people behind large corporate networks (i.e. bored employees at work).

I had a problem where I was trying to limit the amount of new connections to anywhere from 400 to 2000 per minute and it still wasn’t enough for a handful of people under some corporate networks to access the site simultaneously. I think either proxies accessing a webserver are always making NEW connections, or are considered as though they are. I tried making it also look for the SYN flag being set and I think it might have mostly fixed the problem for me.

5 The Mikeness March 16, 2009 at 9:47 pm

also, see this link regarding not using SYN when you limit based on NEW connections

http://www.linuxtopia.org/Linux_Firewall_iptables/x6193.html

apparently NEW isnt necessarily NEW, meaning you might be filtering ALL packets.

Why not simply filter on SYN flag then I guess?

6 Anoop Kumar May 20, 2009 at 12:27 pm

Hi,
I was trying to limit connection per ip but i am not able to fix this problem
When i am running following command
netstat -atnp -A inet | grep “:80″ | awk -F ” ” ‘{print $5} ‘ | awk -F “:” ‘{print $1}’ | sort | uniq -c | sort -nr | head -5
—————————-RESULT IN——————————————-
53 58.42.22.94
53 125.77.94.66
51 72.26.1.73
48 221.237.34.107
44 219.236.217.125
————————————————————————————-
Is it normal that 53 connection from a single IP?
Please help me.
What type of attack is this? and what’s it solution?
thanks in advance!

7 xer December 29, 2009 at 2:39 pm

Hello Vivek

For linux i use this commands below with iptables and it works fine, i’m ask you if you can make a same tutorial for FreeBSd with ipfw
Thank you in advance.

— for linux init commands —
sudo iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
sudo iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 8 --rttl --name SSH -j DROP

— end commands —

and for freebsd?

8 nixCraft December 29, 2009 at 3:08 pm

@xer,

For FreeBSD I recommend pf, it is much better and works like a charm. See our 20 Security tips about OpenSSH. The post got required iptables and pf info including examples.

HTH

9 fareh February 27, 2010 at 1:37 pm

and configure a maximum number of connections has my linux server?

10 Tapas Mishra October 27, 2010 at 3:45 pm

Some one above commented that after testing their firewall they could not ssh.
I would suggest add a cron job entry that would flush your IPTABLES in 10 minutes and test your IPTABLES rules that way if some thing went wrong you will be able to get back to your server after 10 minutes
After you have tested IPTABLE rules and find them correct then you can delete that cron job entry.

11 Tapas Mishra October 27, 2010 at 3:50 pm

Following is what you should add to your cron job
*/10 * * * * /sbin/iptables -F

12 vaLentin May 2, 2012 at 10:14 am

Never do that unless you set INPUT and OUTPUT policy to ACCEPT.

If the default policy is drop and you perform iptables -F you will be dead.

Better is to simply:

/etc/init.d/iptables stop

13 patel rocky February 22, 2011 at 10:10 am

Hi Vivek,

per second syn packet limit is setup per ip base or….?

suppose i have a web server which has a high traffic eCommerce sites.then can i restrict syn flood by above iptables rule…means this rule is also same for per ip..

And pls. suggest me ideal value for per ip syn packet applicable….

Regards,
Rocky

14 cobero March 19, 2011 at 1:48 pm

how to limit a udp port ?
/sbin/iptables -A INPUT -p udp –syn –dport 30033 -m connlimit –connlimit-above 2 -j REJECT
iptables v1.4.4: unknown option `–syn’
Try `iptables -h’ or ‘iptables –help’ for more information.

15 Thomas Heiss November 2, 2011 at 3:14 pm

Hi,

thanks for making your iptables FW script public.

Had found parts of flooding iptables protect script half of an century before but got this part in the Input chain completely wrong.
It just dropped any packet (without -p tcp –syn), so I had no flooding protection until now.

iptables -A INPUT …. “-P TCP –syn” -j syn_flood

You definitely made my day!

16 Vernon March 28, 2012 at 12:29 pm

Really helpful article, thanks. One query: I may be wrong in this but perhaps in the article the line

iptables -A INPUT -p icmp -m limit –limit 1/s –limit-burst 1 -j LOG –log-prefix PING-DROP:

should be:

iptables -A INPUT -p icmp -j LOG –log-prefix PING-DROP:

otherwise the log comment is triggered only before those max limits are triggered, rather than when they are exceeded.

regards
Vernon

17 Bob May 18, 2012 at 12:29 pm

Vernon – I think the LOG line uses “limit” to avoid filling the log with more than 1 line per second, otherwise attacks could cause the logging to bring the server to a crawl, or fill the disk.

Comments on this FAQ are closed. If you'd like to continue the discussion on this topic, you can do so at our forum.

Tagged as: , , , , , , , , , , ,

Previous post:

Next post: