Update 2012-03

Original article written in 2009 describe ipset v.2 which unfortunately do not work with up-to-date Linux kernels.

For some time ipset v.6 was provided by package 'xtables-addons' in Debian until 2012-02-18 when ipset was finally separated to standalone package.

ipset6 utility have slightly different syntax:

ipset4 ipset6
ipset --create net2blk nethash ipset create net2blk hash:net
ipset --add net2blk <CIDR notation> ipset add net2blk <CIDR notation>

Due to Dynamic Kernel Module Support installation of ipset become much easier.

Here is a little introduction how to use ipset. I hope this might be interesting or useful.

The idea of ipset is to consolidate multiple similar iptables rules into one where you're can block (or allow) a set of IP addresses (or ports) like we can assign file system permissions on group level rather than on per user level. It also have a huge performance benefit if you have hundreds of rules because ipset using bitmasks for matching.

It is easier to manage one rule for multiple addresses rather than multiple rules for each and every address.

In Debian ipset can be easily installed by

apt-get install ipset ipset-source && m-a a-i ipset

(ipset loads its kernel module automatically so "modprobe ipset" is not needed)

Then as root we can create a new set of networks named 'nets2blk'

ipset -N nets2blk nethash


ipset -N nets2blk iptreemap

Then (as root) let's load 'nets2blk' with list of networks in CIDR notation from file. In this example I'm using file with one subnet per line like
while read ln; do ipset -A nets2blk $ln; done < CIDR.list

Or same using sudo:

sudo bash -c "while read ln; do ipset -A nets2blk \$ln; done < CIDR.list"

Now when we have ipset prepared we can create one firewall rule for thousands of networks:

sudo iptables -A INPUT -m set --set nets2blk src -j DROP