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

Posted on in Categories Howto, Iptables, Linux, RedHat/Fedora Linux, Security, Suse Linux last updated June 26, 2005

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.

  • ‐‐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

19 comment

  1. 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. 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…


  3. 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. 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. 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——————————————-
    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!

  6. 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?

  7. 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.

      1. 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

  8. 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….


  9. 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.

  10. 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!

    1. 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.


  11. 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.

  12. Hi,

    What i cannot find anywhere is how to limit the nr of simultaneous SSH connections to my ubuntu to just 1 connection. If a launch a second ssh from any client machine to the ubuntu it should refuse because there is already 1 connected.
    How do i do this?

    Thanks for your help, love your site ! 😉

Leave a Comment