mirror of https://gitee.com/openkylin/libvirt.git
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: Laine Stump <laine@laine.org> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
ae05211a36
commit
30a6f91686
|
@ -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 @@
|
||||||
<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 @@
|
||||||
</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 @@
|
||||||
</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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
/* 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)
|
||||||
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)
|
||||||
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,
|
||||||
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 {
|
||||||
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)
|
||||||
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
|
|
||||||
* firewalld is using the nftables backend
|
|
||||||
*/
|
|
||||||
if (virFirewallDIsRegistered() == 0) {
|
|
||||||
|
|
||||||
/* if the "libvirt" zone exists, then set it. If not, and
|
/* if a firewalld zone has been specified, fail/log an error
|
||||||
* if firewalld is using the nftables backend, then we
|
* if we can't honor it
|
||||||
* 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
|
|
||||||
*/
|
*/
|
||||||
if (virFirewallDZoneExists("libvirt")) {
|
if (virFirewallDIsRegistered() < 0) {
|
||||||
if (virFirewallDInterfaceSetZone(def->bridge, "libvirt") < 0)
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
goto cleanup;
|
_("zone %s requested for network %s "
|
||||||
} else {
|
"but firewalld is not active"),
|
||||||
unsigned long version;
|
def->bridgeZone, def->name);
|
||||||
int vresult = virFirewallDGetVersion(&version);
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
if (vresult < 0)
|
if (virFirewallDInterfaceSetZone(def->bridge, def->bridgeZone) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* Support for nftables backend was added in firewalld
|
} else {
|
||||||
* 0.6.0. Support for rule priorities (required by the
|
|
||||||
* 'libvirt' zone, which should be installed by a
|
/* if firewalld is active, try to set the "libvirt" zone. This is
|
||||||
* libvirt package, *not* by firewalld) was not added
|
* desirable (for consistency) if firewalld is using the iptables
|
||||||
* until firewalld 0.7.0 (unless it was backported).
|
* 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
|
||||||
*/
|
*/
|
||||||
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<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 @@
|
||||||
<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>
|
||||||
|
|
Loading…
Reference in New Issue