Andrew Mercer
on this page

What it is

Netfilter is the kernel framework that iptables, nftables, and ipvsadm all configure — a set of hook points in the network stack where userspace-defined rules can inspect, modify, drop, or redirect packets. It's the reason a Linux box can act as a stateful firewall, a NAT gateway, or a load balancer, all from the same underlying mechanism.

The five hook points

Netfilter exposes five points in the packet's journey through the stack:

  1. PREROUTING — before the routing decision (is this packet for us, or does it need forwarding?)
  2. INPUT — packets destined for this host
  3. FORWARD — packets being routed through this host to somewhere else
  4. OUTPUT — packets originating from this host
  5. POSTROUTING — after routing, just before leaving an interface

iptables' chain names map directly onto these hooks. This is why NAT (address rewriting) happens specifically at PREROUTING (DNAT, before the routing decision) and POSTROUTING (SNAT/MASQUERADE, after) — rewriting the destination has to happen before the kernel decides how to route the packet; rewriting the source has to happen after, once the outbound interface is known.

Connection tracking (conntrack)

Netfilter's stateful behavior comes from conntrack, which keeps a table of active connections and their state (NEW, ESTABLISHED, RELATED, INVALID). This is what lets a rule like:

iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

allow return traffic for a connection that was initiated from the inside, without needing an explicit rule for every possible reply. Inspect the table directly:

sudo conntrack -L                    # list tracked connections
sudo conntrack -L -p tcp             # filter by protocol
sudo cat /proc/net/nf_conntrack      # raw view, older kernels

iptables vs nftables

Modern distros (Debian 10+, RHEL 8+, Ubuntu 20.04+) run nftables as the actual kernel-facing engine, with iptables provided as a translation shim (iptables-nft) for compatibility with existing scripts and tools like firewalld. Check which backend is active:

sudo iptables --version    # "(nf_tables)" suffix means it's the nft shim

For day-to-day firewall work the iptables syntax covered in the iptables guide is still what you'll write and read most often, even on nftables-backed systems — but new, complex rulesets are increasingly written directly in native nft syntax for the performance and atomic-reload benefits.

Further reading