提交 30a6f916 编写于 作者: L Laine Stump

network: allow configuring firewalld zone for virtual network bridge device

Since we're setting the zone anyway, it will be useful to allow
setting a different (custom) zone for each network. This will be done
by adding a "zone" attribute to the "bridge" element, e.g.:

   ...
   <bridge name='virbr0' zone='myzone'/>
   ...

If a zone is specified in the config and it can't be honored, this
will be an error.
Signed-off-by: NLaine Stump <laine@laine.org>
Reviewed-by: NDaniel P. Berrangé <berrange@redhat.com>
上级 ae05211a
...@@ -151,6 +151,11 @@ MASQUERADE all -- * * 192.168.122.0/24 !192.168.122.0/24</pre> ...@@ -151,6 +151,11 @@ MASQUERADE all -- * * 192.168.122.0/24 !192.168.122.0/24</pre>
iptables rules regardless of which backend is in use by iptables rules regardless of which backend is in use by
firewalld. firewalld.
</p> </p>
<p>
NB: It is possible to manually set the firewalld zone for a
network's interface with the "zone" attribute of the network's
"bridge" element.
</p>
<p> <p>
NB: Prior to libvirt 5.1.0, the firewalld "libvirt" zone did not NB: Prior to libvirt 5.1.0, the firewalld "libvirt" zone did not
exist, and prior to firewalld 0.7.0 a feature crucial to making exist, and prior to firewalld 0.7.0 a feature crucial to making
......
...@@ -152,6 +152,23 @@ ...@@ -152,6 +152,23 @@
<span class="since">Since 1.2.11, requires kernel 3.17 or <span class="since">Since 1.2.11, requires kernel 3.17 or
newer</span> newer</span>
</p> </p>
<p>
The optional <code>zone</code> attribute of
the <code>bridge</code> element is used to specify
the <a href="https://firewalld.org">firewalld</a>
zone for the bridge of a network with <code>forward</code>
mode of "nat", "route", "open", or one with
no <code>forward</code> specified. By default, the bridges
of all virtual networks with these forward modes are placed
in the firewalld zone named "libvirt", which permits
incoming DNS, DHCP, TFTP, and SSH to the host from guests on
the network. This behavior can be changed either by
modifying the libvirt zone (using firewalld management
tools), or by placing the network in a different zone (which
will also be managed using firewalld tools).
<span class="since">Since 5.1.0</span>
</p>
</dd> </dd>
<dt><code>mtu</code></dt> <dt><code>mtu</code></dt>
......
...@@ -279,6 +279,12 @@ ...@@ -279,6 +279,12 @@
</data> </data>
</define> </define>
<define name="zoneName">
<data type="string">
<param name="pattern">[a-zA-Z0-9_\-]+</param>
</data>
</define>
<define name="filePath"> <define name="filePath">
<data type="string"> <data type="string">
<param name="pattern">.+</param> <param name="pattern">.+</param>
......
...@@ -58,6 +58,12 @@ ...@@ -58,6 +58,12 @@
</attribute> </attribute>
</optional> </optional>
<optional>
<attribute name="zone">
<ref name="zoneName"/>
</attribute>
</optional>
<optional> <optional>
<attribute name="stp"> <attribute name="stp">
<ref name="virOnOff"/> <ref name="virOnOff"/>
......
...@@ -203,6 +203,7 @@ virNetworkDefFree(virNetworkDefPtr def) ...@@ -203,6 +203,7 @@ virNetworkDefFree(virNetworkDefPtr def)
VIR_FREE(def->name); VIR_FREE(def->name);
VIR_FREE(def->bridge); VIR_FREE(def->bridge);
VIR_FREE(def->bridgeZone);
VIR_FREE(def->domain); VIR_FREE(def->domain);
virNetworkForwardDefClear(&def->forward); virNetworkForwardDefClear(&def->forward);
...@@ -1684,6 +1685,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) ...@@ -1684,6 +1685,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
/* Parse bridge information */ /* Parse bridge information */
def->bridge = virXPathString("string(./bridge[1]/@name)", ctxt); def->bridge = virXPathString("string(./bridge[1]/@name)", ctxt);
def->bridgeZone = virXPathString("string(./bridge[1]/@zone)", ctxt);
stp = virXPathString("string(./bridge[1]/@stp)", ctxt); stp = virXPathString("string(./bridge[1]/@stp)", ctxt);
def->stp = (stp && STREQ(stp, "off")) ? false : true; def->stp = (stp && STREQ(stp, "off")) ? false : true;
...@@ -1920,6 +1922,13 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) ...@@ -1920,6 +1922,13 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
def->name); def->name);
goto error; goto error;
} }
if (def->bridgeZone) {
virReportError(VIR_ERR_XML_ERROR,
_("bridge zone not allowed in %s mode (network '%s')"),
virNetworkForwardTypeToString(def->forward.type),
def->name);
goto error;
}
if (def->macTableManager) { if (def->macTableManager) {
virReportError(VIR_ERR_XML_ERROR, virReportError(VIR_ERR_XML_ERROR,
_("bridge macTableManager setting not allowed " _("bridge macTableManager setting not allowed "
...@@ -1931,9 +1940,9 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) ...@@ -1931,9 +1940,9 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
ATTRIBUTE_FALLTHROUGH; ATTRIBUTE_FALLTHROUGH;
case VIR_NETWORK_FORWARD_BRIDGE: case VIR_NETWORK_FORWARD_BRIDGE:
if (def->delay || stp) { if (def->delay || stp || def->bridgeZone) {
virReportError(VIR_ERR_XML_ERROR, virReportError(VIR_ERR_XML_ERROR,
_("bridge delay/stp options only allowed in " _("bridge delay/stp/zone options only allowed in "
"route, nat, and isolated mode, not in %s " "route, nat, and isolated mode, not in %s "
"(network '%s')"), "(network '%s')"),
virNetworkForwardTypeToString(def->forward.type), virNetworkForwardTypeToString(def->forward.type),
...@@ -2508,6 +2517,7 @@ virNetworkDefFormatBuf(virBufferPtr buf, ...@@ -2508,6 +2517,7 @@ virNetworkDefFormatBuf(virBufferPtr buf,
if (hasbridge || def->bridge || def->macTableManager) { if (hasbridge || def->bridge || def->macTableManager) {
virBufferAddLit(buf, "<bridge"); virBufferAddLit(buf, "<bridge");
virBufferEscapeString(buf, " name='%s'", def->bridge); virBufferEscapeString(buf, " name='%s'", def->bridge);
virBufferEscapeString(buf, " zone='%s'", def->bridgeZone);
if (hasbridge) if (hasbridge)
virBufferAsprintf(buf, " stp='%s' delay='%ld'", virBufferAsprintf(buf, " stp='%s' delay='%ld'",
def->stp ? "on" : "off", def->delay); def->stp ? "on" : "off", def->delay);
......
...@@ -235,6 +235,7 @@ struct _virNetworkDef { ...@@ -235,6 +235,7 @@ struct _virNetworkDef {
int connections; /* # of guest interfaces connected to this network */ int connections; /* # of guest interfaces connected to this network */
char *bridge; /* Name of bridge device */ char *bridge; /* Name of bridge device */
char *bridgeZone; /* name of firewalld zone for bridge */
int macTableManager; /* enum virNetworkBridgeMACTableManager */ int macTableManager; /* enum virNetworkBridgeMACTableManager */
char *domain; char *domain;
int domainLocalOnly; /* enum virTristateBool: yes disables dns forwarding */ int domainLocalOnly; /* enum virTristateBool: yes disables dns forwarding */
......
...@@ -671,49 +671,68 @@ int networkAddFirewallRules(virNetworkDefPtr def) ...@@ -671,49 +671,68 @@ int networkAddFirewallRules(virNetworkDefPtr def)
virFirewallPtr fw = NULL; virFirewallPtr fw = NULL;
int ret = -1; int ret = -1;
/* if firewalld is active, try to set the "libvirt" zone. This is if (def->bridgeZone) {
* desirable (for consistency) if firewalld is using the iptables
* backend, but is necessary (for basic network connectivity) if /* if a firewalld zone has been specified, fail/log an error
* firewalld is using the nftables backend * if we can't honor it
*/ */
if (virFirewallDIsRegistered() == 0) { if (virFirewallDIsRegistered() < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
/* if the "libvirt" zone exists, then set it. If not, and _("zone %s requested for network %s "
* if firewalld is using the nftables backend, then we "but firewalld is not active"),
* need to log an error because the combination of def->bridgeZone, def->name);
* nftables + default zone means that traffic cannot be goto cleanup;
* forwarded (and even DHCP and DNS from guest to host }
* will probably no be permitted by the default zone
if (virFirewallDInterfaceSetZone(def->bridge, def->bridgeZone) < 0)
goto cleanup;
} 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 (virFirewallDZoneExists("libvirt")) { if (virFirewallDIsRegistered() == 0) {
if (virFirewallDInterfaceSetZone(def->bridge, "libvirt") < 0)
goto cleanup; /* if the "libvirt" zone exists, then set it. If not, and
} else { * if firewalld is using the nftables backend, then we
unsigned long version; * need to log an error because the combination of
int vresult = virFirewallDGetVersion(&version); * nftables + default zone means that traffic cannot be
* forwarded (and even DHCP and DNS from guest to host
if (vresult < 0) * will probably no be permitted by the default zone
goto cleanup;
/* Support for nftables backend was added in firewalld
* 0.6.0. Support for rule priorities (required by the
* 'libvirt' zone, which should be installed by a
* libvirt package, *not* by firewalld) was not added
* until firewalld 0.7.0 (unless it was backported).
*/ */
if (version >= 6000 && if (virFirewallDZoneExists("libvirt")) {
virFirewallDGetBackend() == VIR_FIREWALLD_BACKEND_NFTABLES) { if (virFirewallDInterfaceSetZone(def->bridge, "libvirt") < 0)
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", goto cleanup;
_("firewalld is set to use the nftables " } else {
"backend, but the required firewalld " unsigned long version;
"'libvirt' zone is missing. Either set " int vresult = virFirewallDGetVersion(&version);
"the firewalld backend to 'iptables', or "
"ensure that firewalld has a 'libvirt' " if (vresult < 0)
"zone by upgrading firewalld to a " goto cleanup;
"version supporting rule priorities "
"(0.7.0+) and/or rebuilding " /* Support for nftables backend was added in firewalld
"libvirt with --with-firewalld-zone")); * 0.6.0. Support for rule priorities (required by the
goto cleanup; * 'libvirt' zone, which should be installed by a
* libvirt package, *not* by firewalld) was not added
* until firewalld 0.7.0 (unless it was backported).
*/
if (version >= 6000 &&
virFirewallDGetBackend() == VIR_FIREWALLD_BACKEND_NFTABLES) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("firewalld is set to use the nftables "
"backend, but the required firewalld "
"'libvirt' zone is missing. Either set "
"the firewalld backend to 'iptables', or "
"ensure that firewalld has a 'libvirt' "
"zone by upgrading firewalld to a "
"version supporting rule priorities "
"(0.7.0+) and/or rebuilding "
"libvirt with --with-firewalld-zone"));
goto cleanup;
}
} }
} }
} }
......
<network> <network>
<name>local</name> <name>local</name>
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid> <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
<bridge name="virbr1"/> <bridge name="virbr1" zone="myzone"/>
<mac address='12:34:56:78:9A:BC'/> <mac address='12:34:56:78:9A:BC'/>
<forward mode="route" dev="eth1"/> <forward mode="route" dev="eth1"/>
<ip address="192.168.122.1" netmask="255.255.255.0"> <ip address="192.168.122.1" netmask="255.255.255.0">
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<forward dev='eth1' mode='route'> <forward dev='eth1' mode='route'>
<interface dev='eth1'/> <interface dev='eth1'/>
</forward> </forward>
<bridge name='virbr1' stp='on' delay='0'/> <bridge name='virbr1' zone='myzone' stp='on' delay='0'/>
<mac address='12:34:56:78:9a:bc'/> <mac address='12:34:56:78:9a:bc'/>
<ip address='192.168.122.1' netmask='255.255.255.0'> <ip address='192.168.122.1' netmask='255.255.255.0'>
</ip> </ip>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册