IP Sets allow for optimized use of complex sets of filters used with the IPTables firewall. There are many types of sets available which provide various options to configure and extend IPTables. It is possible to store large quantities of IP addresses (IPv4 and IPv6), TCP/UDP port numbers, IP and MAC address pairs and IP address and port number pairs in an efficient way.

IP Sets can significantly improve the performance of the IPTables software so that it remains responsive even when several thousand entries are present.

The ipset utility is used to create, change and display IP sets which are a framework inside the Linux kernel.

Installation

If you are using an older version (you really should update for security reasons!) check that the appropriate kernel module has been loaded:

lsmod | grep ip_set

If no output is displayed, you should manually load the kernel module by running:

modprobe ip_set

Features

IP sets deliver different types of set structures which includes:

Types Explanation Example
bitmap:ip uses a memory range, where each bit represents one IP address and can store up to 65535 (B-class network) entries. ipset add set1 192.168.0.1
bitmap:ip,mac uses a memory range, where each 8 bytes represents one IP and a MAC addresses. A bitmap:ip,mac set type can store up to 65535 (B-class network) IP addresses with MAC. Only source MAC ipset add set2 192.168.1.1,00:01:23:45:67:89
bitmap:port uses a memory range, where each bit represents one TCP/UDP port. A bitmap:port type of set can store up to 65535 ports. ipset add set3 22
hash:ip uses a hash to store IP addresses where clashing is resolved by storing the clashing elements in an array and, as a last resort, by dynamically growing the hash. Same size network addresses can be stored in an hash:ip type of set as well. ipset add set4 10.0.1.1
hash:net uses a hash to store CIDR netblocks, which may be of different sizes. The same technique is used to avoid clashes as at the hash:ip set type. ipset add set5 192.168.1.0/24
hash:ip,port is similar to hash:ip but you can store IP address and protocol-port pairs in it. TCP, SCTP, UDP, UDPLITE, ICMP and ICMPv6 are supported with port numbers/ICMP(v6) types and other protocol numbers without port information. ipset add set6 192.168.1.1,icmp:ping
hash:ip,port,ip can store IP address, port number, and IP address triples in an hash:ip,port,ip type of set. ipset add set7 192.168.0.1,22,10.0.1.1
hash:ip,port,net can store IP address, port number and network address triples in this kind of set. ipset add set8 192.168.0.1,22,10.0.1.0/24
hash:net,port type supports to store network address and port number pairs. ipset add set9 192.168.1.0/24,tcp:443
hash:net,iface can store network address and interface name pairs. ipset add set10 192.168.1.0/24,red0
list:set a list:set kind can store other sets. It is like an ordered union of different sets. ipset add set1 set3 set5

How it works

Since IPset do not deliver a configure possibility over the web interface the whole configuration needs to be done over the console/ssh.

The first step should be to create an appropriate set with the above listed types of sets. As an example for an network addresses set which stores CIDR notated addresses the following example can be used:

ipset create newset hash:net

The new created set can now be filled with network addresses in CIDR format:

ipset add newset 12.23.34.45/16
ipset add newset 23.34.45.56/12
ipset add newset 34.45.56.67/15

The next step to activates the set also in the firewall is to create an appropriate rule in IPTables.

Note - As the IPFire web user interface for IPTables currently does not allow configuration of IP sets, you must add rules manually.

To make the firewall rules persistent, the usage of the firewall.local is advised.

As an example that the above added network addresses should be blocked for INPUT (if services are provided), FORWARD (direct client access are prevented {no proxy}) and OUTPUT (IPFire itself) as a source or destination for all ports and all protocols, the following rules can be used.

In start) section:

  ## add your 'start' rules here
  # IPSET FW entries in start
  # IPSET add rules for CIDR list
  /sbin/iptables -I CUSTOMFORWARD -m set --match-set newset dst -j REJECT
  /sbin/iptables -I CUSTOMINPUT -m set --match-set newset src -j REJECT
  /sbin/iptables -I CUSTOMOUTPUT -m set --match-set newset dst -j REJECT

in stop) section:

  ## add your 'stop' rules here
  # IPSET flushing related chains
  /sbin/iptable -F CUSTOMFORWARD
  /sbin/iptable -F CUSTOMINPUT
  /sbin/iptable -F CUSTOMOUTPUT

There is also the possibility to define the addresses from the set as source but also as destination by comma separation 'dst,src' in the IPTable rules.

Don't forget to restart the firewall after editing with:

/etc/sysconfig/firewall.local reload

Note - If you want to refresh the IP sets, you need to deactivate the IPTable rules before otherwise you will run into an error but also to flush the sets which needs to be changed is important (explanation can be found at the "Commands" section at the bottom).

Save and restore your configuration

There is the need to save the configuration manually otherwise your configuration will get lost after a reboot. IPset have his own configuration directory which can be found under /etc/ipset, so it might be a good idea to store your sets configuration in there which can be done by:

ipset save > /etc/ipset/ipset.conf

after a reboot the ipset.conf needs to be reactivated which can be done over a command placed for example into /etc/sysconfig/rc.local. The command looks in conjunction to the above handled IPset configuration directory like this:

ipset restore < /etc/ipset/ipset.conf

this will bring your whole configuration back.

Commands

There are several commands to control IPset but to list and explain all of them in detail here would sprinkle the frame, so only some major commands will be listed with a little explanation, for further info please refer to the Links section below.

ipset --flush {SETname}             # empties a defined chain
ipset destroy {SETname}             # deletes a defined chain
ipset destroy                       # deletes all chains
ipset save > /etc/ipset/ipset.conf  # save chains to survive a reboot
ipset -n list                       # shows all existing sets
ipset -t list                       # show further infos and sets
ipset list                          # lists all sets with further infos
ipset save > /tmp/ipsetbck          # makes a backup also in other directories
ipset restore < /tmp/ipsetbck       # restores the backup
ipset -W old-set new-set            # renames the sets & copy content from old to new set

There is a lot more of informations which should not be documented in here but there are good further knowledge findable in the internet regarding to this topic. Some sources are listed in the next section.