https://www.teldat.com/wp-content/uploads/2022/06/cropped-andrejStender-500x500-1-96x96.jpg

TELDAT Blog

Communicate with us

Connecting some of the dots between Nftables, Iptables and Netfilter

Nov 10, 2020

nftables-and-netfilter-hooks-via-linux-kernelWhen it comes to packet filtering on Linux, Nftables (a successor to Iptables) has matured sufficiently in recent years for it to be considered the default tool to use today.

However, Iptables is still widely used in modern systems (e.g., Debian buster),  with it often being “emulated” by using Nftables as backend, whereupon it becomes merely an alternative syntax to Nftables for defining packet filtering rules. Emulated or not, both Nftables and Iptables are based on the underlying Netfilter framework.

Netfilter

The Netfilter framework provides a series of “hooks” inside the Linux kernel network stack that are traversed by network packets (Figure 1). Other kernel components can register callback functions with those hooks, enabling them to inspect any packets coming in and decide whether to drop or accept them.

Netfilter Diagram

 

Figure 1: Simplified block diagram of Netfilter hooks

When a network packet is received on a network device, it first passes through the Prerouting hook. This is where the routing decision takes place. The kernel decides whether the packet is destined for a local process (e.g., a listening socket on a server in this system) or whether to forward it (system operates as a router). In the first case, the packet passes the Input hook and is then handed over to the local process.  If the packet is destined to be forwarded, it traverses the Forward hook and then a final Postrouting hook before being sent out on a network device. For packets that are generated locally (e.g., by a client or server process that likes sending things out), they must first pass the Output hook and then the  Postrouting hook before being sent out on a network device.

Hooks have been in the kernel for many years now but overall, their functionality has changed very little since the days of kernel 2.4. Of course, things get somewhat more complex when it comes to the intricate details of a modern kernel (Figure 2): The aforementioned hooks  exist independently for the IPv4 and IPv6 protocols. Thus, IPv4 and IPv6 packets each traverse their own hooks. There are also other hooks for ARP packets and for Bridging. And all the  hooks exist independently within each network namespace. Additionally, there is an ingress hook for each network device. The list goes on…

IPv4-IPv6, ARP

 

Figure 2: Netfilter hooks for IPv4, IPv6, ARP, Bridging and Ingress

Registering callbacks

Figure 3 shows the API provided by Netfilter for registering callback functions with a hook. Multiple functions can be registered with a hook, and an integer value called priority sorts the functions for said hook in ascending order.

Callback function with a Netfilter hook

 

Figure 3: Registering/Unregistering a callback function with a Netfilter hook

 

Hook traversal and verdict

For each network packet traversing a hook, the registered callback functions are called upon one by one in the order defined by the priority value. Each callback is required to return a “verdict”: NF_ACCEPT or NF_DROP. In case of NF_ACCEPT, the packet will traverse the next callback (if there is one). Thus, if all callbacks return NF_ACCEPT, the packet continues traversing the kernel network stack. NF_DROP, however, causes the packet to be deleted so that no further callbacks are traversed.

Netfilter Hook

 

Figure 4: Traversal of callback functions and verdict

Nftables vs. Iptables

Both Nftables and Iptables organize their packet filtering rules into tables and chains, with a table being  merely a container to group chains with a common purpose. The actual rules reside in the chains. Both frameworks register their (base) chains as callbacks with the Netfilter hooks. Iptables has a predefined, fixed set of tables and chains (see Figure 5), and the chains take their names from the hooks they are registered with. Furthermore, the Iptables suite is split into several distinct command line tools and corresponding kernel modules:

  • iptables for IPv4
  • ip6tables for IPv6
  • arptables for ARP
  • ebtables for Bridging

 

IPv4 Netfilters Hooks

 

Figure 5: Iptables chains registered with IPv4 Netfilter hooks (+ connection tracking)

 

With Nftables, there are no predefined tables and chains, so it is up to the user to create them. This is done via a single command line tool called nft,which brings us to the concept of “address families”:

  • ip: maps to IPv4 hooks (default)
  • ip6: maps to IPv6 hooks
  • inet: maps to both IPv4 and IPv6 hooks
  • arp: maps to ARP hooks
  • bridge: maps to bridging hooks
  • netdev: maps to ingress hook

When creating a table, the user has to specify an address family. This then applies to all chains within that table. When creating a chain, the user must specify the Netfilter hook that the chain will be registered with and the priority value.

Example: IPv4 Input hook

Creating a table named filter in the address family ip and two base chains named foo and bar,  and registering them with the Netfilter IPv4 hook input with priorities 0 and 50 (Figure 6).

Nft input hook

 

input myfilter

Figure 6: IPv4 Netfilter Input hook

Example: Tiny Edge Router

Doing some simple IPv4 packet filtering and SNAT (masquerading) on an edge router.

WAN & LAN

 

Figure 7: Edge Router

nft create table ip nat

IPv4 Netfilter Hook connection tracking

 

Figure 8: Nftables chains registered with an IPv4 Netfilter hook (+ connection tracking)

Conclusion

At Teldat, we consider services like Nftables and Netfilter to be essential basic building blocks to provide the SDN / SD-WAN functionality

Related Posts