It's 2022: nftables kind of integrates now

🕒 2 minutes

This is a follow up to the It’s 2021: nftables still does not integrate.

The good: What works compared to 2021?

Pretty much everything is still revolving around the iptables-nft compatibility layer, but it has improved a lot so things seem to work just fine now.

libvirt

Everything works. Seems to implicitly use compatibility layer very likely (assuming from libvirt Network Filters).

Docker

Everything works out of the box, without having to write own rules or handle wiring with own Docker event handler. Implicitly uses compatibility layer.

CNI firewall plugin

Also uses compatibility layer. This was worth mentioning because podman, Kubernetes, containerd etc. rely on CNI.

The bad

Scripting/firewall management by shelling out to iptables

Pretty much all open & popular solutions mentioning firewall management on Linux simply shell out to iptables commands.

I’ve seen one edge case with iptables-nft - if you try to list rules in nonexistent chain, it fails with unrelated error:

$ iptables-nft -t filter -X SWDFW-INPUT || true
$ iptables-nft -t filter -S SWDFW-INPUT 1
iptables v1.8.8 (nf_tables): chain `SWDFW-INPUT' in table `filter' is incompatible, use 'nft' tool.

coreos/go-iptables ChainExists is using -S <chain> 1 to report whether chain exists.

Alternative would be doing something similar to this:

nft --json --stateless --terse list ruleset | jq --arg table "filter" --arg chain "SWDFW-INPUT" -e -r '.nftables[] | select(.chain and .chain.table == $table and .chain.name == $chain) | "ok"'

…however not all systems have nftables installed next to iptables-nft (NixOS - there are nftables and iptables-nftables-compat packages).

The ugly

Translation layer makes use of iptables kernel modules in the background

Throw following into /etc/modprobe.d/blacklist-iptables.conf & reboot:

install ip_tables /bin/true
install ip6_tables /bin/true

And try following rules:

ip6tables -A INPUT -p icmpv6 --icmpv6-type redirect -j DROP
ip6tables -A INPUT -p icmpv6 --icmpv6-type 139 -j DROP

Get Extension icmpv6 revision 0 not supported, missing kernel module?, why?

modinfo ip6_tables shows alias: ip6t_icmp6, loading it gets it working, therefore icmpv6 filtering is provided by that, even though nftables support icmp natively…

Legacy iptables is using /proc/net/ip_tables_names for table names, but that’s unsurprisingly empty on a system which doesn’t use legacy framework.

Future

RHEL 9 deprecated ipset & iptables-nft
OpenWRT 22.03.0 is using nftables for its firewall management. It’s doing rule templating instead of using JSON though.

I hope legacy iptables and its compatibility layer is going to be replaced on other distributions as well in next following years.

Until then, enjoy iptables and its compatibility cruft.