Skip to content
CloudOps
Newsletter
All guides
AI for Linux Admins By James Joyner IV · · 9 min read

Migrating from iptables to nftables: A Practical Firewall Guide

iptables is on its way out and nftables is the replacement. Here's how I migrate real firewalls without locking myself out or dropping traffic.

  • #linux
  • #nftables
  • #iptables
  • #firewall
  • #networking
  • #security

I have written more iptables rules than I care to count, and I will not miss the syntax. It worked, but it was a pile of separate tools (iptables, ip6tables, arptables, ebtables), a confusing chain/table model, and rule files that nobody could read six months later. nftables replaces all of it with one tool, one syntax, and a rule format that actually looks like the policy you meant to write.

Most distros already route the legacy iptables command through the nft backend, so you may be using nftables without knowing it. But to get the real benefits — sets, maps, one ruleset for v4 and v6 — you want native nft rules. Here’s how I migrate without cutting my own SSH session.

The model in one paragraph

nftables has tables (containers, scoped to a family like inet, ip, ip6), which hold chains (attached to hooks like input, forward, output), which hold rules. The big win is the inet family: one table handles both IPv4 and IPv6, so you stop maintaining two parallel rulesets. Chains have a policy (the default action) and a priority (ordering relative to other chains on the same hook).

Translate your existing rules first

Don’t hand-rewrite. There’s a converter:

# Dump current iptables rules to a file
sudo iptables-save > /tmp/rules.v4
# Translate to nft syntax
iptables-restore-translate -f /tmp/rules.v4 > /tmp/ruleset.nft

Read the output — it’s a faithful translation, but it’s mechanical, not idiomatic. You’ll usually clean it up into something tighter. Still, it’s the fastest way to see your real policy in the new syntax.

A clean starting ruleset

Here’s a minimal, readable /etc/nftables.conf for a typical server — SSH, HTTP/HTTPS, ICMP, and established traffic:

#!/usr/sbin/nft -f
flush ruleset

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

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

        ip protocol icmp accept
        ip6 nexthdr ipv6-icmp accept

        tcp dport 22 accept
        tcp dport { 80, 443 } accept
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }
}

Note tcp dport { 80, 443 } — an anonymous set in one rule instead of two. That readability compounds fast on a real firewall.

Don’t lock yourself out

This is the rule that has saved me more than once. Before you apply a policy drop ruleset over SSH, set a dead-man’s switch:

# Apply the new ruleset, but schedule a rollback in 2 minutes
sudo sh -c 'nft -f /etc/nftables.conf; sleep 120 && nft flush ruleset' &

If your SSH session survives, you cancel the rollback (kill the background job) and persist for real. If you locked yourself out, the flush fires in two minutes and you get back in. I have never regretted doing this; I have absolutely regretted skipping it.

Then make it permanent:

sudo systemctl enable --now nftables
sudo nft list ruleset > /etc/nftables.conf   # snapshot the live state

Sets and maps: the actual reason to switch

Anonymous sets are nice, but named sets are where nftables earns its keep. A blocklist that updates without rewriting rules:

table inet filter {
    set blocklist {
        type ipv4_addr
        flags timeout
    }
    chain input {
        type filter hook input priority 0; policy drop;
        ip saddr @blocklist drop
        ct state established,related accept
        tcp dport 22 accept
    }
}

Now adding a bad actor is a data operation, not a rule edit:

sudo nft add element inet filter blocklist '{ 203.0.113.7 timeout 1h }'

The timeout flag auto-expires the entry. You can wire this to fail2ban-style automation and never touch the chain again. Maps go further — map a destination port to a verdict, or do destination NAT with a single map lookup instead of a rule per port.

Verifying and debugging

sudo nft list ruleset                 # the whole policy, human-readable
sudo nft list table inet filter       # one table
sudo nft -a list ruleset              # with handles, needed for deleting rules

To watch a rule actually match, add a counter:

tcp dport 22 counter accept

Then nft list ruleset shows packet and byte counts per rule — far easier than tcpdump for “is this rule even being hit?”

Where AI saves time

The translation from “what I want” to nft syntax is the slow part, especially for NAT and the set/map features. I describe the intent — “rate-limit new SSH connections to 10 per minute per source IP” — and ask a model for the nft rule, then read it carefully before applying. The syntax is regular enough that models do well here, but a firewall is exactly the place you verify every line. Keep a few Linux firewall prompts handy for the common patterns.

Migration checklist

  • Translate existing rules with iptables-restore-translate to see your real policy.
  • Rewrite into idiomatic inet rules with named sets where it helps.
  • Apply with a dead-man’s-switch rollback so you can’t lock yourself out.
  • Add counters to rules you’re unsure about and watch them match.
  • systemctl enable nftables and snapshot the live ruleset to disk.

The payoff is one tool, one ruleset for both IP versions, and dynamic sets that turn firewall changes into data updates. After the first clean migration you won’t want to go back.

Firewall changes can sever remote access. Always apply drop policies behind a timed rollback and verify your management path before persisting.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.