Abstract
| Goal | Describe the major enhancements in network packet processing and network device management. |
| Objectives |
|
| Sections |
|
| Lab | Implementing Enhanced Networking Features |
After completing this section, students should be able to explain the new nftables firewall back-end design, advantages, and configuration.
Firewalld, the firewall management tool in Red Hat Enterprise Linux, uses nftables as its new default firewall back end. In Red Hat Enterprise Linux 8, nftables replaces iptables, which is now deprecated.
The nft command replaces the iptables commands iptables, ip6tables, arptables, and ebtables, as a unified, consistent, and simpler command. Additionally, nftables is more efficient and can perform multiple actions in a single rule.
Introducing Nftables as the New Back End for Firewalld
Firewalld uses nftables as its back end.
The nft command replaces the iptables, ip6tables, arptables, and ebtables commands.
Firewalld is the recommended way to manage the firewall, over the low-level nft command.
The iptables commands are links to the xtables-nft-multi command, which accepts iptables syntax but creates nftables rules instead.
Red Hat recommends using firewalld when managing your firewall.
Even though firewalld now uses the nftables back end, it behaves the same as in the previous releases.
Its syntax is the same, even for the direct and rich rules.
In addition to the firewall-cmd and firewall-config commands, you can also manage firewalld with the web console.
Comparing Nftables with Iptables
Issues with iptables regarding performance, code maintenance, ease of use, and scalability are solved by nftables.
Although you should use firewalld to inspect your firewall rules, you can view all firewall information with a single underlying tool: nft.
You only need a single rule for both IPv4 and IPv6 instead of duplicating rules with iptables and ip6tables.
You can add multiple actions per rule. For example, you can log and deny in the same rule.
Red Hat recommends using Firewalld for managing the firewall. As an alternative, for complex use cases, you can also work directly with the nft command-line tool to create nftables tables, chains, and rules.
Nftables Objects
In nftables, tables are the top-level objects logically organizing your firewall configuration.
Inside tables, chains group your firewall rules.
Rules can have multiple conditions and multiple actions.
Use the nft command to create and review all those nftables objects.
For persistence, define your objects in /etc/sysconfig/nftables.conf and enable the systemd nftables service.
Introducing the Table Object
In nftables, tables are top-level objects that you use to group your firewall rules. To list the tables, use the nft list tables command.
[root@demo ~]#nft list tablestable ip filter table ip6 filter ...output omitted... table inet firewalld table ip firewalld table ip6 firewalld
When the firewalld service starts, it creates tables from the previous output.
Notice that firewalld creates its own tables, named firewalld, to group its rules.
It also creates the other tables, such as filter, so you can add your own tables with the nft command.
Each table has an address family, such as ip, ip6, or inet, indicating the type of packets it is processing.
inet is a special address family that combines IPv4 and IPv6.
This is useful for rules that apply to both families.
This way, you do not have to write the same rule for IPv4 and again for IPV6.
Create new tables with the nft add table family name command and delete tables with nft delete table family name.
[root@demo ~]#nft add table inet mytable
With nftables, administrators can create as many tables as needed to organize the firewall configuration. On the other hand, iptables has predefined tables that cannot be changed.
Introducing nftables Chains
Inside tables, chains group the firewall rules.
Use the nft list table family name to list the contents of a table.
[root@demo ~]#nft list table inet filtertable inet filter { chain input { type filter hook input priority 0; policy drop; } chain forward { type filter hook forward priority 0; policy accept; } chain output { type filter hook output priority 0; policy accept; } }
The previous output shows three chains inside the filter table.
Chains have special attributes:
When you create a chain, you give it a name of your choice.
The names in the previous output, input, forward, and output, have been chosen to help you transition from iptables.
They have no other meaning.
The type indicates the purpose of the chain.
This can be filter to filter the traffic, nat to perform network address translation, or route to mark packets.
The hook attaches the chain to a packet processing stage in the kernel.
The hook value can be prerouting, input, output, forward, or postrouting.
When two or more chains have the same hook value, the priority indicates which chain to process first. The chain with the lowest priority value is processed first.
The priority is evaluated globally, across all the tables.
In the following example, the system evaluates the rules from the myinput1 chain, then from the Input_ch chain, and finally from the myinput2 chain.
[root@demo ~]#nft list table inet mytable1table inet mytable1 { chainmyinput1{ type filter hook inputpriority -10; policy accept; } chainmyinput2{ type filter hook inputpriority 100; policy accept; } }[root@demo ~]#nft list table inet mytable2table inet mytable2 { chainInput_ch{ type filter hook inputpriority 50; policy accept; } }
The policy establishes the default behavior of the chain when no rule matches.
The policy is optional and defaults to accept.
You create a new chain with the nft add chain family table_name chain_name { attributes } command and you delete chains with nft delete chain family table_name chain_name.
[root@demo ~]#nft add chain inet mytable go_in \>{ type filter hook input priority 10 \; policy drop \;}
Remember to protect the ; character from Bash with \.
Writing nftables Rules
The chains group your firewall rules.
Each rule has two parts: the matches part which gives the conditions the packet must meet, and the statements part to indicate the actions to perform when the conditions match.
Use the nft add rule family table_name chain_name match... statement... command to add a rule to a chain.
[root@demo ~]#nft add rule inet mytable go_in ct state established,related accept[root@demo ~]#nft add rule inet mytable go_in iifname lo accept[root@demo ~]#nft add rule inet mytable go_in icmp type echo-request accept[root@demo ~]#nft add rule inet mytable go_in tcp dport {ssh, http, https} accept[root@demo ~]#nft list table inet mytabletable inet mytable { chain go_in { type filter hook input priority 10; policy accept; ct state established,related accept iifname "lo" accept icmp type echo-request accept tcp dport { ssh, http, https } accept } }
Consult the nft(8) man page to get the full rule syntax. You can use the iptables-translate command to translate the iptables syntax to nft.
[root@demo ~]#iptables-translate -A INPUT -p tcp --dport 22 \>-m conntrack --ctstate NEW -j ACCEPTnft add rule ip filter INPUT tcp dport 22 ct state new counter accept
The iptables-translate command shows the corresponding nft command but does not run it.
When a packet matches the conditions of a rule, and the statement is accept, nftables does not evaluate further the following rules in the chain.
However, if there is another chain with the same hook, nftables carries on evaluating the packet against the rules in that second chain.
This may result in the packet being dropped if the second chain does not accept it.
The following example illustrates that situation.
[root@demo ~]#nft list table inet mytabletable inet mytable { chain go_in { type filter hook input priority10; policy accept;tcp dport 8181 accept}[root@demo ~]#nft list table inet mytable2table inet mytable2 { chain go_in2 { type filter hook input priority20; policydrop; } }
In this example, a TCP packet with a destination port of 8181 first goes through the go_in chain (priority 10) where a rule accepts it.
Then, the packet goes through the go_in2 chain (priority 20) where nftables drops it because of its default policy.
Ultimately the packet is dropped even though there is an explicit rule that accepts it in the first chain.
The nft add rule command adds the new rule at the end on the chain.
The nft insert rule command takes the same parameters but inserts the rule at the beginning of the chain.
By adding the handle option, you can also insert a rule at a specific position.
A handle is a unique object identifier.
When you create an object, such as a rule, the system automatically gives it a handle.
First, retrieve the handle of the existing rules by adding the --handle (-a) option to the nft list table command.
[root@demo ~]#nft list table inet mytable --handletable inet mytable {# handle 21chain go_in {# handle 1type filter hook input priority 10; policy accept; ct state established,related accept# handle 2iifname "lo" accept# handle 3icmp type echo-request accept# handle 4tcp dport { ssh, http, https } accept# handle 6} }
To insert a rule after the rule with handle 4, use the nft add rule command as follows:
[root@demo ~]#nft add rule inet mytable go_in handle 4 tcp dport ftp log reject[root@demo ~]#nft list table inet mytable --handletable inet mytable { # handle 21 chain go_in { # handle 1 type filter hook input priority 10; policy accept; ct state established,related accept # handle 2 iifname "lo" accept # handle 3 icmp type echo-request accept# handle 4tcp dport ftp log reject # handle 8tcp dport { ssh, http, https } accept # handle 6 } }
You also use the handle to remove a rule with the nft delete rule command.
[root@demo ~]#nft delete rule inet mytable go_in handle 8[root@demo ~]#nft list table inet mytable --handletable inet mytable { # handle 21 chain go_in { # handle 1 type filter hook input priority 10; policy accept; ct state established,related accept # handle 2 iifname "lo" accept # handle 3 icmp type echo-request accept # handle 4 tcp dport { ssh, http, https } accept # handle 6 } }
Red Hat recommends using Firewalld for managing your system firewall.
As an alternative, and with complex rules, you can disable firewalld and directly use nftables through the nft command.
Also, for compatibility with previous releases, the iptables commands and the Systemd service are still available but deprecated.
Replacing Firewalld by Nftables or Iptables
Red Hat recommends using firewalld for managing your system firewall.
For complex configurations, you can disable firewalld and directly use nftables.
Use the iptables-restore-translate command to migrate your iptables rules to nftables.
As an alternative, use the iptables compatibility layer to reuse your legacy iptables rules.
Replacing Firewalld by Nftables Rules
Firewalld rich and direct rules allow for complex firewall configurations.
Sometimes, however, you may prefer to disable firewalld and directly use nftables from the command line.
In preparation for that configuration, stop, disable, and mask firewalld.
[root@demo ~]#systemctl stop firewalld[root@demo ~]#systemctl disable firewalldRemoved /etc/systemd/system/multi-user.target.wants/firewalld.service. Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.[root@demo ~]#systemctl mask firewalldCreated symlink /etc/systemd/system/firewalld.service -> /dev/null.[root@demo ~]#nft flush ruleset
When the firewalld service stops, it does not clear its configuration.
The nft flush ruleset command removes all the nftables chains and tables.
Enable and start the nftables service.
[root@demo ~]#systemctl enable --now nftablesCreated symlink /etc/systemd/system/multi-user.target.wants/nftables.service -> /usr/lib/systemd/system/nftables.service.
When the service starts, it uses the nft -f /etc/sysconfig/nftables.conf command to load the rules from the /etc/sysconfig/nftables.conf file.
By default, the file only contains comments that you can use as a starting point to develop your rules.
You can also generate the file from your current nftables configuration by using the nft list ruleset command.
[root@demo ~]#nft list ruleset > /etc/sysconfig/nftables.conf
As an alternative, you can also use a script.
For that, make sure to start your file with #!/usr/sbin/nft -f for the nft -f command to identify it as a script and not as a list of rules in the pseudo JSON format.
The nft -f command accepts both formats.
[root@demo ~]#cat /etc/sysconfig/nftables.conf#!/usr/sbin/nft -f flush ruleset add table inet mytable add chain inet mytable go_in { type filter hook input priority 10;policy drop;} add rule inet mytable go_in ct state established,related accept add rule inet mytable go_in iifname lo accept add rule inet mytable go_in icmp type echo-request accept add rule inet mytable go_in tcp dport {ssh, http, https} accept
Translating Iptables Rules to Nftables
From a backup of your iptables rules, use the iptables-restore-translate command. The command generates nftables commands on its output.
[root@demo6 ~]#iptables-save > save.txt[root@demo6 ~]#cat save.txt# Generated by iptables-save v1.4.7 on Mon Feb 18 16:25:28 2019 *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [85:14053] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT # Completed on Mon Feb 18 16:25:28 2019[root@demo6 ~]#scp save.txt root@demo:/root[root@demo ~]#iptables-restore-translate -f save.txt# Translated by iptables-restore-translate v1.8.2 on Tue Feb 19 02:57:51 2019 add table ip filter add chain ip filter INPUT { type filter hook input priority 0; policy accept; } add chain ip filter FORWARD { type filter hook forward priority 0; policy accept; } add chain ip filter OUTPUT { type filter hook output priority 0; policy accept; } add rule ip filter INPUT ct state related,established counter accept add rule ip filter INPUT ip protocol icmp counter accept add rule ip filter INPUT iifname "lo" counter accept add rule ip filter INPUT ct state new tcp dport 22 counter accept add rule ip filter INPUT counter reject with icmp type host-prohibited add rule ip filter FORWARD counter reject with icmp type host-prohibited # Completed on Tue Feb 19 02:57:51 2019
Review the rules and redirect the iptables-restore-translate -f command output to /etc/sysconfig/nftables.conf for the nftables service.
Do not forget to add the #!/usr/sbin/nft -f line at the top of the file.
Replacing Nftables by Iptables
nftables provides a compatibility layer for iptables. The iptables and ip6tables commands are still available, but they are links to the nftables xtables-nft-multi command. That command accepts the iptables syntax but creates nftables objects instead.
In addition, the iptables-services package provides the Systemd iptables service and the associated /etc/sysconfig/iptables and /etc/sysconfig/iptables-config configuration files.
For this reason, you can reuse your configuration from previous Red Hat Enterprise Linux releases.
The following example shows how to switch your configuration to the now deprecated iptables infrastructure.
[root@demo ~]#yum install iptables-services...output omitted... Is this ok [y/N]:y...output omitted... Complete![root@demo ~]#systemctl disable --now firewalld nftables[root@demo ~]#systemctl mask firewalld nftablesCreated symlink /etc/systemd/system/firewalld.service -> /dev/null. Created symlink /etc/systemd/system/nftables.service -> /dev/null.[root@demo ~]#systemctl enable --now iptablesCreated symlink /etc/systemd/system/basic.target.wants/iptables.service -> /usr/lib/systemd/system/iptables.service.[root@demo ~]#iptables -nLChain INPUT (policy ACCEPT) target prot opt source destination ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain FORWARD (policy ACCEPT) target prot opt source destination REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain OUTPUT (policy ACCEPT) target prot opt source destination[root@demo ~]#nft list rulesettable ip filter { chain INPUT { type filter hook input priority 0; policy accept; ct state related,established counter packets 104 bytes 6984 accept meta l4proto icmp counter packets 0 bytes 0 accept iifname "lo" counter packets 0 bytes 0 accept meta l4proto tcp ct state new tcp dport 22 counter packets 0 bytes 0 accept counter packets 18 bytes 5634 reject with icmp type host-prohibited } chain FORWARD { type filter hook forward priority 0; policy accept; counter packets 0 bytes 0 reject with icmp type host-prohibited } chain OUTPUT { type filter hook output priority 0; policy accept; } }
Notice in the previous output that the iptables -nL command reformats nftables rules. If you insert a rule with nft, the iptables -nL command reflects that new rule. In the same way, if you insert a rule with the iptables command, nft also reports that rule.
The nft(8) man page.
For more information on firewall management, refer to the Using and configuring firewalls chapter in the Configuring and Managing Networking guide at https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html-single/configuring_and_managing_networking/#assembly_using-firewalls_Configuring-Networking-with-GNOME-GUI
For more information on nftables, refer to the Firewalld: The Future is nftables article at https://developers.redhat.com/blog/2018/08/10/firewalld-the-future-is-nftables/