5

I need to limit access to some port per IP. Let's say 5 connections per minute - not more.

I've seen iptables recent, connlimit and limit, but all of them are not fitting exactly what I need.

Suppose you have a client trying to connect every second. In my scenario I need to allow 5 packets each minute.

recent: If some IP tries to connect every 1 second, --hitcount 5 will memorize this IP and keep it in the list until no packets comes within --second 60 time. So, it will limit the client permanently in my scenario.

limit: This one limits as I wish with --limit 5/min, but for all IPs - no way to specify this per IP.

connlimit: Limits number of simultaneous connections, not per some time.

In fact, I need a mixture of limit + recent. Who knows how to do it?

2
  • Are you trying to limit a specific application, say Apache or Postfix, or do you want something for a generic TCP application? Commented Jun 20, 2014 at 18:30
  • I need to limit number of connections to SSH server
    – PoltoS
    Commented Jun 21, 2014 at 22:13

3 Answers 3

2

Finally managed to do it with recent:

iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW \
         -m recent --rcheck --seconds 60 --hitcount 5 --name ssh --rsource \
         -j REJECT --reject-with icmp-port-unreachable

iptables -A INPUT -p tcp -m tcp --dport 22 -m state --state NEW \
         -m recent --set --name ssh --rsource

--update will restart the timer again on each receiving packet, but --rcheck will only check it. After 60 seconds the structure is deleted and a new timer is started again.

This is how I got it (I was not looking into sources - too lazy)

1

Use the hashlimit match extension:

port=9999
iptables -A INPUT -p tcp --dport $port        \
      -m conntrack --ctstate NEW              \
      -m hashlimit --hashlimit-name SuperUser \
                   --hashlimit-above 5/minute \
                   --hashlimit-mode srcip     \
      -j DROP

Debug version:

#!/bin/sh
dport=9999
limit=2/minute
burst=2

iptables -F
iptables -N SuperUser 2>/dev/null
iptables -N SuperUserLimited 2>/dev/null

# SuperUserLimited
iptables -A SuperUserLimited -j LOG                         \
                                 --log-level info           \
                                 --log-prefix 'SU:dropped '
iptables -A SuperUserLimited -j DROP

# SuperUser
iptables -A SuperUser -j LOG                         \
                          --log-level info           \
                          --log-prefix 'SU:new '
iptables -A SuperUser -m hashlimit                   \
                          --hashlimit-name SuperUser \
                          --hashlimit-above $limit   \
                          --hashlimit-burst $burst   \
                          --hashlimit-mode srcip     \
                      -j SuperUserLimited
iptables -A SuperUser -j LOG                         \
                          --log-level info           \
                          --log-prefix 'SU:accepted '

# main
iptables -A INPUT -p tcp --dport $dport \
                  -m state --state NEW  \
                  -j SuperUser
9
  • Hm, never seen hashlimit while googling. But I don't understand how it works: iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m hashlimit --hashlimit-name SSH --hashlimit-mode srcip --hashlimit-above 5/min -j REJECT this call does not trap any command, while iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m hashlimit --hashlimit-name SSH --hashlimit-mode srcip --hashlimit 5/min -j REJECT traps all new connections...
    – PoltoS
    Commented Jun 21, 2014 at 22:38
  • I don't see --hashlimit option in the documentation, so the second command should have raised an error. Commented Jun 21, 2014 at 23:39
  • It seems I've an old iptables, where hashlimit seems to be same as hashlimit-upto. May be it does not work being to old.
    – PoltoS
    Commented Jun 23, 2014 at 13:48
  • I have iptables-1.4.19.1-1.fc20.x86_64. Commented Jun 23, 2014 at 13:52
  • @PoltoS, what iptables version do you have? What distribution? Commented Jun 24, 2014 at 14:15
0

To limit the number of connections is to use connlimit match. an example:

iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 5 --connlimit-mask 32 -j REJECT --reject-with tcp-reset

that will reject connections above 5 from one source IP. If you want to protect from a DDoS attack use hashlimit, you can limit them per IP, per combination IP + port, etc. So an example for a web server will be something like this

iptables -A INPUT -p tcp --dport 80 -m hashlimit --hashlimit 45/sec --hashlimit-burst 60 --hashlimit-mode srcip --hashlimit-name DDOS --hashlimit-htable-size 32768 --hashlimit-htable-max 32768 --hashlimit-htable-gcinterval 1000 --hashlimit-htable-expire 100000 -j ACCEPT

2
  • @PoltoS, How is it ?
    – totti
    Commented Jun 25, 2014 at 14:14
  • This is not what I want. This limits simultaneous connections, while I need to limit total number of connections established (and may be ended) during 1 minute.
    – PoltoS
    Commented Jul 28, 2014 at 12:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .