Skip to main content
  1. Index/

nftables

nftables is the successor to iptables within the Linux Netfilter framework, merged into the mainline kernel in 3.13 (2014) and now the default firewall backend on all major distributions — Debian 10+, Ubuntu 20.04+, RHEL 8+, Fedora 32+. It replaces not just iptables but the entire family of legacy Netfilter frontends: ip6tables (IPv6), arptables (ARP), and ebtables (Ethernet bridging) are all unified under a single nft command and a single kernel subsystem. The kernel component is a generic, protocol-independent packet classification engine; the protocol-specific logic (IPv4, IPv6, ARP, bridging) is expressed in user-space rule syntax rather than hardcoded in separate kernel modules. This unification eliminates the fragmented ruleset management of the iptables era, where a firewall with consistent IPv4/IPv6 and bridging policy required coordinating four separate tools with four separate rulesets and four separate persistence mechanisms.

The nftables data model is more expressive than iptables. Rules are organised into tables (named, associated with a protocol family: ip, ip6, inet for dual-stack, arp, bridge, netdev) and chains (which declare their hook point and priority explicitly rather than being fixed as in iptables). The inet family is the key addition: a single inet table with inet chains handles both IPv4 and IPv6 traffic with one ruleset, eliminating the duplication of maintaining filter rules in both iptables and ip6tables. Rule syntax uses a consistent expression language: ip saddr 192.168.0.0/24, tcp dport { 80, 443 }, ct state established,related, meta oifname "eth0". The major performance and expressiveness improvement over iptables is sets and maps: nftables maintains kernel-side data structures (hash tables, radix trees, intervals) that can hold thousands of IP addresses or port ranges and match against them in O(1) or O(log n) time, rather than iptables’s O(n) linear scan. A set is declared once and referenced by name in rules: ip saddr @blocked_hosts drop — updating the set (adding or removing an IP) does not require reloading or re-evaluating the ruleset. Maps extend this to verdict maps (ip daddr map { 10.0.0.1: accept, 10.0.0.2: drop }) and NAT translation maps, enabling compact, data-driven rulesets that would require thousands of individual iptables rules. Ruleset updates are atomic: the entire ruleset can be replaced in a single nft -f operation using a transaction, preventing the brief inconsistency windows that iptables rule loading creates when rules are added one at a time.

In Kubernetes environments, nftables is relevant in two contexts. kube-proxy added an nftables backend (beta in Kubernetes 1.31) that replaces the historically iptables-based Service load balancing with nftables sets and maps, dramatically reducing rule count and improving connection setup latency at scale — the same 10,000-Service cluster that generates hundreds of thousands of iptables rules generates a handful of nftables sets instead. firewalld uses nftables as its backend on RHEL 8+ and Fedora, translating its zone-based policy model into nftables rules. The iptables-nft compatibility shim allows legacy tooling that emits iptables commands to function on nftables systems, but the shim carries overhead and loses nftables’ atomicity guarantees — production systems should migrate to native nftables rules or use firewalld rather than relying on the compatibility layer. eBPF-based CNI plugins like Cilium bypass Netfilter entirely for pod-to-pod traffic, attaching XDP and TC programs before packets reach the nftables hooks, so nftables and Cilium coexist at different layers of the networking stack: nftables handles host-level firewall policy, Cilium handles pod network policy in eBPF.

Related

iptables

iptables is the user-space command-line interface to the Linux kernel’s Netfilter packet filtering framework, the dominant firewall tool on Linux from its introduction in 2001 until nftables began replacing it in the mid-2010s. Netfilter inserts hook points at five positions in the kernel’s IPv4 (and separately IPv6, via ip6tables) packet processing path: PREROUTING (immediately after a packet arrives, before routing), INPUT (packets destined for the local host), FORWARD (packets being routed through the host), OUTPUT (packets generated by local processes), and POSTROUTING (after routing, before transmission). At each hook point, Netfilter calls into the active tables, each of which contains ordered chains of rules. A rule is a match condition (source IP, destination port, protocol, connection state, interface, packet mark, and many more via match extensions) paired with a target — the action to take if the rule matches: ACCEPT, DROP, REJECT, LOG, MASQUERADE, DNAT, SNAT, or a jump to a user-defined chain. Rules are evaluated in order; the first matching rule’s target is applied and evaluation stops (unless the target is LOG or another non-terminating target). If no rule matches, the chain’s policy (the default target) applies.

WireGuard

WireGuard is a VPN protocol and implementation designed by Jason Donenfeld, merged into the Linux kernel in 5.6 (2020) and subsequently ported to Windows, macOS, iOS, Android, and BSD. Its defining characteristic is radical simplicity: the reference Linux kernel implementation is approximately 4,000 lines of code, compared to tens of thousands for IPsec’s XFRM subsystem and hundreds of thousands for OpenVPN. This simplicity is a deliberate security property — a smaller codebase has a smaller attack surface, is easier to audit, and is less likely to contain implementation vulnerabilities. WireGuard achieves this by making every design decision that allows optionality to be eliminated: there is no algorithm negotiation, no handshake negotiation, no cipher suite selection. The cryptographic suite is fixed: X25519 for key exchange, ChaCha20-Poly1305 for authenticated encryption, BLAKE2s for hashing and key derivation (via a custom HKDF-like construction), and Curve25519 for the static key pairs that identify peers. Peers are identified exclusively by their 32-byte Curve25519 public key, making WireGuard a public-key routed VPN: there are no usernames, passwords, certificates, or CAs; access control is entirely a function of which public keys are listed in each peer’s configuration.

eBPF (Extended Berkeley Packet Filter)

eBPF (Extended Berkeley Packet Filter) is a Linux kernel subsystem, its modern form dating to kernel 3.18 (2014), that allows user-authored programs to run inside the kernel with near-native performance, subject to safety guarantees enforced at load time by a verifier. The name is historical: the original BPF (Berkeley Packet Filter, 1992) was a narrow packet filtering mechanism for tools like tcpdump. eBPF extended the instruction set, registers, and capabilities far beyond packet filtering into a general-purpose in-kernel programmability platform. The central design constraint is that eBPF programs must be provably safe: they cannot crash the kernel, loop infinitely, or access memory out of bounds. The verifier statically analyses every program at load time, checking that all memory accesses are bounds-checked, all loops are bounded or unrolled, and all pointer dereferences are preceded by null checks. Only programs that pass verification are accepted; once accepted, the kernel JIT-compiles the eBPF bytecode to native machine code for the host architecture — x86-64, ARM64, RISC-V — so eBPF programs run at the same speed as compiled kernel code, not as an interpreter.