From Fedora Project Wiki

Libvirt Virtual Network NFTables

Summary

The default firewall backend for the default libvirt virtual network (the virbr0 bridge device), will change from 'iptables' to 'nftables'.

Owner

Current status

Detailed Description

A default installation of libvirt will create an isolated bridge device (virbr0), to which guest virtual machines can have their NIC connected. Firewall rules are used to provide NAT based connectivity on this bridge device, as well as allow access to the DNS/DHCP services provided by the dnsmasq it launches on the host.

Historically libvirt has always used the iptables tools, which first talked to the iptables kernel modules, but in recent Fedora uses the nftables kernel modules. When Fedora switched Firewalld to use nftables for its own firewall rules, libvirt kept using its iptables userspace backend, which then indirectly created kernel nftables rules. To work correctly, libvirt added the ability to associate its bridge devices with a 'libvirt' zone in firewall to ensure guest->host DHCP/DNS/SSH traffic was not blocked by firewall.

With this change, libvirt will now prefer to directly use the nftables userspace tools to create its firewall rules, where they are installed:

  • nftables only installed => libvirt uses its nftables backend
  • iptables only intsalled => libvirt uses its iptables backend
  • nftables and iptables installed => libvirt uses its nftables backend

This default behaviour can be overridden to force a specific backend by editting settings in /etc/libvirt/network.conf.

Note that this change only applies to libvirt's virtual network functionality. Libvirt's nwfilter (network filter) functionality is still exclusively using iptables/ebtables. This will be switched to nftables in a future Fedora release, timeframe to be determined.

Feedback

TBD

Benefit to Fedora

  • Libvirt will be using the same recommended modern nftables userspace as firewalld instead of the legacy iptables compatibility tools which secretly talk to nftables behind the scenes.
  • All the libvirt nftables rules will be self-contained in a dedicated 'libvirt_network' nftables table, reducing the scope for other applications accidentally changing/removing them.
  • Improved performance scalability since libvirt's nftables rules are written to use an interface ID match which is a simple lookup, while traditional string based interface name matches in iptables require multiple string comparisons.

Scope

  • Proposal owners: Change the libvirt RPM spec to set the 'nftables' backend as the preferred default
  • Other developers: N/A
  • Release engineering: N/A
  • Policies and guidelines: N/A
  • Trademark approval: N/A
  • Alignment with the Fedora Strategy:

Upgrade/compatibility impact

Existing hosts with libvirt deployed will be using iptables for their firewall rules. When the Fedora upgrade brings in the new libvirt, it will detect the switch to nftables and attempt to remove the historically created iptables rules, and create new nftables rules providing equivalent functionality.

A number of iptables chains will remain present after an upgrade

  • Chain LIBVIRT_FWI
  • Chain LIBVIRT_FWO
  • Chain LIBVIRT_FWX
  • Chain LIBVIRT_INP
  • Chain LIBVIRT_OUT

These chains should not contain rules and thus be harmless. They will go away permanently the next time the host is rebooted, or can be deleted manually if desired.

Reverting to iptables for compatibility

If an incompatibility is discovered between libvirt's nftables backend and some other use case, it is possible to tell libvirt to revert to its iptables backend.

  • Edit /etc/libvirt/network.conf and set 'firewall_backend = "iptables"'
  • systemctl restart virtnetworkd

Libvirt should then automatically delete its nftables rules and create equivalent iptables rules as present on previous Fedora releases.

Alternatively, if the 'nftables' userspace tools are not installed at all, libvirt will attempt to use the 'iptables' userspace tools instead, if present.

Known issue: docker

The Docker iptables integration force changes the iptables FORWARD chain policy from ACCEPT to DENY. This makes Docker incompatible with any application that is using nftables to try to allow forwarding:

https://docs.docker.com/network/packet-filtering-firewalls/#docker-on-a-router

When libvirt uses its iptables backend, its FORWARD rules will end up in the same table as docker's, and so override the DENY policy docker had created. When libvirt uses its nftables backend, its FORWARD rules end up in a separate table from dockers'. Since nftables requires a packet to be allowed by *all* top level tables, docker's DENY rules will block the libvirt traffic.

The possible workarounds are:

  • Reconfigure libvirt to use iptables when compatibility with docker is required
  • Use podman instead of docker, since podman does not create problematic iptables rules
  • TBD: whether libvirt can do something automagic to workaround docker's DENY policy

Known issue: non-firewalld firewall mgmt tools

Libvirt requires the ability to mark traffic from the guest to the host, for DHCP and DNS as permitted.

When using iptables kernel modules, libvirt could achieve this by inserting some rules in the INPUT chain to allow DHCP/DNS.

When using nftables kernel modules, there are an arbitrary number of application defined top level tables with unknown names. All top level tables must allow a packet in order for it to pass. libvirt must not touch tables created by other applications, thus it is no longer practical to seemlessly allow DHCP & DNS when nftables userspace is used by any component on the system.

To address this, when Fedora 32 switched firewall to its nftables backend, libvirt gained ability to install a firewalld zone files to allow guest traffic. Libvirt does not have equivalent integration for any other nftables based firewall mgmt tool, but other tools using iptables remained compatible as long as libvirt also kept using iptables.

With libvirt changing to prefer its nftables backend, libvirt is will be incompatible with any other non-firewalld firewall management tools.

The compatibility matrix is as follows

  1. Kernel module: iptables, firewall mgmt userspace: iptables, libvirt backend: iptables => WORKS for all firewall mgmt tools
  2. Kernel module: nftables, firewall mgmt userspace: iptables, libvirt backend: iptables => WORKS for all firewall mgmt tools
  3. Kernel module: nftables, firewall mgmt userspace: iptables, libvirt backend: nftables => WORKS for firewalld, other tools require workaround
  4. Kernel module: nftables, firewall mgmt userspace: nftables, libvirt backend: iptables => WORKS for firewalld, other tools require workaround
  5. Kernel module: nftables, firewall mgmt userspace: nftables, libvirt backend: nftables => WORKS for firewalld, other tools require workaround

The two main workaround options:

  • Change /etc/libvirt/network.conf 'firewall_backend' setting to 'iptables'
  • Manually add rules to the firewall mgmt tool to allow DHCP, DNS & SSH from guests.

The long term answer is to enhance libvirt upstream to natively learn about integration for more firewall mgmt tools than just firewalld. eg UFW: https://gitlab.com/libvirt/libvirt/-/issues/644

Early Testing (Optional)

Do you require 'QA Blueprint' support? N

How To Test

  • Perform a default libvirt KVM install 'dnf groupinstall @Virtualization'
  • Create a KVM guest using virt-install, virt-manager, or cockpit, and configure it to use the 'default' virtual network
  • Boot the KVM guest
  • Login to the KVM guest graphical console, and attempt to connect to the internet. eg curl https://google.com
  • Configure the KVM guest to enable SSH (if not already allowed & started)
  • Attempt to SSH to the guest from the host

User Experience

  • Libvirt firewall rules will no longer be present when running 'iptables -L'
  • A new 'libvirt_network' table will be present when running 'nft list ruleset'

Dependencies

None

Contingency Plan

  • Contingency mechanism: Libvirt maintainers to change the libvirt.spec to set 'prefer_nftables' variable to '0' for Fedora 41
  • Contingency deadline: Final freeze
  • Blocks release? No

Documentation

General libvirt network documentation at https://libvirt.org/formatnetwork.html

Release Notes

The libvirt virtual network has been changed to prefer use of the nftables firewall backend instead of iptables.