5.4. Using the iptables Service

To use the iptables and ip6tables services instead of firewalld, first disable firewalld by running the following command as root:
~]# systemctl disable firewalld
~]# systemctl stop firewalld
Then install the iptables-services package by entering the following command as root:
~]# yum install iptables-services
The iptables-services package contains the iptables service and the ip6tables service.
Then, to start the iptables and ip6tables services, enter the following commands as root:
~]# systemctl start iptables
~]# systemctl start ip6tables
To enable the services to start on every system start, enter the following commands:
~]# systemctl enable iptables
~]# systemctl enable ip6tables

5.4.1. iptables and IP Sets

The ipset utility is used to administer IP sets in the Linux kernel. An IP set is a framework for storing IP addresses, port numbers, IP and MAC address pairs, or IP address and port number pairs. The sets are indexed in such a way that very fast matching can be made against a set even when the sets are very large. IP sets enable simpler and more manageable configurations as well as providing performance advantages when using iptables. The iptables matches and targets referring to sets create references which protect the given sets in the kernel. A set cannot be destroyed while there is a single reference pointing to it.
The use of ipset enables iptables commands, such as those below, to be replaced by a set:
~]# iptables -A INPUT -s 10.0.0.0/8 -j DROP
~]# iptables -A INPUT -s 172.16.0.0/12 -j DROP
~]# iptables -A INPUT -s 192.168.0.0/16 -j DROP
The set is created as follows:
~]# ipset create my-block-set hash:net
~]# ipset add my-block-set 10.0.0.0/8
~]# ipset add my-block-set 172.16.0.0/12
~]# ipset add my-block-set 192.168.0.0/16
The set is then referenced in an iptables command as follows:
~]# iptables -A INPUT -m set --set my-block-set src -j DROP
If the set is used more than once a saving in configuration time is made. If the set contains many entries a saving in processing time is made.

5.4.1.1. Using IP Sets with firewalld

To use IP sets that are not supported by firewalld, a permanent direct rule is required to reference the set, and a custom service must be added to create these IP sets. This service needs to be started before firewalld starts, otherwise firewalld is not able to add the direct rules using these sets. You can add permanent direct rules with the /etc/firewalld/direct.xml file.
To see the list of IP set types supported by firewalld, enter the following command as root.
~]# firewall-cmd --get-ipset-types
hash:ip hash:ip,mark hash:ip,port hash:ip,port,ip hash:ip,port,net hash:mac hash:net hash:net,iface hash:net,net hash:net,port hash:net,port,net

Procedure 5.1. Configuring a Custom Service for an IP Set

Configure a custom service to create and load the IP set structure before firewalld starts.
  1. Using an editor running as root, create a file as follows:
    ~]# vi /etc/systemd/system/ipset_name.service
    [Unit]
    Description=ipset_name
    Before=firewalld.service
    
    [Service]
    Type=oneshot
    RemainAfterExit=yes
    ExecStart=/usr/local/bin/ipset_name.sh start
    ExecStop=/usr/local/bin/ipset_name.sh stop
    
    [Install]
    WantedBy=basic.target
  2. Use the IP set permanently in firewalld:
    ~]# vi /etc/firewalld/direct.xml
    <?xml version="1.0" encoding="utf-8"?>
    <direct>
       <rule ipv="ipv4" table="filter" chain="INPUT" priority="0">-m set
    --match-set <replaceable>ipset_name</replaceable> src -j DROP</rule>
    </direct>
  3. A firewalld reload is required to activate the changes:
    ~]# firewall-cmd --reload
    This will reload the firewall without losing state information (TCP sessions will not be terminated), but service disruption is possible during the reload.

5.4.1.2. Installing ipset

To install the ipset utility, enter the following command as root:
~]# yum install ipset
To see the usage message:
~]$ ipset --help
ipset v6.11

Usage: ipset [options] COMMAND
output truncated

5.4.1.3. ipset Commands

