Advanced Firewall Management with nftables: Transitioning from iptables

nftables is the successor to iptables on Linux systems, and has since become the default firewall. If you have not yet transitioned over to nftables, you are missing out on improved performance, easier command syntax, and an overall simpler way to manage firewall rules. In this tutorial, you will learn how to transition to nftables from iptables. To do so, we must become familiar with how nftables differs from iptables from a functional standpoint, as well as the new command syntax for configuring rules.

In this tutorial you will learn:

  • How does nftables function differently than iptables?
  • How iptables commands are being automatically translated to nftables
  • How to get started with transitioning to nftables, from an iptables point of view
Advanced Firewall Management with nftables: Transitioning from iptables
Advanced Firewall Management with nftables: Transitioning from iptables
Software Requirements and Linux Command Line Conventions
Category Requirements, Conventions or Software Version Used
System Any Linux system
Software nftables, iptables
Other Privileged access to your Linux system as root or via the sudo command.
Conventions # – requires given linux commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – requires given linux commands to be executed as a regular non-privileged user

nftables vs. iptables: Differences in Functionality




iptables comes with multiple tools like iptables, ip6tables, arptables, and ebtables. This can make rule management rather complex, as we need to maintain multiple rulesets depending on what we are trying to filter. At minimum, in the age of widespread IPv6, it means that we need to write filters in both iptables and ip6tables nearly every time we want to add a rule to our firewall.

nftables combines everything into one tool. In addition, nftables gives us more control over the structure of our firewall rules. Instead of the default chains INPUT, OUTPUT, and FORWARD that are present in iptables, along with tables mangle, nat, filter, and raw, nftables does not come with any chains or tables automatically created. We are required to create and name our own tables and chains, and then populate them with rules and tie functionality together. The result is a lot more granular control over how our firewall processes network traffic.

In addition, there is also a difference in performance. Since iptables forces default chains and tables on us, this structure is touched with every packet flowing through our system, and has a measurable impact on network performance, even if no rules have been configured! Since nftables allows us to configure only exactly what we need, we can trim down the unnecessary parts introduced by iptables.

Automatic Transition From iptables to nftables

The good news is that some of the transition to nftables is being taken care of automatically.

DID YOU KNOW?
Even if you are using the outdated iptables commands on your system, these rules are being translated into the equivalent for nftables, and the configuration is being enforced by nftables. That is, unless you are using a severely outdated system (e.g., from 2019 or before) that still utilizes iptables under the hood.

The iptables command can still be used on most systems, but it is now linked to a tool that translates the input to equivalent nftables rules, before handing the configuration off to nftables for enforcement.

You can see this for yourself by using the readlink command to see that the iptables command is merely a symbolic link to another tool. On our Ubuntu test system, xtables-nft-multi is what is actually being executed any time we type iptables:

$ readlink -f $(which iptables)
/usr/sbin/xtables-nft-multi

If we open up the manual page for this tool with man xtables-nft-multi, we can see what it actually does:

xtables-nft — iptables using nftables kernel api




So this tool simply sends the iptables commands over to the nftables API.

Despite this translation happening for us automatically, it is still recommended to abandon the old iptables command syntax in favor of nftables. For complex rules, translation via the API may not work as expected, so we are better off interfacing directly with nftables through the nft command. Not only that, but the command syntax is easier, and rules are simpler to maintain.

In addition, iptables is liable to become completely deprecated in future releases, and this compatibility layer may cease to work or include needed functions. In short, transition is unavoidable and advantageous for system administrators.

Translating iptables to nftables

Complex rules that are written in iptables will undoubtedly need to be manually converted over nftables. However, for simpler rules, the iptables-translate command does a decent job at taking an iptables command as input and outputting the equivalent nft command. Here is an example that accepts all established and related connections:

$ iptables-translate -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
nft add rule ip filter INPUT ct state related,established counter accept

We specify the iptables command but use iptables-translate instead of iptables. The rest of the arguments are typical for iptables. Then, as output, we are given an nft command which directly translates to the same iptables rule.

Here is another example which would drop incoming ICMP traffic:

