6c915788a6
- Revert "network: *un*set the firewalld zone while shutting down a network" (RHEL-61752) - Revert "network: support setting firewalld zone for bridge device of open networks" (RHEL-61752) - network: call network(Add|Remove)FirewallRules() for forward mode='open' (RHEL-61752) - network: a different way of supporting firewalld zone for mode='open' networks (RHEL-61752) - network: a different implementation of *un*setting firewalld zone when network is destroyed (RHEL-61752) Resolves: RHEL-61752
172 lines
7.7 KiB
Diff
172 lines
7.7 KiB
Diff
From d0efb1123f1e2d4b4792e5eca8ff3d69fa9d46e7 Mon Sep 17 00:00:00 2001
|
|
Message-ID: <d0efb1123f1e2d4b4792e5eca8ff3d69fa9d46e7.1728560653.git.jdenemar@redhat.com>
|
|
From: Laine Stump <laine@redhat.com>
|
|
Date: Fri, 4 Oct 2024 18:14:36 -0400
|
|
Subject: [PATCH] network: a different way of supporting firewalld zone for
|
|
mode='open' networks
|
|
|
|
Now that networkAddFirewallRules and networkRemoveFirewallRules() are
|
|
being called for mode='open' networks, we just need to move the code
|
|
that sets the zone outside of the if (mode != ...OPEN) clause, so that
|
|
it's done for all forward modes, with the exception of setting the
|
|
implied 'libvirt*' zones, which are set when no zone is specified for
|
|
all forward modes *except* 'open'.
|
|
|
|
This was previously done in commit v10.7.0-76-g1a72b83d56, but in a
|
|
manner that caused the zone to be unset whenever firewalld reloaded
|
|
its rules. That patch was reverted, and this new better patch takes
|
|
its place.
|
|
|
|
Replaces: 1a72b83d566df952033529001b0f88a66d7f4393
|
|
Resolves: https://issues.redhat.com/browse/RHEL-61576
|
|
Re-Resolves: https://gitlab.com/libvirt/libvirt/-/issues/215
|
|
Signed-off-by: Laine Stump <laine@redhat.com>
|
|
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
|
|
(cherry picked from commit cb4e38d4b1e947d0718232a59f964f35ad156c74)
|
|
|
|
https://issues.redhat.com/browse/RHEL-61752
|
|
|
|
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
---
|
|
src/network/bridge_driver_linux.c | 111 ++++++++++++++++--------------
|
|
1 file changed, 60 insertions(+), 51 deletions(-)
|
|
|
|
diff --git a/src/network/bridge_driver_linux.c b/src/network/bridge_driver_linux.c
|
|
index 31feec9c9f..8956d38ab1 100644
|
|
--- a/src/network/bridge_driver_linux.c
|
|
+++ b/src/network/bridge_driver_linux.c
|
|
@@ -337,6 +337,64 @@ networkAddFirewallRules(virNetworkDef *def,
|
|
virFirewallBackend firewallBackend,
|
|
virFirewall **fwRemoval)
|
|
{
|
|
+ /* If firewalld is running on the system, a firewalld zone is
|
|
+ * always set for the bridge device of all bridge-based managed
|
|
+ * networks of all forward modes *except* 'open', which is only
|
|
+ * set if specifically requested in the config.
|
|
+ */
|
|
+ if (def->bridgeZone) {
|
|
+
|
|
+ /* if a firewalld zone has been specified, fail/log an error
|
|
+ * if we can't honor it
|
|
+ */
|
|
+ if (virFirewallDIsRegistered() < 0) {
|
|
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
+ _("zone %1$s requested for network %2$s but firewalld is not active"),
|
|
+ def->bridgeZone, def->name);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (virFirewallDInterfaceSetZone(def->bridge, def->bridgeZone) < 0)
|
|
+ return -1;
|
|
+
|
|
+ } else if (def->forward.type != VIR_NETWORK_FORWARD_OPEN) {
|
|
+
|
|
+ /* if firewalld is active, try to set the "libvirt" zone by
|
|
+ * default (forward mode='open' networks have no zone set by
|
|
+ * default, but we honor it if one is specified). This is
|
|
+ * desirable (for consistency) if firewalld is using the
|
|
+ * iptables backend, but is necessary (for basic network
|
|
+ * connectivity) if firewalld is using the nftables backend
|
|
+ */
|
|
+ if (virFirewallDIsRegistered() == 0) {
|
|
+
|
|
+ /* if the "libvirt" zone exists, then set it. If not, and
|
|
+ * if firewalld is using the nftables backend, then we
|
|
+ * need to log an error because the combination of
|
|
+ * nftables + default zone means that traffic cannot be
|
|
+ * forwarded (and even DHCP and DNS from guest to host
|
|
+ * will probably no be permitted by the default zone
|
|
+ *
|
|
+ * Routed networks use a different zone and policy which we also
|
|
+ * need to verify exist. Probing for the policy guarantees the
|
|
+ * running firewalld has support for policies (firewalld >= 0.9.0).
|
|
+ */
|
|
+ if (def->forward.type == VIR_NETWORK_FORWARD_ROUTE &&
|
|
+ virFirewallDPolicyExists("libvirt-routed-out") &&
|
|
+ virFirewallDZoneExists("libvirt-routed")) {
|
|
+ if (virFirewallDInterfaceSetZone(def->bridge, "libvirt-routed") < 0)
|
|
+ return -1;
|
|
+ } else if (virFirewallDZoneExists("libvirt")) {
|
|
+ if (virFirewallDInterfaceSetZone(def->bridge, "libvirt") < 0)
|
|
+ return -1;
|
|
+ } else {
|
|
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
+ _("firewalld can't find the 'libvirt' zone that should have been installed with libvirt"));
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
if (def->forward.type == VIR_NETWORK_FORWARD_OPEN) {
|
|
|
|
VIR_DEBUG("No firewall rules to add for mode='open' network '%s'", def->name);
|
|
@@ -348,6 +406,7 @@ networkAddFirewallRules(virNetworkDef *def,
|
|
def->name,
|
|
virFirewallBackendTypeToString(firewallBackend));
|
|
|
|
+ /* one-time (per system boot) initialization */
|
|
networkSetupPrivateChains(firewallBackend, false);
|
|
|
|
if (errInitV4 &&
|
|
@@ -365,57 +424,7 @@ networkAddFirewallRules(virNetworkDef *def,
|
|
return -1;
|
|
}
|
|
|
|
- if (def->bridgeZone) {
|
|
-
|
|
- /* if a firewalld zone has been specified, fail/log an error
|
|
- * if we can't honor it
|
|
- */
|
|
- if (virFirewallDIsRegistered() < 0) {
|
|
- virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
- _("zone %1$s requested for network %2$s but firewalld is not active"),
|
|
- def->bridgeZone, def->name);
|
|
- return -1;
|
|
- }
|
|
-
|
|
- if (virFirewallDInterfaceSetZone(def->bridge, def->bridgeZone) < 0)
|
|
- return -1;
|
|
-
|
|
- } else {
|
|
-
|
|
- /* if firewalld is active, try to set the "libvirt" zone. This is
|
|
- * desirable (for consistency) if firewalld is using the iptables
|
|
- * backend, but is necessary (for basic network connectivity) if
|
|
- * firewalld is using the nftables backend
|
|
- */
|
|
- if (virFirewallDIsRegistered() == 0) {
|
|
-
|
|
- /* if the "libvirt" zone exists, then set it. If not, and
|
|
- * if firewalld is using the nftables backend, then we
|
|
- * need to log an error because the combination of
|
|
- * nftables + default zone means that traffic cannot be
|
|
- * forwarded (and even DHCP and DNS from guest to host
|
|
- * will probably no be permitted by the default zone
|
|
- *
|
|
- * Routed networks use a different zone and policy which we also
|
|
- * need to verify exist. Probing for the policy guarantees the
|
|
- * running firewalld has support for policies (firewalld >= 0.9.0).
|
|
- */
|
|
- if (def->forward.type == VIR_NETWORK_FORWARD_ROUTE &&
|
|
- virFirewallDPolicyExists("libvirt-routed-out") &&
|
|
- virFirewallDZoneExists("libvirt-routed")) {
|
|
- if (virFirewallDInterfaceSetZone(def->bridge, "libvirt-routed") < 0)
|
|
- return -1;
|
|
- } else if (virFirewallDZoneExists("libvirt")) {
|
|
- if (virFirewallDInterfaceSetZone(def->bridge, "libvirt") < 0)
|
|
- return -1;
|
|
- } else {
|
|
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
- _("firewalld can't find the 'libvirt' zone that should have been installed with libvirt"));
|
|
- return -1;
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
+ /* now actually add the rules */
|
|
switch (firewallBackend) {
|
|
case VIR_FIREWALL_BACKEND_NONE:
|
|
virReportError(VIR_ERR_NO_SUPPORT, "%s",
|
|
--
|
|
2.47.0
|