Devops

iptables vs nftables

ยท2 min read

The Linux kernel had a firewall called iptables for nearly twenty years. Since around 2014 the kernel has shipped nftables, which is meant to replace it. Most distributions now default to nftables; iptables still works through a compatibility layer. Knowing both pays off any time you touch a non-trivial firewall.

The same mental model

Both tools work on the same kernel netfilter framework. Packets traverse chains at specific hook points (PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING). Chains contain rules; rules match on packet attributes and have an action (accept, drop, reject, jump to another chain). Chains are grouped into tables (filter, nat, mangle, raw).

iptables: the classic syntax

# Default policy
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Always allow loopback and established
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# SSH
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT

# HTTP/S
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT

# Persist
iptables-save > /etc/iptables/rules.v4

nftables: the modern equivalent

# /etc/nftables.conf
flush ruleset

table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;

        iif lo accept
        ct state established,related accept
        ct state invalid drop

        tcp dport 22  ct state new accept comment "ssh"
        tcp dport {80, 443} accept    comment "web"

        icmp type echo-request limit rate 5/second accept
        ip6 nexthdr icmpv6 limit rate 5/second accept
    }
    chain forward { type filter hook forward priority 0; policy drop; }
    chain output  { type filter hook output  priority 0; policy accept; }
}
nft -f /etc/nftables.conf
nft list ruleset
systemctl enable --now nftables

Why nftables is better

  • One tool for IPv4, IPv6, ARP, and bridge filtering โ€” the inet family covers v4 and v6 simultaneously.
  • Sets and maps as first-class values: tcp dport @allowed_ports is far faster than dozens of individual rules.
  • Atomic ruleset replacement โ€” apply a new ruleset in one syscall instead of accumulating rule changes.
  • Cleaner syntax โ€” no more -m multiport --dports.

Migration paths

  • Stay on iptables: most distros ship iptables-nft, which speaks iptables syntax but writes nftables rules under the hood. Your old scripts still work.
  • Translate: iptables-translate converts an iptables rule to its nftables equivalent. iptables-restore-translate does the same for a saved ruleset.
  • Rewrite: for non-trivial firewalls, the cleanest path is rewriting in nftables. Easier to maintain afterwards.

Higher-level wrappers

For desktop and single-server use, you may not need either directly. ufw (Debian/Ubuntu) and firewalld (RHEL/Fedora) are friendlier frontends that compile to the underlying tool.

ufw default deny incoming
ufw allow ssh
ufw allow 80,443/tcp
ufw enable

Related