Understanding how Linux handles network packets at the kernel level can feel overwhelming — until you see how the pieces fit together. Netfilter provides the foundation, while nftables gives us a modern, flexible way to define firewall rules, NAT, and packet mangling.
Whether you’re debugging connectivity issues, writing security tools, or optimizing performance, knowing these internals helps you work more effectively with Linux networking.
Netfilter: The Kernel’s Packet Processing Framework
Netfilter is the Linux kernel’s packet filtering and mangling infrastructure. It defines well-known hook points where packets can be inspected and modified as they flow through the system:
- PREROUTING — Right after a packet arrives, before routing decisions
- INPUT — Packets destined for the local system
- FORWARD — Packets being routed through the host
- OUTPUT — Locally generated packets
- POSTROUTING — After routing, before leaving the host
Chains attached to these hooks let you enforce security policies, perform NAT, or influence routing.
nftables: The Modern Replacement for iptables
nftables brings a cleaner, more consistent syntax and better performance compared to the older iptables framework. It organizes configuration into tables, chains, rules, sets, and expressions.
Core nftables Building Blocks
Tables
Containers that group related chains, sets, and rules. Common families include ip (IPv4), ip6 (IPv6), and inet (both).
nft add table ip myfirewall
Chains
Sequences of rules. Base chains attach directly to Netfilter hooks and define behavior (filter, nat, route).
nft add chain ip myfirewall input { type filter hook input priority 0 \; }
Rules
Define matching conditions and actions (accept, drop, jump, etc.).
nft add rule ip myfirewall input tcp dport 22 accept
Sets
Efficient collections for matching (IP addresses, ports, etc.).
nft add set ip myfirewall trusted_ips { type ipv4_addr \; }
nft add element ip myfirewall trusted_ips { 192.168.1.10, 10.0.0.5 }
Practical Example: Simple Firewall
Here’s how to create a basic firewall that allows SSH from trusted IPs and drops everything else:
nft add table ip myfirewall
nft add chain ip myfirewall input { type filter hook input priority 0 \; }
nft add set ip myfirewall trusted_ips { type ipv4_addr \; }
nft add element ip myfirewall trusted_ips { 192.168.1.1, 192.168.1.2 }
nft add rule ip myfirewall input ip saddr @trusted_ips accept
nft add rule ip myfirewall input drop
Behind the Scenes: User Space to Kernel
Tools like nft use libmnl and libnftnl to communicate with the kernel via Netlink. This allows atomic batch operations — multiple changes applied together or not at all — ensuring consistent firewall state.
Best Practices for Production
- Use named sets for frequently updated lists (trusted IPs, blocked addresses)
- Keep base chains simple and explicit with a final drop rule
- Leverage priorities to control execution order
- Batch operations when making multiple changes
- Monitor and log dropped packets for visibility
Conclusion
Netfilter and nftables form a powerful, unified framework for packet processing in Linux. Understanding how tables, chains, rules, and sets work together helps you build more effective firewalls, troubleshoot network issues faster, and appreciate the elegance of the modern Linux networking stack.
Whether you’re securing servers, implementing complex NAT rules, or exploring kernel internals, nftables gives you the tools to control traffic with precision and clarity.