I rewrote the firewall on my main box in nftables this weekend, and the headline is that the whole thing now lives in one readable file instead of a shell script full of iptables -A lines I'd stopped understanding years ago.
The migration tool gets you started. iptables-translate will convert a single rule, and iptables-restore-translate will chew through a whole iptables-save dump. The output is correct but verbose, so I treated it as a first draft rather than the finished article.
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
iif "lo" accept
tcp dport { 22, 443 } accept
}
}
What sold me was the inet family. One table covers IPv4 and IPv6 together, so I stopped maintaining two parallel rulesets that inevitably drifted. Sets and { 22, 443 } syntax mean adding a port is a one-character change, not a new rule. The whole config is now version-controlled and survives a reboot through nftables.service. No more wondering which interface a stray rule applied to. Should have done this years ago, of course.