Comment 0 for bug 1968608

Revision history for this message
Jamie Strandboge (jdstrand) wrote : container/vm problems after upgrade when using iptables-nft

Filing this issue in the hopes that it will help people who are upgrading from a system that previously used xtables to one that is using netfilter.

ufw uses the 'iptables' suite of commands under the hood. As of iptables 1.8, iptables ships with two different backends for these commands:

* nft (netfilter)
* legacy (xtables)

such that there are iptables-nft, iptables-legacy, ip6tables-nft, ip6tables-legacy, etc commands on the system. Distributions may choose to then install symlinks from these commands to the traditional command. Eg, iptables will point to either iptables-nft or iptables-legacy. These symlinks can be configured by the admin on Debian/Ubuntu-based systems with:

$ sudo update-alternatives --config iptables # configures all the iptables* symlinks
$ sudo update-alternatives --config ip6tables # configures all the ip6tables* symlinks

ufw is fully compatible with either backend. The iptables-nft and nftables (ie, the 'nft' command not part of 'iptables'; will refer to this here as 'nftables' for clarity) both work with the kernel netfilter and different software on the system may freely use iptables-nft or nftables (eg, ufw using iptables-nft with other software (eg, libvirt) using nftables is fine). Since iptables-nft works well for ufw's requirements, there hasn't been a compelling reason to migrate ufw to use 'nftables' instead of 'iptables'.

While iptables-nft and nftables can be used together, you should NOT mix and match netfilter and xtables rules as the upstream kernel considers this undefined and the firewall may not work correctly. Before iptables 1.8, admins could not mix and match iptables and nftables (or software that used one or the other). With iptables 1.8, admins can choose to use iptables-legacy or nftables and/or iptables-nft.

Older releases of distributions (eg, Ubuntu 20.04 LTS) defaulted to iptables-legacy as the iptables backend with the admin able to opt into iptables-nft. Newer releases of distributions (eg, Ubuntu 22.04 LTS) are choosing to default to iptables-nft instead.

As mentioned, so long as all of the software on the system agrees on using either netfilter or xtables, everything should be fine. Use of the symlink mechanism (eg, the aforementioned 'update-alternatives' on Debian/Ubuntu) helps ensure everything works properly.

Software that manipulates the firewall outside of the configured symlinks (or using iptables-legacy/iptables 1.6 while nftables is also in use) might introduce problems if they are not aware of the xtables/netfilter incompatibility. Eg, this might happen with snaps that ship their own iptables or nftables and unconditionally use it without considering existing rules on the system.

The ufw snap will detect and use the correct backend for the system on startup. The lxd and multipass snaps will do the same. As such, eg, an Ubuntu 20.04 system that is configured with the default iptables-legacy backend can use the ufw deb from Ubuntu with the lxd and multipass snaps without issue (ufw follows the iptables symlink to use the legacy (xtables) backend to load firewall rules in early boot. When lxd and multipass are started, they see that legacy rules are in use and use xtables). Similarly, on an Ubuntu 22.04 system that is configured with the default iptables-nft backend, the ufw deb from Ubuntu will follow the iptables symlink to use the nft (netfilter) backend to load firewall rules in early boot. When lxd and multipass are started, the see that nft rules are in use and use netfilter.

Users upgrading from earlier distributions that defaulted to the legacy backend to newer releases that use the nft backend may find that non-distro software isn't choosing the correct backend. You can see if this is the case by running:

$ sudo iptables-nft -S

and compare with:

$ sudo iptables-legacy -S

If one is populated and the other comes back with only:

then everything should be operating together ok. You should also check ip6tables-nft vs ip6tables-legacy and if you have 'nft' on your system, see that 'sudo nft list ruleset' has only accept rules if 'iptables-legacy -S' shows rules are in use.

If there is a mixture of rules in both backends, you'll need to make everything use either netfilter or xtables. If things were working correctly before the upgrade, you might find that going back to iptables-legacy could make things work until you're ready to migrate to iptables-nft (on Debian/Ubuntu, see update-alternatives, above).

The 'docker' snap as of 20.10.12 in the stable channel is known to unconditionally use xtables. At the time of this filing, it did not have a way to adjust to using netfilter, so if using the docker snap, you might have to update your system to use iptables-legacy (on Debian/Ubuntu, see update-alternatives, above).

Finally, if using various container/VM software with ufw on the host and everything agrees on using the same backend, you might check that the ufw ruleset has everything it needs. Eg, simple rules to allow the container/VM to work with the host for libvirt, lxd and multipass might be:

$ sudo ufw allow in on virbr0 comment 'libvirt default network'
$ sudo ufw allow in on mpqemubr0 comment 'multipass' # not typically needed
$ sudo ufw allow in on lxd0 comment 'lxd default interface'

Other rules are of course possible. Eg, to allow lxd containers to the outside
$ sudo ufw route allow in on lxd0 comment 'lxd to outside'

Or being more specific with the rules:
$ sudo ufw allow in on lxd0 to any port 67 proto udp comment 'lxd dhcp'
$ sudo ufw allow in on lxd0 to any port 53 comment 'lxd dns'
$ sudo ufw allow in on lxd0 to any port 5355 'lxd resolved'
$ sudo ufw route allow in on lxd0 out on ... to any port 443 'lxd https'

As always, while debugging look for kernel messages (eg, 'journalctl -k
--follow', /var/log/kern.log, /var/log/ufw.log, 'dmesg', etc). Remember:
* filter rules (ufw allow|deny|reject) are separate from route rules (ufw route allow|deny|reject)
* first rule that matches wins
* the default loglevel in ufw is 'low', which "logs all blocked packages not matching the default policy (with rate limiting) as well as packets matching logged rules". This means that all 'allow', 'deny' and 'reject' rules are NOT logged unless you specified 'log' or 'log-all' in the rule. See 'man ufw' for details