Blame SOURCES/libvirt-RHEL-network-regain-guest-network-connectivity-after-firewalld-switch-to-nftables.patch

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