Exploring the new nftables firewall tool – a successor to iptables

Traffic Rules

© Lead Image © Russell Shively, 123RF

© Lead Image © Russell Shively, 123RF

Author(s):

The nftables firewall utility offers a simpler and more consistent approach for managing firewalls in Linux.

If you are training to become a network administrator, or even if you just want to get better at Linux, you cannot avoid dealing with the topic of firewalls, including the rules for filtering packets on the network.

The iptables firewall tool [1] is slightly long in the tooth, and the program code in particular has become more and more complex. Small changes in the project core affected all the tools associated with the project. Iptables, ip6tables, ebtables, and arptables all originate from the same codebase – not in the form of modules, but by code duplication. Accordingly, the four tools drifted apart over time. Iptables was best maintained, and ebtables was neglected. Bugs patched in iptables still existed in Ebtables years later.

The problems with maintaining the iptables code base prompted the development of a successor called nftables [2] back in 2009 by the netfilter project [3]. The first two letters of nftables are derived from the project; nftables simply means "netfilter tables." The stated development goals include higher data throughput, greater scalability with a view to changing requirements, and, in particular, a modular structure that is easier to maintain. Since Linux 3.13 (January 2014), nftables has existed directly in the kernel [4]. The nftables firewall tool uses internal, proven components of the netfilter project.

As of the release of Debian 10 "Buster," which is planned for summer 2019, Debian will completely rely on nftables [5], which will also affect derivatives like Ubuntu and Linux Mint. Red Hat-based distros are also moving to more reliance on nftables. The current releases of most Linux distributions already contain nftables – not enabled, but ready for use.

Extensions and Conversions

You can create rules for firewalls with the command-line tools iptables (IPv4), ip6tables (IPv6), arptables (ARP packets), and ebtables (Ethernet frames). Nftables replaces all four with a single command-line tool named nft, which now sets all the rules for accepting, forwarding, modifying, or rejecting packets from the network on the system.

Iptables uses different filters and three processing chains named INPUT, FORWARD, and OUTPUT to handle packets. The nftables framework does not have any similar built-in chains – you'll have to define the chains yourself.

Nft uses two libraries: libmnl, a minimalist Netlink library [6], and libnfnetlink, a Netlink library in userspace [7]. As a result, the size of the code in the Linux kernel is smaller, and small changes to nft do not mean that you need to customize the kernel [8].

To make sure that the appropriate kernel module is loaded in your system kernel, work with the output from the modinfo (Figure 1) and lsmod (Figure 2) commands. The feedback in the examples shown is positive and lets you get started with nft directly.

Figure 1: The output from the modinfo command returns information about the kernel module.
Figure 2: lsmod tells you whether the kernel module has been loaded by the system.

Basic Configuration

Nftables starts with a completely empty ruleset; there are no predefined tables, chains, or rules. As the user (or admin), you first create the tables, add chains that latch into the Linux kernel as netfilter hooks, and then populate them with appropriate rules. All these steps are performed using the nft command, which you execute as root.

Listing 1 demonstrates how to define a firewall that does not (yet) let packets through. The first command (line 1) creates a table for IP packets of type filter. Line 2 adds a chain to the filter table. In line 3, a rule is added to the chain to discard all packets (drop).

Listing 1

Setting Up a Chain

01 # nft add table ip filter
02 # nft add chain ip filter input {type filter hook input priority 0\;}
03 # nft add rule ip filter input drop
04 # nft list ruleset -a
05 # nft delete rule ip filter input handle 2

The command in line 4 gives an overview with all the rules on the firewall (Figure 3). In addition to the entries, there are comments in the form # handle handle_number, which you use to reference the entries. This option is of particular interest if you want to delete or change existing specifications, or insert new ones before or after them. For example, the command from line 5 deletes the drop rule.

Figure 3: The command nft list ruleset -a lists all set rules.

Basic Approach

nft's developers chose the Berkeley Packet Filter (BPF) [9] to define the nomenclature of their rules, and they orient their work on the classic tcpdump [10], so that you don't have to relearn everything [11].

nft provides a number of address families: arp (ARP), bridge (previously provided by ebtables), inet (includes IPv4 and IPv6), ip (for IPv4), ip6 (for IPv6), and netdev are predefined. netdev is used to filter incoming packets before they reach Layer 3, according to the ISO/OSI specification.

nft translates the rules and keeps them in a small virtual machine (nftables core) for communication with the Linux kernel.

The example in Listing 2 demonstrates how to enable port 22 for incoming packets as needed for access via SSH. Thanks to nft, the overhead is reduced to a single command, and the syntax is simpler.

Listing 2

Enabling Port 22

### Allow incoming packets on port 22.
### With Iptables:
# iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
# iptables -A OUTPUT -p tcp --sport 22 -m conntrack --ctstate ESTABLISHED -j ACCEPT
### With Nft:
$ nft add rule inet filter input tcp dport 22 ct state new,established accept

If you want to add two ports, 80 and 443 (i.e., HTTP and HTTPS), you need two extra lines per port for iptables. With nft, however, you just need to extend the existing line to combine all three protocols at once. Port 22 is added in braces, followed by the two ports, 80 and 443 (Listing 3), separated by commas.

Listing 3

Adding Ports

# nft add rule inet filter input tcp dport { 22, 80, 443 } ct state new,established accept

Please note that the spaces within the brackets must be exactly as shown – otherwise Bash will swallow them up and complain. Users of Zsh run into the same problem, which you can resolve with suitable quoting.

Save and Restore

As with iptables, the nftables configuration can be saved to a file. The first command from Listing 4 writes the current ruleset to the firewall.config file, while the second command reads the configuration again.

Listing 4

Writing the Ruleset to a File

# nft list ruleset > firewall.config
# nft -f firewall.config

To make sure that there are no other (possibly interfering) rules in the cache before initializing the firewall, add a line that reads flush ruleset at the beginning of the firewall.config configuration file.

Translation

Humans are known to be creatures of habit who have difficulty with change. The iptables-translate and ip6tables-translate commands are two tools that help you get used to the new environment. These commands convert the nomenclature of iptables firewall rules to nftables format (Listing 5). You can convert both for individual statements and complete rulesets.

Listing 5

Converting Iptables Rules

$ iptables-translate -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
nft add rule ip filter INPUT tcp dport 22 ct state new counter accept
$ ip6tables-translate -A FORWARD -i eth0 -o eth3 -p udp -m multiport --dports 111.222 -j ACCEPT
nft add rule ip6 filter FORWARD iifname eth0 oifname eth3 meta l4proto udp udp dport { 111,222} counter accept

Conclusions

Nftables helps you accommodate several complex tools under one roof, thus making it easier to secure the network. You'll want to try out the new firewall rules before you deploy them on your network. One option is to create a virtual test network using VirtualBox or the smart application Mininet [12]. Or, you could set up a pack of Raspberry Pis on a small, isolated network to simulate a real-world configuration.

Acknowledgements

The author thanks Axel Beckert and Werner Heuser for their suggestions and criticism during the preparation of the article.

The Author

Frank Hofmann works on the road, preferably in Berlin, Geneva, and Cape Town, as a developer, trainer, and author. He is coauthor of the Debian Package Management Book (http://www.dpmb.org/index.en.html).