The format of the ipset command is as follows:
ipset [options] command [command-options]
Where command is one of:
create | add | del | test | destroy | list | save | restore | flush | rename | swap | help | version | - 
Allowed options are:
-exist | -output [ plain | save | xml ] | -quiet | -resolve | -sorted | -name | -terse
The create command is used to create a new data structure to store a set of IP data. The add command adds new data to the set, the data added is referred to as an element of the set.
The -exist option suppresses error message if the element already exists, and it has a special role in updating a time out value. To change a time out, use the ipset add command and specify all the data for the element again, changing only the time out value as required, and using the -exist option.
The test option is for testing if the element already exists within a set.
The format of the create command is as follows:
ipset create set-name type-name [create-options]
The set-name is a suitable name chosen by the user, the type-name is the name of the data structure used to store the data comprising the set. The format of the type-name is as follows:
method:datatype[,datatype[,datatype]]
The allowed methods for storing data are:
 bitmap | hash | list 
The allowed data types are:
ip | net | mac | port | iface 
When adding, deleting, or testing entries in a set, the same comma separated data syntax must be used for the data that makes up one entry, or element, in the set. For example:
ipset add set-name ipaddr,portnum,ipaddr

Note

A set cannot contain IPv4 and IPv6 addresses at the same time. When a set is created it is bound to a family, inet for IPv4 or inet6 for IPv6, and the default is inet.

Example 5.1. Create an IP Set

To create an IP set consisting of a source IP address, a port, and destination IP address, run a command as follows:
~]# ipset create my-set hash:ip,port,ip
Once the set is created, entries can be added as follows:
~]# ipset add my-set 192.168.1.2,80,192.168.2.2
~]# ipset add my-set 192.168.1.2,443,192.168.2.2
The set types have the following optional parameters in common. They must be specified when the set is created in order for them to be used:
  • timeout — The value given with the create command will be the default value for the set created. If a value is given with the add command, it will be the initial non-default value for the element.
  • counters — If the option is given with the create command then packet and byte counters are created for every element in the set. If no value is given with the add command then the counters start from zero.
  • comment — If the option is given with the create command then a quoted string of text can be passed with the add command to document the purpose of the element being added. Note that quotation marks are not allowed within the string, and escape characters will have no effect within IP set.

Example 5.2. List an IP Set

To list the contents of a specific IP Set, my-set, run a command as follows:
~]# ipset list my-set
Name: my-set
Type: hash:ip,port,ip
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 8360
References: 0
Members:
192.168.1.2,tcp:80,192.168.2.2
192.168.1.2,tcp:443,192.168.2.2
Omit the set name to list all sets.

Example 5.3. Test the Elements of an IP Set

Listing the contents of large sets is time consuming. You can test for the existence of an element as follows:
~]# ipset test my-set 192.168.1.2,80,192.168.2.2
192.168.1.2,tcp:80,192.168.2.2 is in set my-set.

5.4.1.4. IP Set Types

bitmap:ip
Stores an IPv4 host address, a network range, or an IPv4 network addresses with the prefix-length in CIDR notation if the netmask option is used when the set is created. It can optionally store a timeout value, a counter value, and a comment. It can store up to 65536 entries. The command to create the bitmap:ip set has the following format:
ipset create set-name range start_ipaddr-end_ipaddr |ipaddr/prefix-length [netmask prefix-length] [timeout value] [counters] [comment]

Example 5.4. Create an IP Set for a Range of Addresses Using a Prefix Length

To create an IP set for a range of addresses using a prefix length, make use of the bitmap:ip set type as follows:
~]# ipset create my-range bitmap:ip range 192.168.33.0/28
Once the set is created, entries can be added as follows:
~]# ipset add my-range 192.168.33.1
Review the members of the list:
~]# ipset list my-range
Name: my-range
Type: bitmap:ip
Header: range 192.168.33.0-192.168.33.15
Size in memory: 84
References: 0
Members:
192.168.33.1
To add a range of addresses:
~]# ipset add my-range 192.168.33.2-192.168.33.4
Review the members of the list:
~]# ipset list my-range
Name: my-range
Type: bitmap:ip
Header: range 192.168.33.0-192.168.33.15
Size in memory: 84
References: 0
Members:
192.168.33.1
192.168.33.2
192.168.33.3
192.168.33.4

