From iptables to nftables: a practical migration
Translate your ruleset to nftables' cleaner syntax and sets, and run both during the cutover without lockouts.
For years, iptables was the Linux firewall userspace front end most admins knew. Modern kernels prefer nftables — one nft binary, consistent syntax, native sets and maps, and no translation layer between ipv4 and ipv6 rules. Distros ship iptables-nft shims so old scripts keep working, but new rules should be written in nftables native syntax so you are not debugging double indirection at 2am.
Cloud security groups remain the primary edge control for VMs — host nftables is defense in depth when an SG is misconfigured or for bare-metal without a hypervisor envelope. Treat host firewall as compensating control, not the only gate.
This note translates a classic iptables ruleset to nftables, runs both during cutover on a test host, and shows persistence with nft list ruleset > /etc/nftables.conf. For host hardening context see Linux hardening; for detecting blocked scans and firewall changes, Linux detection engineering.
Work on a host with console access. Flush test rules before applying default-drop. Keep ssh allow rule first in every iteration.
Translate a simple allowlist
iptables -m set --match-set becomes an nftables set with automatic element updates. Inline ip lists in iptables explode into unmaintainable one-liners; nftables set blocks are readable and fast.
Use meta nftrace set 1 or nflog groups sparingly for dropped-packet debugging — send copies to userspace loggers without printf-in-chain hacks. Document chain priorities (priority filter - 10) when Docker or Kubernetes inserts their own tables so your drop policy still runs where you expect.
#!/usr/sbin/nft -fflush rulesettable inet filter {set admin_ips {type ipv4_addrelements = { 203.0.113.10, 203.0.113.11 }}chain input {type filter hook input priority 0; policy drop;ct state established,related acceptiif lo accepttcp dport 22 ip saddr @admin_ips accepttcp dport { 80, 443 } accept}}
Old iptables equivalent
The iptables version used separate iptables and ip6tables invocations, -A INPUT append order mattered, and ipsets required a second tool. nftables inet table handles both address families in one file.
During migration, iptables-nft-save can dump translated rules for comparison. Run both stacks in audit mode if your distro supports it — log what legacy would drop vs what nft drops — before decommissioning iptables-legacy services.
# Fragile — order-dependent, ipv4-onlyiptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPTiptables -A INPUT -i lo -j ACCEPTiptables -A INPUT -p tcp -s 203.0.113.10 --dport 22 -j ACCEPTiptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPTiptables -P INPUT DROP
nft -c -f /etc/nftables.confsyntax check passednft -f /etc/nftables.confnft list ruleset | head -20ss -tlnp | grep :22ssh still listening — test login before closing sessionWhere this goes next
Host firewall is one layer — pair with cloud security groups, SSH hardening, and centralized logging of dropped packets via nflog or audit. Linux hardening covers SSH and systemd; Linux detection engineering shows how to alert on nft rule changes and port scan patterns in logs.
Outbound filtering matters for compromised workloads — a chain output policy drop with exceptions for DNS and NTP limits C2 exfiltration. Document emergency break-glass rules that allow your admin IP before any mass rollout.