From 54e270d7fb68b41002654374d395e4f260a24add Mon Sep 17 00:00:00 2001 Message-Id: <54e270d7fb68b41002654374d395e4f260a24add@dist-git> From: Laine Stump Date: Mon, 15 Oct 2018 20:31:02 -0400 Subject: [PATCH] RHEL: network: regain guest network connectivity after firewalld switch to nftables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a DOWNSTREAM ONLY patch to temporarily get back guest network connectivity while still allowing the firewalld backend to use nftables (which is the default with RHEL8). The circumstances that cause the problem: In the past (when both libvirt and firewalld used iptables), if either libvirt's rules *OR* firewalld's rules accepted a packet, it would be accepted. But now firewalld uses nftables for its backend, while libvirt's firewall rules are still using iptables; iptables rules are still processed, but at a different time during packet processing than the firewalld nftables hooks. The result is that a packet must be accepted by *BOTH* the libvirt iptables rules *AND* the firewalld nftable rules in order to be accepted. This causes pain for two types of traffic: 1) libvirt always adds rules to permit DNS and DHCP (and sometimes TFTP) from guests to the host. But libvirt's bridges are in firewalld's "default" zone (which is usually the zone called "public"). The public zone allows ssh, but doesn't allow DNS, DHCP, or TFTP. So guests connected to libvirt's bridges can't acquire an IP address from DHCP, nor can they make DNS queries to the DNS server libvirt has setup on the host. 2) firewalld's higher level "rich rules" don't yet have the ability to configure the acceptance of forwarded traffic (traffic that is going somewhere beyond the host), so any traffic that needs to be forwarded is rejected. libvirt can't send "direct" nftables rules (firewalld only supports that for iptables), so we can't solve this problem by just sending direct nftables rules instead of iptables rules. However, we can take advantage of a quirk in firewalld zones that have a default policy of accept (meaning any packet that doesn't match a specific rule in the zone will be accepted) - this default accept will also accept forwarded traffic (not just traffic destined for the host). So, as a temporary solution to get all network traffic flowing, this patch creates a new firewalld zone called "libvirt" which is setup to include interfaces named virbr0-virbr9, and has a default policy of accept. With this zone installed, libvirt networks that use the names virbr0-virbr9 will have *all* their traffic accepted, both to the host and to/from the rest of the network. firewalld zones can't normally be added to the runtime config of firewalld, so we have to reload all of the permanent config for it to be recognized. This is done with a call to "firewall-cmd --reload" during postinstall and postuninstall. In the case that firewalld is inactive, firewall-cmd exits without doing anything (i.e. it doesn't start up firewalld.service if it's not already started). This obviously can't be a permanent solution, since it allows guests to have access to *all* services on the host. However, it doesn't allow QE and beta testers to test firewalld with an nftables backend (which is important for firewalld and nftables devs) without breaking network connectivity for libvirt managed virtual machines (so testing of those can also take place. Resolves: https://bugzilla.redhat.com/1638864 This problem is discussed in more detail in this message thread: https://post-office.corp.redhat.com/mailman/private/virt-devel/2018-September/msg00145.html https://post-office.corp.redhat.com/mailman/private/virt-devel/2018-October/msg00042.html and in the BZ assigned to firewalld: https://bugzilla.redhat.com/1623841 Signed-off-by: Laine Stump Acked-by: Daniel P. Berrangé Reviewed-by: Jiri Denemark --- libvirt.spec.in | 14 ++++++++++++++ src/network/Makefile.inc.am | 10 +++++++++- src/network/libvirt.zone | 15 +++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 src/network/libvirt.zone diff --git a/src/network/Makefile.inc.am b/src/network/Makefile.inc.am index 508c8c0422..20d899e699 100644 --- a/src/network/Makefile.inc.am +++ b/src/network/Makefile.inc.am @@ -87,6 +87,11 @@ install-data-network: ( cd $(DESTDIR)$(confdir)/qemu/networks/autostart && \ rm -f default.xml && \ $(LN_S) ../default.xml default.xml ) +if HAVE_FIREWALLD + $(MKDIR_P) "$(DESTDIR)$(prefix)/lib/firewalld/zones" + $(INSTALL_DATA) $(srcdir)/network/libvirt.zone \ + $(DESTDIR)$(prefix)/lib/firewalld/zones/libvirt.xml +endif HAVE_FIREWALLD uninstall-data-network: rm -f $(DESTDIR)$(confdir)/qemu/networks/autostart/default.xml @@ -95,10 +100,13 @@ uninstall-data-network: rmdir "$(DESTDIR)$(confdir)/qemu/networks" || : rmdir "$(DESTDIR)$(localstatedir)/lib/libvirt/network" ||: rmdir "$(DESTDIR)$(localstatedir)/run/libvirt/network" ||: +if HAVE_FIREWALLD + rm -f $(DESTDIR)$(prefix)/lib/firewalld/zones/libvirt.xml +endif HAVE_FIREWALLD endif WITH_NETWORK -EXTRA_DIST += network/default.xml +EXTRA_DIST += network/default.xml network/libvirt.zone .PHONY: \ install-data-network \ diff --git a/src/network/libvirt.zone b/src/network/libvirt.zone new file mode 100644 index 0000000000..355a70b4da --- /dev/null +++ b/src/network/libvirt.zone @@ -0,0 +1,15 @@ + + + libvirt + All network connections are accepted. This also permits packets to/from interfaces in the zone to be forwarded. This zone is intended to be used only by libvirt virtual networks. + + + + + + + + + + + -- 2.19.1