Linux – Block Ping from server using iptables based on packet count

firewallicmpiptableslinux

I am trying to block icmp pings from a server if the packet count is greater than 2 per second (packet count reduced for testing).
I tried these 2 rules separately but they don't seem to help:

iptables -A INPUT -p icmp --icmp-type echo-request -m recent --update --seconds 1 --hitcount 2 -j DROP

iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT --match limit --limit 2/s --limit-burst 2

wht's wrong with these rules ?

I am pinging form another server using below command but the ping continues to get replies –

ping -n -i 0.2 192.168.2.86

also when I check iptables -nvL output – the packet count for the rule is not increasing …

Machine used is centos 6.8

Some Progress:
I added a default drop rule at the end of table:

iptables -A INPUT -p icmp -m icmp -j DROP

and then adding this rule dropped pings that exceeded the limit

iptables -A INPUT -p icmp -m icmp --icmp-type 8 -m limit --limit 2/second -j ACCEPT -m comment --comment "icmprule1"

still not able to block the server completely.

Best Answer

Here it goes, adding a secondary ICMPSCAN chain (and putting the jump rule in first position of INPUT chain):

iptables -N ICMPSCAN
iptables -I INPUT -p icmp -m icmp --icmp-type echo-request -j ICMPSCAN 
iptables -A ICMPSCAN -m recent --set --name badicmp --rsource 
iptables -A ICMPSCAN -m recent --update --seconds 1 --hitcount 2 --name badicmp --rsource -j DROP

Note: both set/update rules could be set instead in INPUT without the secondary, but I prefer to put such rules in distinct chains.

Note2: an additional rule after --set could be added to log the event...

dynamic blacklisting:

Now, to add a permanent dynamic blacklist based on recent hitcount trigger, we can take advantage of ipset feature. ipset is available for centos 6.x , and iptables is ipset aware, but you may need to install it first.

Here the iptables/ipset rules to match your need:

iptables -F ICMPSCAN
iptables -N ICMPSCAN
ipset -N banned_hosts iphash
iptables -I INPUT -p icmp -m icmp --icmp-type echo-request -j ICMPSCAN 
iptables -A ICMPSCAN -m recent --set --name badicmp --rsource 
iptables -A ICMPSCAN -m recent --update --seconds 1 --hitcount 2 --name badicmp --rsource -j SET --add-set banned_hosts src
iptables -A ICMPSCAN -m set --set banned_hosts src -j DROP

You can list the current contents of banned list using ipset list, for example:

# ipset list banned_hosts
Name: banned_hosts
Type: hash:ip
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 8284
References: 2
Members:
192.168.122.1

and manage the set list, for example to remove an ip address like:

# ipset del banned_hosts 192.168.122.1

See also this page: http://www.linuxjournal.com/content/advanced-firewall-configurations-ipset

Related Topic