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

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