Bookmark this page

Chapter 7. Implementing Enhanced Networking Features

Abstract

Goal Describe the major enhancements in network packet processing and network device management.
Objectives
  • Explain the new nftables firewall back-end design, advantages and configuration.

  • Explain how the NetworkManager service has become an integral and mandatory component in modern network management, able to configure complex, layered network interfaces and components.

Sections
  • Managing Server Firewalls in RHEL 8 (and Guided Exercise)

  • Configuring Server Networking with NetworkManager (and Guided Exercise)

Lab Implementing Enhanced Networking Features

Managing Server Firewalls in RHEL 8

Objectives

After completing this section, students should be able to explain the new nftables firewall back-end design, advantages, and configuration.

Introducing Nftables

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.

Create nftables tables, Chains, and Rules using the nft Command Line Tool

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.

Figure 7.1: Attaching nftables chains to the input packet processing stage in the kernel

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 tables
table 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 filter
table 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:

name

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.

type

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.

hook

The hook attaches the chain to a packet processing stage in the kernel. The hook value can be prerouting, input, output, forward, or postrouting.

priority

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 mytable1
table inet mytable1 {
  chain myinput1 {
    type filter hook input priority -10; policy accept;
  }
  chain myinput2 {
    type filter hook input priority 100; policy accept;
  }
}
[root@demo ~]# nft list table inet mytable2
table inet mytable2 {
  chain Input_ch {
    type filter hook input priority 50; policy accept;
  }
}
policy

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 mytable
table 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 ACCEPT
nft 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 mytable
table inet mytable {
  chain go_in {
    type filter hook input priority 10; policy accept;
    tcp dport 8181 accept
}
[root@demo ~]# nft list table inet mytable2
table inet mytable2 {
  chain go_in2 {
    type filter hook input priority 20; policy drop;
  }
}

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 --handle
table 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
  }
}

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 --handle
table 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 ftp log reject # handle 8
    tcp 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 --handle
table 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
  }
}

Describing Nftables and Iptables Persistent Configuration

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 firewalld
Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
[root@demo ~]# systemctl mask firewalld
Created 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 nftables
Created 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 nftables
Created symlink /etc/systemd/system/firewalld.service -> /dev/null.
Created symlink /etc/systemd/system/nftables.service -> /dev/null.
[root@demo ~]# systemctl enable --now iptables
Created symlink /etc/systemd/system/basic.target.wants/iptables.service -> /usr/lib/systemd/system/iptables.service.
[root@demo ~]# iptables -nL
Chain 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 ruleset
table 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.

References

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/

Revision: rh354-8.0-0e36520