Dynamic Rules with IPSet

Wouldn't it be good if port scanning IPs could trigger a rule that adds themselves to a 'known offenders' firewall list? Wouldn't it be good if you could combine white and black ACLs into single unified rules.

Typically IPTables operates statically from a predefined collection of rules. This has the advantage of allowing you to filter packets to very exact parameters. However at the cost of a lot of tedious and manual work, and when you're manually adding a bunch of these, easy mistakes are all to common with potentially quite severe consequences on a production system.

The idea is you can put all the static parameters in a single match rule, and have a mutable set of source/destination arguments. So you dont need to copy-paste-substitute lines for opening up ports etc.

Enter IPSet

IPSet is an extension for the the Netfilter kernel module. It allows you to create a mutable collection of addresses and define rules applying to everything in the set. This can significantly reduce the number of rules you have to write and allows you to control traffic without modifying the firewall itself.

For example suppose you have the following rules which allow access to some protected ports from a couple of known ips

-A INPUT -s 192.0.2.42 -d 0/0 -p tcp --dport 22 -j ACCEPT 
-A INPUT -s 192.0.2.42 -d 0/0 -p tcp --dport 25 -j ACCEPT
-A INPUT -s 198.51.100.54 -d 0/0 -p tcp --dport 22 -j ACCEPT
-A INPUT -s 198.51.100.54 -d 0/0 -p tcp --dport 25 -j ACCEPT

You could use condense this into a single rule:

-A INPUT -p tcp -m set --match-set ADMIN_ADDR src -m set --match-set RESTRICTED_PORTS dst -j ACCEPT

By creating the sets as follows

ipset create ADMIN_ADDR hash:ip
ipset create RESTRICTED_PORTS bitmap:port
ipset add ADMIN_ADDR 192.0.2.42,198.51.100.54
ipset add RESTRICTED_PORTS 22,25

The handy thing about this is that if you wanted to let your friend connect over ssh temporarily, you would not need to have to create and then delete new iptables rules. Instead with ipset you can do this

ipset add ADMIN_ADDR $friend_ip
ipset del ADMIN_ADDR $friend_ip 

In the next post, we will look at how iptables/nerfilter itself can modify sets, such as adding sources to blacklists.