|
|
edecca |
From 8cc240a1652a465727d5b66d9fb6a5fa71656dba Mon Sep 17 00:00:00 2001
|
|
|
edecca |
Message-Id: <8cc240a1652a465727d5b66d9fb6a5fa71656dba@dist-git>
|
|
|
edecca |
From: Laine Stump <laine@redhat.com>
|
|
|
edecca |
Date: Fri, 1 Feb 2019 20:29:31 -0500
|
|
|
edecca |
Subject: [PATCH] network: set firewalld zone of bridges to "libvirt" zone when
|
|
|
edecca |
appropriate
|
|
|
edecca |
MIME-Version: 1.0
|
|
|
edecca |
Content-Type: text/plain; charset=UTF-8
|
|
|
edecca |
Content-Transfer-Encoding: 8bit
|
|
|
edecca |
|
|
|
edecca |
This patch restores broken guest network connectivity after a host
|
|
|
edecca |
firewalld is switched to using an nftables backend. It does this by
|
|
|
edecca |
adding libvirt networks' bridge interfaces to the new "libvirt" zone
|
|
|
edecca |
in firewalld.
|
|
|
edecca |
|
|
|
edecca |
After this patch, the bridge interface of any network created by
|
|
|
edecca |
libvirt (when firewalld is active) will be added to the firewalld
|
|
|
edecca |
zone called "libvirt" if it exists (regardless of the firewalld
|
|
|
edecca |
backend setting). This behavior does *not* depend on whether or not
|
|
|
edecca |
libvirt has installed the libvirt zone file (set with
|
|
|
edecca |
"--with[out]-firewalld-zone" during the configure phase of the package
|
|
|
edecca |
build).
|
|
|
edecca |
|
|
|
edecca |
If the libvirt zone doesn't exist (either because the package was
|
|
|
edecca |
configured to not install it, or possibly it was installed, but
|
|
|
edecca |
firewalld doesn't support rule priorities, resulting in a parse
|
|
|
edecca |
error), the bridge will remain in firewalld's default zone, which
|
|
|
edecca |
could be innocuous (in the case that the firewalld backend is
|
|
|
edecca |
iptables, guest networking will still function properly with the
|
|
|
edecca |
bridge in the default zone), or it could be disastrous (if the
|
|
|
edecca |
firewalld backend is nftables, we can be assured that guest networking
|
|
|
edecca |
will fail). In order to be unobtrusive in the former case, and
|
|
|
edecca |
informative in the latter, when the libvirt zone doesn't exist we
|
|
|
edecca |
then check the firewalld version to see if it's new enough to support
|
|
|
edecca |
the nftables backend, and then if the backend is actually set to
|
|
|
edecca |
nftables, before logging an error (and failing the net-start
|
|
|
edecca |
operation, since the network couldn't possibly work anyway).
|
|
|
edecca |
|
|
|
edecca |
When the libvirt zone is used, network behavior is *slightly*
|
|
|
edecca |
different from behavior of previous libvirt. In the past, libvirt
|
|
|
edecca |
network behavior would be affected by the configuration of firewalld's
|
|
|
edecca |
default zone (usually "public"), but now it is affected only by the
|
|
|
edecca |
"libvirt" zone), and thus almost surely warrants a release note for
|
|
|
edecca |
any distro upgrading to libvirt 5.1 or above. Although it's
|
|
|
edecca |
unfortunate that we have to deal with a mandatory behavior change, the
|
|
|
edecca |
architecture of multiple hooks makes it impossible to *not* change
|
|
|
edecca |
behavior in some way, and the new behavior is arguably better (since
|
|
|
edecca |
it will now be possible to manage access to the host from virtual
|
|
|
edecca |
machines vs from public interfaces separately).
|
|
|
edecca |
|
|
|
edecca |
Creates-and-Resolves: https://bugzilla.redhat.com/1650320
|
|
|
edecca |
Resolves: https://bugzilla.redhat.com/1638342
|
|
|
edecca |
Signed-off-by: Laine Stump <laine@laine.org>
|
|
|
edecca |
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
|
|
edecca |
(cherry picked from commit ae05211a360077f56883cd0a6c0f82ed57f746cb)
|
|
|
edecca |
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
|
|
edecca |
---
|
|
|
edecca |
docs/firewall.html.in | 33 +++++++++++++++++++++
|
|
|
edecca |
src/network/bridge_driver_linux.c | 48 +++++++++++++++++++++++++++++++
|
|
|
edecca |
2 files changed, 81 insertions(+)
|
|
|
edecca |
|
|
|
edecca |
diff --git a/docs/firewall.html.in b/docs/firewall.html.in
|
|
|
edecca |
index 0a50687c26..5d584e582e 100644
|
|
|
edecca |
--- a/docs/firewall.html.in
|
|
|
edecca |
+++ b/docs/firewall.html.in
|
|
|
edecca |
@@ -129,6 +129,39 @@ MASQUERADE all -- * * 192.168.122.0/24 !192.168.122.0/24
|
|
|
edecca |
|
|
|
edecca |
|
|
|
edecca |
|
|
|
edecca |
+
|
|
|
edecca |
+
|
|
|
edecca |
+
|
|
|
edecca |
+ If firewalld is active on
|
|
|
edecca |
+ the host, libvirt will attempt to place the bridge interface of
|
|
|
edecca |
+ a libvirt virtual network into the firewalld zone named
|
|
|
edecca |
+ "libvirt" (thus making all guest->host traffic on that network
|
|
|
edecca |
+ subject to the rules of the "libvirt" zone). This is done
|
|
|
edecca |
+ because, if firewalld is using its nftables backend (available
|
|
|
edecca |
+ since firewalld 0.6.0) the default firewalld zone (which would
|
|
|
edecca |
+ be used if libvirt didn't explicitly set the zone) prevents
|
|
|
edecca |
+ forwarding traffic from guests through the bridge, as well as
|
|
|
edecca |
+ preventing DHCP, DNS, and most other traffic from guests to
|
|
|
edecca |
+ host. The zone named "libvirt" is installed into the firewalld
|
|
|
edecca |
+ configuration by libvirt (not by firewalld), and allows
|
|
|
edecca |
+ forwarded traffic through the bridge as well as DHCP, DNS, TFTP,
|
|
|
edecca |
+ and SSH traffic to the host - depending on firewalld's backend
|
|
|
edecca |
+ this will be implemented via either iptables or nftables
|
|
|
edecca |
+ rules. libvirt's own rules outlined above will *always* be
|
|
|
edecca |
+ iptables rules regardless of which backend is in use by
|
|
|
edecca |
+ firewalld.
|
|
|
edecca |
+
|
|
|
edecca |
+
|
|
|
edecca |
+ NB: Prior to libvirt 5.1.0, the firewalld "libvirt" zone did not
|
|
|
edecca |
+ exist, and prior to firewalld 0.7.0 a feature crucial to making
|
|
|
edecca |
+ the "libvirt" zone operate properly (rich rule priority
|
|
|
edecca |
+ settings) was not implemented in firewalld. In cases where one
|
|
|
edecca |
+ or the other of the two packages is missing the necessary
|
|
|
edecca |
+ functionality, it's still possible to have functional guest
|
|
|
edecca |
+ networking by setting the firewalld backend to "iptables" (in
|
|
|
edecca |
+ firewalld prior to 0.6.0, this was the only backend available).
|
|
|
edecca |
+
|
|
|
edecca |
+
|
|
|
edecca |
|
|
|
edecca |
|
|
|
edecca |
This driver provides a fully configurable network filtering capability
|
|
|
edecca |
diff --git a/src/network/bridge_driver_linux.c b/src/network/bridge_driver_linux.c
|
|
|
edecca |
index 3effcdce22..823d5a9742 100644
|
|
|
edecca |
--- a/src/network/bridge_driver_linux.c
|
|
|
edecca |
+++ b/src/network/bridge_driver_linux.c
|
|
|
edecca |
@@ -29,6 +29,7 @@
|
|
|
edecca |
#include "virstring.h"
|
|
|
edecca |
#include "virlog.h"
|
|
|
edecca |
#include "virfirewall.h"
|
|
|
edecca |
+#include "virfirewalld.h"
|
|
|
edecca |
|
|
|
edecca |
#define VIR_FROM_THIS VIR_FROM_NONE
|
|
|
edecca |
|
|
|
edecca |
@@ -641,6 +642,53 @@ int networkAddFirewallRules(virNetworkDefPtr def)
|
|
|
edecca |
virFirewallPtr fw = NULL;
|
|
|
edecca |
int ret = -1;
|
|
|
edecca |
|
|
|
edecca |
+ /* if firewalld is active, try to set the "libvirt" zone. This is
|
|
|
edecca |
+ * desirable (for consistency) if firewalld is using the iptables
|
|
|
edecca |
+ * backend, but is necessary (for basic network connectivity) if
|
|
|
edecca |
+ * firewalld is using the nftables backend
|
|
|
edecca |
+ */
|
|
|
edecca |
+ if (virFirewallDIsRegistered() == 0) {
|
|
|
edecca |
+
|
|
|
edecca |
+ /* if the "libvirt" zone exists, then set it. If not, and
|
|
|
edecca |
+ * if firewalld is using the nftables backend, then we
|
|
|
edecca |
+ * need to log an error because the combination of
|
|
|
edecca |
+ * nftables + default zone means that traffic cannot be
|
|
|
edecca |
+ * forwarded (and even DHCP and DNS from guest to host
|
|
|
edecca |
+ * will probably no be permitted by the default zone
|
|
|
edecca |
+ */
|
|
|
edecca |
+ if (virFirewallDZoneExists("libvirt")) {
|
|
|
edecca |
+ if (virFirewallDInterfaceSetZone(def->bridge, "libvirt") < 0)
|
|
|
edecca |
+ goto cleanup;
|
|
|
edecca |
+ } else {
|
|
|
edecca |
+ unsigned long version;
|
|
|
edecca |
+ int vresult = virFirewallDGetVersion(&version);
|
|
|
edecca |
+
|
|
|
edecca |
+ if (vresult < 0)
|
|
|
edecca |
+ goto cleanup;
|
|
|
edecca |
+
|
|
|
edecca |
+ /* Support for nftables backend was added in firewalld
|
|
|
edecca |
+ * 0.6.0. Support for rule priorities (required by the
|
|
|
edecca |
+ * 'libvirt' zone, which should be installed by a
|
|
|
edecca |
+ * libvirt package, *not* by firewalld) was not added
|
|
|
edecca |
+ * until firewalld 0.7.0 (unless it was backported).
|
|
|
edecca |
+ */
|
|
|
edecca |
+ if (version >= 6000 &&
|
|
|
edecca |
+ virFirewallDGetBackend() == VIR_FIREWALLD_BACKEND_NFTABLES) {
|
|
|
edecca |
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
|
edecca |
+ _("firewalld is set to use the nftables "
|
|
|
edecca |
+ "backend, but the required firewalld "
|
|
|
edecca |
+ "'libvirt' zone is missing. Either set "
|
|
|
edecca |
+ "the firewalld backend to 'iptables', or "
|
|
|
edecca |
+ "ensure that firewalld has a 'libvirt' "
|
|
|
edecca |
+ "zone by upgrading firewalld to a "
|
|
|
edecca |
+ "version supporting rule priorities "
|
|
|
edecca |
+ "(0.7.0+) and/or rebuilding "
|
|
|
edecca |
+ "libvirt with --with-firewalld-zone"));
|
|
|
edecca |
+ goto cleanup;
|
|
|
edecca |
+ }
|
|
|
edecca |
+ }
|
|
|
edecca |
+ }
|
|
|
edecca |
+
|
|
|
edecca |
fw = virFirewallNew();
|
|
|
edecca |
|
|
|
edecca |
virFirewallStartTransaction(fw, 0);
|
|
|
edecca |
--
|
|
|
edecca |
2.20.1
|
|
|
edecca |
|