$ iptables-translate -t mangle -A PREROUTING -p icmp -j DROP
nft add rule ip mangle PREROUTING ip protocol icmp counter drop
NOTE
Unfortunatley the iptables-translate tool is not perfect, and quite easy to stump once you start giving it more complex iptables rules for which there is not a direct equivalent with the nft command.

nftables vs. iptables: Making the Transition

In this section, we will operate with the assumption that the reader is a system administrator who is reasonably familiar with iptables, but knows nothing about nftables. This will serve as an introduction to get you familiar with nftables, while assuming that you have a bit of knowledge in iptables to aid in understanding.

Let’s go through the process of applying some basic firewall configuration in nftables, while also showing how the same process would be done the old way in iptables:

  1. As mentioned earlier, nftables gives us a blank slate with no tables or chains created by default. So, unlike iptables, we should start off by creating a table. Tables are the top-most containers used for organizing our firewall rules. Let’s start by creating a table called filter:
    $ sudo nft add table inet filter
    




    nft starts the command and is how we interact with nftables. add tells the utility that we wish to add something. table is what we would like to add. inet means that we want to apply the rule to both IPv4 and IPv6 – we could have specified ip or ip6 if we only wanted to filter IPv4 or IPv6, respectively. Lastly, filter is the name of the table that we are adding.

  2. Next, we need to add a chain to our table. We will name our chain input to make it clear that this chain will be used to process incoming network packets:
    $ sudo nft 'add chain inet filter input { type filter hook input priority 0; }'
    

    We have already gone over what some of the arguments above will do; now let’s cover the rest. chain specifies that we are trying to add a chain to the firewall configuration. filter is the name of the table to which we are adding the new chain. input is the name of the chain (a commonly chosen name to make its purpose clear). In curly braces, we specify type filter to indicate that this chain will be filtering packets. hook input means that the chain will be attached to the input hook, which nftables uses for processing incoming packets. Lastly, priority 0 just gives the chain higher priority than other chains (a lower number equals higher priority, with 0 being the highest priority).

  3. Up to this point, we have a table named filter and a chain named input. Now we can continue with adding some rules to the chain. Let’s see a simple nft command to add a rule that allows incoming traffic on ports 80 and 443:
    $ sudo nft add rule inet filter input tcp dport { 80, 443 } accept
    

    The equivalent rule in iptables would be:

    $ sudo iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
    

    Both of these commands will do the same thing, which is allow incoming traffic on ports 80 (HTTP) and 443 (HTTPS) to flow through the firewall and hit the exposed services running on the server. The nft command proves to be simpler, while also applying to both IPv4 and IPv6, unlike the iptables command.

  4. We can see our nftables configuration by executing the following command:
    $ sudo nft list ruleset
    table inet filter {
    	chain input {
    		type filter hook input priority filter; policy accept;
    		tcp dport { 80, 443 } accept
    	}
    }
    

    The output is much easier to understand than that of iptables, with most of the credit due to its structured format. We can see our inet table named filter contains a chain named input, the chain is attached to the input hook, and that traffic destined for ports (dport) 80 and 443 is being accepted.

By completing these steps, you have set up a table and chain in nftables, along with a rule that applies to incoming traffic, while understanding how the command translates from the original iptables equivalent.

FEELING OVERWHELMED?
While nftables proves to be a bit easier than iptables, both are admittedly not very user friendly. If learning the new syntax seems like a daunting task, remember that simpler front ends like firewalld and ufw offer a much easier way to interact with the underlying iptables or nftables firewall on your system. These are user friendly alternatives that still utilize iptables and nftables, but have an easier syntax and do some of the extra work for you.


Closing Thoughts

In this tutorial, we saw how to transition from the iptables firewall to nftables firewall on a Linux system. This only serves as an introduction that scratches the surface, as both firewalls are complex and require a lot of dedication for those that wish to be thoroughly comfortable with using them.

Now that you know how to make tables, chains, and rules with the nft command, and can translate iptables syntax to nft via the iptables-translate tool, you will be able to get started with making the transition from iptables to nftables on your Linux system. For complex rules, some additional tinkering will likely be required. We recommend further reading on the nftables wiki, where you can see examples of advanced rules and nftables configuration.



Comments and Discussions
Linux Forum