|
|
edecca |
From 69de85ec80efd714528955e9c0ab67ee6811c824 Mon Sep 17 00:00:00 2001
|
|
|
edecca |
Message-Id: <69de85ec80efd714528955e9c0ab67ee6811c824@dist-git>
|
|
|
edecca |
From: Laine Stump <laine@laine.org>
|
|
|
edecca |
Date: Fri, 1 Feb 2019 20:29:32 -0500
|
|
|
edecca |
Subject: [PATCH] network: allow configuring firewalld zone for virtual network
|
|
|
edecca |
bridge device
|
|
|
edecca |
MIME-Version: 1.0
|
|
|
edecca |
Content-Type: text/plain; charset=UTF-8
|
|
|
edecca |
Content-Transfer-Encoding: 8bit
|
|
|
edecca |
|
|
|
edecca |
Since we're setting the zone anyway, it will be useful to allow
|
|
|
edecca |
setting a different (custom) zone for each network. This will be done
|
|
|
edecca |
by adding a "zone" attribute to the "bridge" element, e.g.:
|
|
|
edecca |
|
|
|
edecca |
...
|
|
|
edecca |
<bridge name='virbr0' zone='myzone'/>
|
|
|
edecca |
...
|
|
|
edecca |
|
|
|
edecca |
If a zone is specified in the config and it can't be honored, this
|
|
|
edecca |
will be an error.
|
|
|
edecca |
|
|
|
edecca |
Signed-off-by: Laine Stump <laine@laine.org>
|
|
|
edecca |
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
|
|
edecca |
(cherry picked from commit 30a6f9168634f8ce269f1ef294c4a18d9c95939c)
|
|
|
edecca |
|
|
|
edecca |
Conflicts:
|
|
|
edecca |
|
|
|
edecca |
src/conf/network_conf.c - upstream added a new bool called
|
|
|
edecca |
hasBridge that is the equivalent of all the comparisons in the
|
|
|
edecca |
if() just following the line that adds "zone='blah'" to the xml
|
|
|
edecca |
string.
|
|
|
edecca |
|
|
|
edecca |
https://bugzilla.redhat.com/1650320
|
|
|
edecca |
|
|
|
edecca |
Signed-off-by: Laine Stump <laine@laine.org>
|
|
|
edecca |
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
|
|
edecca |
---
|
|
|
edecca |
docs/firewall.html.in | 5 ++
|
|
|
edecca |
docs/formatnetwork.html.in | 17 ++++
|
|
|
edecca |
docs/schemas/basictypes.rng | 6 ++
|
|
|
edecca |
docs/schemas/network.rng | 6 ++
|
|
|
edecca |
src/conf/network_conf.c | 14 +++-
|
|
|
edecca |
src/conf/network_conf.h | 1 +
|
|
|
edecca |
src/network/bridge_driver_linux.c | 95 +++++++++++++---------
|
|
|
edecca |
tests/networkxml2xmlin/routed-network.xml | 2 +-
|
|
|
edecca |
tests/networkxml2xmlout/routed-network.xml | 2 +-
|
|
|
edecca |
9 files changed, 106 insertions(+), 42 deletions(-)
|
|
|
edecca |
|
|
|
edecca |
diff --git a/docs/firewall.html.in b/docs/firewall.html.in
|
|
|
edecca |
index 5d584e582e..e86ab0d974 100644
|
|
|
edecca |
--- a/docs/firewall.html.in
|
|
|
edecca |
+++ b/docs/firewall.html.in
|
|
|
edecca |
@@ -151,6 +151,11 @@ MASQUERADE all -- * * 192.168.122.0/24 !192.168.122.0/24
|
|
|
edecca |
iptables rules regardless of which backend is in use by
|
|
|
edecca |
firewalld.
|
|
|
edecca |
|
|
|
edecca |
+
|
|
|
edecca |
+ NB: It is possible to manually set the firewalld zone for a
|
|
|
edecca |
+ network's interface with the "zone" attribute of the network's
|
|
|
edecca |
+ "bridge" element.
|
|
|
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 |
diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
|
|
|
edecca |
index 363a72bbc9..7ddcfee127 100644
|
|
|
edecca |
--- a/docs/formatnetwork.html.in
|
|
|
edecca |
+++ b/docs/formatnetwork.html.in
|
|
|
edecca |
@@ -152,6 +152,23 @@
|
|
|
edecca |
Since 1.2.11, requires kernel 3.17 or
|
|
|
edecca |
newer
|
|
|
edecca |
|
|
|
edecca |
+
|
|
|
edecca |
+
|
|
|
edecca |
+ The optional zone attribute of
|
|
|
edecca |
+ the bridge element is used to specify
|
|
|
edecca |
+ the firewalld
|
|
|
edecca |
+ zone for the bridge of a network with forward
|
|
|
edecca |
+ mode of "nat", "route", "open", or one with
|
|
|
edecca |
+ no forward specified. By default, the bridges
|
|
|
edecca |
+ of all virtual networks with these forward modes are placed
|
|
|
edecca |
+ in the firewalld zone named "libvirt", which permits
|
|
|
edecca |
+ incoming DNS, DHCP, TFTP, and SSH to the host from guests on
|
|
|
edecca |
+ the network. This behavior can be changed either by
|
|
|
edecca |
+ modifying the libvirt zone (using firewalld management
|
|
|
edecca |
+ tools), or by placing the network in a different zone (which
|
|
|
edecca |
+ will also be managed using firewalld tools).
|
|
|
edecca |
+ Since 5.1.0
|
|
|
edecca |
+
|
|
|
edecca |
|
|
|
edecca |
|
|
|
edecca |
mtu
|
|
|
edecca |
diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng
|
|
|
edecca |
index 1a18cd31b1..b45a7fcdc8 100644
|
|
|
edecca |
--- a/docs/schemas/basictypes.rng
|
|
|
edecca |
+++ b/docs/schemas/basictypes.rng
|
|
|
edecca |
@@ -252,6 +252,12 @@
|
|
|
edecca |
</data>
|
|
|
edecca |
</define>
|
|
|
edecca |
|
|
|
edecca |
+ <define name="zoneName">
|
|
|
edecca |
+ <data type="string">
|
|
|
edecca |
+ <param name="pattern">[a-zA-Z0-9_\-]+</param>
|
|
|
edecca |
+ </data>
|
|
|
edecca |
+ </define>
|
|
|
edecca |
+
|
|
|
edecca |
<define name="filePath">
|
|
|
edecca |
<data type="string">
|
|
|
edecca |
<param name="pattern">.+</param>
|
|
|
edecca |
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
|
|
|
edecca |
index f37c422bf3..2a6e3358fd 100644
|
|
|
edecca |
--- a/docs/schemas/network.rng
|
|
|
edecca |
+++ b/docs/schemas/network.rng
|
|
|
edecca |
@@ -58,6 +58,12 @@
|
|
|
edecca |
</attribute>
|
|
|
edecca |
</optional>
|
|
|
edecca |
|
|
|
edecca |
+ <optional>
|
|
|
edecca |
+ <attribute name="zone">
|
|
|
edecca |
+ <ref name="zoneName"/>
|
|
|
edecca |
+ </attribute>
|
|
|
edecca |
+ </optional>
|
|
|
edecca |
+
|
|
|
edecca |
<optional>
|
|
|
edecca |
<attribute name="stp">
|
|
|
edecca |
<ref name="virOnOff"/>
|
|
|
edecca |
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
|
|
|
edecca |
index 630a87fc07..1e3650b70f 100644
|
|
|
edecca |
--- a/src/conf/network_conf.c
|
|
|
edecca |
+++ b/src/conf/network_conf.c
|
|
|
edecca |
@@ -206,6 +206,7 @@ virNetworkDefFree(virNetworkDefPtr def)
|
|
|
edecca |
|
|
|
edecca |
VIR_FREE(def->name);
|
|
|
edecca |
VIR_FREE(def->bridge);
|
|
|
edecca |
+ VIR_FREE(def->bridgeZone);
|
|
|
edecca |
VIR_FREE(def->domain);
|
|
|
edecca |
|
|
|
edecca |
virNetworkForwardDefClear(&def->forward);
|
|
|
edecca |
@@ -1689,6 +1690,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
|
|
|
edecca |
|
|
|
edecca |
/* Parse bridge information */
|
|
|
edecca |
def->bridge = virXPathString("string(./bridge[1]/@name)", ctxt);
|
|
|
edecca |
+ def->bridgeZone = virXPathString("string(./bridge[1]/@zone)", ctxt);
|
|
|
edecca |
stp = virXPathString("string(./bridge[1]/@stp)", ctxt);
|
|
|
edecca |
def->stp = (stp && STREQ(stp, "off")) ? false : true;
|
|
|
edecca |
|
|
|
edecca |
@@ -1925,6 +1927,13 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
|
|
|
edecca |
def->name);
|
|
|
edecca |
goto error;
|
|
|
edecca |
}
|
|
|
edecca |
+ if (def->bridgeZone) {
|
|
|
edecca |
+ virReportError(VIR_ERR_XML_ERROR,
|
|
|
edecca |
+ _("bridge zone not allowed in %s mode (network '%s')"),
|
|
|
edecca |
+ virNetworkForwardTypeToString(def->forward.type),
|
|
|
edecca |
+ def->name);
|
|
|
edecca |
+ goto error;
|
|
|
edecca |
+ }
|
|
|
edecca |
if (def->macTableManager) {
|
|
|
edecca |
virReportError(VIR_ERR_XML_ERROR,
|
|
|
edecca |
_("bridge macTableManager setting not allowed "
|
|
|
edecca |
@@ -1936,9 +1945,9 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
|
|
|
edecca |
ATTRIBUTE_FALLTHROUGH;
|
|
|
edecca |
|
|
|
edecca |
case VIR_NETWORK_FORWARD_BRIDGE:
|
|
|
edecca |
- if (def->delay || stp) {
|
|
|
edecca |
+ if (def->delay || stp || def->bridgeZone) {
|
|
|
edecca |
virReportError(VIR_ERR_XML_ERROR,
|
|
|
edecca |
- _("bridge delay/stp options only allowed in "
|
|
|
edecca |
+ _("bridge delay/stp/zone options only allowed in "
|
|
|
edecca |
"route, nat, and isolated mode, not in %s "
|
|
|
edecca |
"(network '%s')"),
|
|
|
edecca |
virNetworkForwardTypeToString(def->forward.type),
|
|
|
edecca |
@@ -2478,6 +2487,7 @@ virNetworkDefFormatBuf(virBufferPtr buf,
|
|
|
edecca |
|
|
|
edecca |
virBufferAddLit(buf, "
|
|
|
edecca |
virBufferEscapeString(buf, " name='%s'", def->bridge);
|
|
|
edecca |
+ virBufferEscapeString(buf, " zone='%s'", def->bridgeZone);
|
|
|
edecca |
if (def->forward.type == VIR_NETWORK_FORWARD_NONE ||
|
|
|
edecca |
def->forward.type == VIR_NETWORK_FORWARD_NAT ||
|
|
|
edecca |
def->forward.type == VIR_NETWORK_FORWARD_ROUTE ||
|
|
|
edecca |
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
|
|
|
edecca |
index 54c8ed1c4c..415792166f 100644
|
|
|
edecca |
--- a/src/conf/network_conf.h
|
|
|
edecca |
+++ b/src/conf/network_conf.h
|
|
|
edecca |
@@ -237,6 +237,7 @@ struct _virNetworkDef {
|
|
|
edecca |
int connections; /* # of guest interfaces connected to this network */
|
|
|
edecca |
|
|
|
edecca |
char *bridge; /* Name of bridge device */
|
|
|
edecca |
+ char *bridgeZone; /* name of firewalld zone for bridge */
|
|
|
edecca |
int macTableManager; /* enum virNetworkBridgeMACTableManager */
|
|
|
edecca |
char *domain;
|
|
|
edecca |
int domainLocalOnly; /* enum virTristateBool: yes disables dns forwarding */
|
|
|
edecca |
diff --git a/src/network/bridge_driver_linux.c b/src/network/bridge_driver_linux.c
|
|
|
edecca |
index 823d5a9742..121d42b646 100644
|
|
|
edecca |
--- a/src/network/bridge_driver_linux.c
|
|
|
edecca |
+++ b/src/network/bridge_driver_linux.c
|
|
|
edecca |
@@ -642,49 +642,68 @@ 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 |
+ if (def->bridgeZone) {
|
|
|
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 |
+ /* if a firewalld zone has been specified, fail/log an error
|
|
|
edecca |
+ * if we can't honor it
|
|
|
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 |
+ if (virFirewallDIsRegistered() < 0) {
|
|
|
edecca |
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
edecca |
+ _("zone %s requested for network %s "
|
|
|
edecca |
+ "but firewalld is not active"),
|
|
|
edecca |
+ def->bridgeZone, def->name);
|
|
|
edecca |
+ goto cleanup;
|
|
|
edecca |
+ }
|
|
|
edecca |
|
|
|
edecca |
- if (vresult < 0)
|
|
|
edecca |
- goto cleanup;
|
|
|
edecca |
+ if (virFirewallDInterfaceSetZone(def->bridge, def->bridgeZone) < 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 |
+ } else {
|
|
|
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 (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 |
+ 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 |
diff --git a/tests/networkxml2xmlin/routed-network.xml b/tests/networkxml2xmlin/routed-network.xml
|
|
|
edecca |
index ab5e15b1f6..fce01df132 100644
|
|
|
edecca |
--- a/tests/networkxml2xmlin/routed-network.xml
|
|
|
edecca |
+++ b/tests/networkxml2xmlin/routed-network.xml
|
|
|
edecca |
@@ -1,7 +1,7 @@
|
|
|
edecca |
<network>
|
|
|
edecca |
<name>local</name>
|
|
|
edecca |
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
|
|
|
edecca |
- <bridge name="virbr1"/>
|
|
|
edecca |
+ <bridge name="virbr1" zone="myzone"/>
|
|
|
edecca |
<mac address='12:34:56:78:9A:BC'/>
|
|
|
edecca |
<forward mode="route" dev="eth1"/>
|
|
|
edecca |
<ip address="192.168.122.1" netmask="255.255.255.0">
|
|
|
edecca |
diff --git a/tests/networkxml2xmlout/routed-network.xml b/tests/networkxml2xmlout/routed-network.xml
|
|
|
edecca |
index 81abf06e9f..2e13cf4ffa 100644
|
|
|
edecca |
--- a/tests/networkxml2xmlout/routed-network.xml
|
|
|
edecca |
+++ b/tests/networkxml2xmlout/routed-network.xml
|
|
|
edecca |
@@ -4,7 +4,7 @@
|
|
|
edecca |
<forward dev='eth1' mode='route'>
|
|
|
edecca |
<interface dev='eth1'/>
|
|
|
edecca |
</forward>
|
|
|
edecca |
- <bridge name='virbr1' stp='on' delay='0'/>
|
|
|
edecca |
+ <bridge name='virbr1' zone='myzone' stp='on' delay='0'/>
|
|
|
edecca |
<mac address='12:34:56:78:9a:bc'/>
|
|
|
edecca |
<ip address='192.168.122.1' netmask='255.255.255.0'>
|
|
|
edecca |
</ip>
|
|
|
edecca |
--
|
|
|
edecca |
2.20.1
|
|
|
edecca |
|