Example 5.5. Create an IP Set for a Range of Addresses Using a Netmask

To create an IP set for a range of address using a netmask, make use of the bitmap:ip set type as follows:
~]# ipset create my-big-range bitmap:ip range 192.168.124.0-192.168.126.0 netmask 24
Once the set is created, entries can be added as follows:
~]# ipset add my-big-range 192.168.124.0
If you attempt to add an address, the range containing that address will be added:
~]# ipset add my-big-range 192.168.125.150
~]# ipset list my-big-range
Name: my-big-range
Type: bitmap:ip
Header: range 192.168.124.0-192.168.126.255 netmask 24
Size in memory: 84
References: 0
Members:
192.168.124.0
192.168.125.0
bitmap:ip,mac
Stores an IPv4 address and a MAC address as a pair. It can store up to 65536 entries.
ipset create my-range bitmap:ip,mac range start_ipaddr-end_ipaddr | ipaddr/prefix-length [timeout value ] [counters] [comment]

Example 5.6. Create an IP Set for a Range of IPv4 MAC Address Pairs

To create an IP set for a range of IPv4 MAC address pairs, make use of the bitmap:ip,mac set type as follows:
~]# ipset create my-range bitmap:ip,mac range 192.168.1.0/24
It is not necessary to specify a MAC address when creating the set.
Once the set is created, entries can be added as follows:
~]# ipset add my-range 192.168.1.1,12:34:56:78:9A:BC
bitmap:port
Stores a range of ports. It can store up to 65536 entries.
ipset create my-port-range bitmap:port range start_port-end_port [timeout value ] [counters] [comment]
The set match and SET target netfilter kernel modules interpret the stored numbers as TCP or UDP port numbers. The protocol can optionally be specified together with the port. The proto only needs to be specified if a service name is used, and that name does not exist as a TCP service.

Example 5.7. Create an IP Set for a Range of Ports

To create an IP set for a range of ports, make use of the bitmap:port set type as follows:
~]# ipset create my-permitted-port-range bitmap:port range 1024-49151
Once the set is created, entries can be added as follows:
~]# ipset add my-permitted-port-range 5060-5061
hash:ip
Stores a host or network address in the form of a hash. By default, an address specified without a network prefix length is a host address. The all-zero IP address cannot be stored.
ipset create my-addresses hash:ip [family[ inet | inet6 ]] [hashsize value] [maxelem value ] [netmask prefix-length] [timeout value ]
The inet family is the default, if family is omitted addresses will be interpreted as IPv4 addresses. The hashsize value is the initial hash size to use and defaults to 1024. The maxelem value is the maximum number of elements which can be stored in the set, it defaults to 65536.
The netfilter tool searches for a network prefix which is the most specific, it tries to find the smallest block of addresses that match.

Example 5.8. Create an IP Set for IP Addresses

To create an IP set for IP addresses, make use of the hash:ip set type as follows:
~]# ipset create my-addresses hash:ip
Once the set is created, entries can be added as follows:
~]# ipset add my-addresses 10.10.10.0
If additional options such as netmask and timeout are required, they must be specified when the set is created. For example:
~]# ipset create my-busy-addresses hash:ip maxelem 24 netmask 28 timeout 100
The maxelem option restricts to total number of elements in the set, thus conserving memory space.
The timeout option means that elements will only exist in the set for the number of seconds specified. For example:
~]# ipset add my-busy-addresses 192.168.60.0 timeout 100
The following output shows the time counting down:
~]# ipset list my-busy-addresses
Name: my-busy-addresses
Type: hash:ip
Header: family inet hashsize 1024 maxelem 24 netmask 28 timeout 100
Size in memory: 8300
References: 0
Members:
192.168.60.0 timeout 90
~]# ipset list my-busy-addresses
Name: my-busy-addresses
Type: hash:ip
Header: family inet hashsize 1024 maxelem 24 netmask 28 timeout 100
Size in memory: 8300
References: 0
Members:
192.168.60.0 timeout 83
The element will be removed from the set when the timeout period ends.
See the ipset(8) manual page for more examples.