How to Use the nftables Framework to Configure Packet Filtering Firewalls in Linux

For decades, Linux administrators relied on the legacy iptables, ip6tables, and arptables utilities for packet inspection and network address translation. However, these tools suffered from separate codebases, inefficient linear rule evaluation, and complex syntax. nftables replaced the legacy Netfilter subsystem, uniting IPv4, IPv6, ARP, and bridging into a single kernel-level virtual machine. By leveraging sets, maps, and atomic transactions, nftables delivers significantly higher throughput and unified firewall administration.

Understanding the nftables Architecture: Tables, Chains, and Rules

Unlike iptables, which enforced predefined tables (filter, nat, mangle) with hardcoded chains, nftables uses an entirely customizable hierarchy:

  • Address Families: Defines the network protocol domain: ip (IPv4), ip6 (IPv6), inet (dual-stack IPv4/IPv6 unified), arp, and bridge.
  • Tables: Arbitrary containers created by the administrator to house specific chains and rules.
  • Chains: Hook points where packets are intercepted:
    • prerouting: Evaluates packets immediately upon arrival before routing decisions.
    • input: Filters packets destined for the local host.
    • forward: Filters packets being routed through the host to other interfaces.
    • output: Filters packets originated by local processes.
    • postrouting: Handles outbound modifications (such as SNAT/masquerade) prior to transmission.
  • Rules: Conditional expressions evaluated inside chains that trigger verdicts (accept, drop, reject, log, or jump).

Installing and Checking nftables Service Status

Most modern Linux distributions include nftables in the base installation. Ensure the management packages are installed:

sudo apt update
sudo apt install nftables -y

Enable and start the systemd service to persist firewall rules across reboots:

sudo systemctl enable --now nftables

Inspect the currently active ruleset:

sudo nft list ruleset

If no rules are configured, the command returns empty, indicating a clean slate.

Building a Dual-Stack Stateful Firewall Ruleset

Using the inet family, you can establish baseline protection for both IPv4 and IPv6 within a single configuration block.

Create a dedicated table named filter:

sudo nft add table inet filter

Add a standard input chain hooked to the Netfilter input stage with a default drop policy:

sudo nft 'add chain inet filter input { type filter hook input priority 0; policy drop; }'

Add stateful inspection rules to permit loopback traffic and established connections:

# Permit traffic on the local loopback interface
sudo nft add rule inet filter input iifname "lo" accept

# Permit established and related connection states
sudo nft add rule inet filter input ct state established,related accept

# Drop invalid packets immediately
sudo nft add rule inet filter input ct state invalid drop

Open required public services (such as SSH on port 22 and HTTPS on port 443) using anonymous sets:

sudo nft add rule inet filter input tcp dport { 22, 80, 443 } ct state new accept

Allow essential ICMP diagnostics (ping and IPv6 neighbor discovery):

sudo nft add rule inet filter input ip protocol icmp icmp type { echo-request, echo-reply } accept
sudo nft add rule inet filter input ip6 nexthdr icmpv6 accept

Configuring Forward and Output Chains

To regulate forwarded and outbound host traffic:

# Create forward chain (block forwarding by default on non-router hosts)
sudo nft 'add chain inet filter forward { type filter hook forward priority 0; policy drop; }'

# Create output chain (allow all outbound client lookups and sessions)
sudo nft 'add chain inet filter output { type filter hook output priority 0; policy accept; }'

Saving and Atomically Applying Configuration Files

To persist your firewall ruleset across server reboots, export the live configuration to /etc/nftables.conf:

sudo sh -c 'nft list ruleset > /etc/nftables.conf'

When updating rules in production, test syntax without applying changes using the -c check flag:

sudo nft -c -f /etc/nftables.conf

To apply complex updates atomically (guaranteeing that either all rules load or none do, preventing accidental remote lockouts):

sudo nft -f /etc/nftables.conf

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.