[libvirt] [PATCH 5/5] network: allow configuring firewalld zone for virtual network bridge device
Daniel P. Berrangé
berrange at redhat.com
Tue Jan 15 16:42:19 UTC 2019
On Wed, Jan 09, 2019 at 09:57:37PM -0500, Laine Stump wrote:
> 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. If no zone is specified and the default zone
> ("libvirt") can't be set, it will be ignored.
>
> (BTW, Federico Simoncelli proposed a similar patch 5 1.2 years (!!)
> ago, but I misunderstood its usefulness at first, and by the time I
> did we were both too busy to revisit it. libvirt's code has changed so
> much in the intervening time that it was simpler to just rewrite from
> scratch)
Should this paragraph go below the --- ?
>
> Signed-off-by: Laine Stump <laine at laine.org>
> ---
> docs/formatnetwork.html.in | 17 +++++++++
> docs/news.xml | 40 ++++++++++++++++++++++
> docs/schemas/basictypes.rng | 6 ++++
> docs/schemas/network.rng | 6 ++++
> src/conf/network_conf.c | 14 ++++++--
> src/conf/network_conf.h | 1 +
> src/network/bridge_driver_linux.c | 30 ++++++++++++----
> tests/networkxml2xmlin/routed-network.xml | 2 +-
> tests/networkxml2xmlout/routed-network.xml | 2 +-
> 9 files changed, 107 insertions(+), 11 deletions(-)
>
> diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
> index 156cfae4ec..4aecdfe8e0 100644
> --- a/docs/formatnetwork.html.in
> +++ b/docs/formatnetwork.html.in
> @@ -152,6 +152,23 @@
> <span class="since">Since 1.2.11, requires kernel 3.17 or
> newer</span>
> </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.0.0</span>
> + </p>
> </dd>
>
> <dt><code>mtu</code></dt>
> diff --git a/docs/news.xml b/docs/news.xml
> index 8c608cdc36..d894821ed5 100644
> --- a/docs/news.xml
> +++ b/docs/news.xml
> @@ -58,6 +58,19 @@
> trunking configuration.
> </description>
> </change>
> + <change>
> + <summary>
> + network: support setting a firewalld "zone" for all virtual network bridges
> + </summary>
> + <description>
> + All libvirt virtual networks with bridges managed by libvirt
> + (i.e. those with <code>forward</code> mode of "nat",
> + "route", "open", or no forward mode) will now be placed in a
> + special firewalld zone called "libvirt" by default, and the
> + zone of any network bridge can be changed using the <code>zone</code>
> + attribute of the network's <code>bridge</code> element.
> + </description>
> + </change>
> </section>
> <section title="Removed features">
> <change>
> @@ -123,6 +136,33 @@
> </change>
> </section>
> <section title="Bug fixes">
> + <change>
> + <summary>
> + network: fix virtual networks on systems using firewalld+nftables
> + </summary>
> + <description>
> + Because of the transitional state of firewalld's new support
> + for nftables, not all iptables features required by libvirt
> + are yet available, so libvirt must continue to use iptables
> + for its own packet filtering rules even when the firewalld
> + backend is set to use nftables, but due to the way iptables
> + support is implemented in kernels using nftables (iptables
> + rules are converted to nftables rules and processed in a
> + separate hook from the native nftables rules), guest
> + networking was broken on hosts with firewalld configured to
> + use nftables as the backend. This has been fixed by putting
> + libvirt-managed bridges in their own firewalld zone, so that
> + guest traffic can be forwarded beyond the host, and so that
> + host services can be exposed to guests on the virtual
> + network without opening up those same services to the rest
> + of the physical network. This means that host access from
> + virtual machines is no longer controlled by the firewalld
> + default zone (usually "public"), but rather by the new
> + firewalld zone called "libvirt" (unless configured otherwise
> + using the new <code>zone</code> attribute of the network
> + <code>bridge</code> element).
> + </description>
> + </change>
Either this change belongs in the previous patch, or we should
put both changes in a patch #6 separate from the code.
> </section>
> </release>
> <release version="v4.10.0" date="2018-12-03">
> diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng
> index 9a63720ff7..9b3dcad4a5 100644
> --- a/docs/schemas/basictypes.rng
> +++ b/docs/schemas/basictypes.rng
> @@ -279,6 +279,12 @@
> </data>
> </define>
>
> + <define name="zoneName">
> + <data type="string">
> + <param name="pattern">[a-zA-Z0-9_\-]+</param>
> + </data>
> + </define>
> +
> <define name="filePath">
> <data type="string">
> <param name="pattern">.+</param>
> diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
> index f37c422bf3..2a6e3358fd 100644
> --- a/docs/schemas/network.rng
> +++ b/docs/schemas/network.rng
> @@ -58,6 +58,12 @@
> </attribute>
> </optional>
>
> + <optional>
> + <attribute name="zone">
> + <ref name="zoneName"/>
> + </attribute>
> + </optional>
> +
> <optional>
> <attribute name="stp">
> <ref name="virOnOff"/>
> diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
> index e035d8aba7..b09cb1dae2 100644
> --- a/src/conf/network_conf.c
> +++ b/src/conf/network_conf.c
> @@ -203,6 +203,7 @@ virNetworkDefFree(virNetworkDefPtr def)
>
> VIR_FREE(def->name);
> VIR_FREE(def->bridge);
> + VIR_FREE(def->bridgeZone);
> VIR_FREE(def->domain);
>
> virNetworkForwardDefClear(&def->forward);
> @@ -1684,6 +1685,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
>
> /* Parse bridge information */
> def->bridge = virXPathString("string(./bridge[1]/@name)", ctxt);
> + def->bridgeZone = virXPathString("string(./bridge[1]/@zone)", ctxt);
> stp = virXPathString("string(./bridge[1]/@stp)", ctxt);
> def->stp = (stp && STREQ(stp, "off")) ? false : true;
>
> @@ -1920,6 +1922,13 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
> def->name);
> 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) {
> virReportError(VIR_ERR_XML_ERROR,
> _("bridge macTableManager setting not allowed "
> @@ -1931,9 +1940,9 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
> ATTRIBUTE_FALLTHROUGH;
>
> case VIR_NETWORK_FORWARD_BRIDGE:
> - if (def->delay || stp) {
> + if (def->delay || stp || def->bridgeZone) {
> 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 "
> "(network '%s')"),
> virNetworkForwardTypeToString(def->forward.type),
> @@ -2508,6 +2517,7 @@ virNetworkDefFormatBuf(virBufferPtr buf,
> if (hasbridge || def->bridge || def->macTableManager) {
> virBufferAddLit(buf, "<bridge");
> virBufferEscapeString(buf, " name='%s'", def->bridge);
> + virBufferEscapeString(buf, " zone='%s'", def->bridgeZone);
> if (hasbridge)
> virBufferAsprintf(buf, " stp='%s' delay='%ld'",
> def->stp ? "on" : "off", def->delay);
> diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
> index c630674300..69ee8d7f2a 100644
> --- a/src/conf/network_conf.h
> +++ b/src/conf/network_conf.h
> @@ -235,6 +235,7 @@ struct _virNetworkDef {
> int connections; /* # of guest interfaces connected to this network */
>
> char *bridge; /* Name of bridge device */
> + char *bridgeZone; /* name of firewalld zone for bridge (default "libvirt" */
> int macTableManager; /* enum virNetworkBridgeMACTableManager */
> char *domain;
> int domainLocalOnly; /* enum virTristateBool: yes disables dns forwarding */
> diff --git a/src/network/bridge_driver_linux.c b/src/network/bridge_driver_linux.c
> index a32f19bcf0..8c585594d1 100644
> --- a/src/network/bridge_driver_linux.c
> +++ b/src/network/bridge_driver_linux.c
> @@ -639,13 +639,29 @@ int networkAddFirewallRules(virNetworkDefPtr def)
> virFirewallPtr fw = NULL;
> int ret = -1;
>
> -
> - /* if firewalld is active, try to set the default "libvirt" zone,
> - * but ignore failure, since the version of firewalld on the host
> - * may have failed to load the libvirt zone
> - */
> - if (virFirewallDStatus() >= 0)
> - ignore_value(virFirewallDInterfaceSetZone(def->bridge, "libvirt"));
> + if (!def->bridgeZone) {
> + /* if firewalld is active and no zone has been explicitly set
> + * in the config, try to set the default "libvirt" zone, but
> + * ignore failure, since the version of firewalld on the host
> + * may have failed to load the libvirt zone
> + */
> + if (virFirewallDStatus() >= 0)
> + ignore_value(virFirewallDInterfaceSetZone(def->bridge, "libvirt"));
> +
> + } else {
> + /* if a zone has been specified, fail/log an error if we can't
> + * honor it
> + */
> + if (virFirewallDStatus() < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("zone %s requested for network %s "
> + "but firewalld is not active"),
> + def->bridgeZone, def->name);
> + goto cleanup;
> + }
> + if (virFirewallDInterfaceSetZone(def->bridge, def->bridgeZone) < 0)
> + goto cleanup;
> + }
>
> fw = virFirewallNew();
>
> diff --git a/tests/networkxml2xmlin/routed-network.xml b/tests/networkxml2xmlin/routed-network.xml
> index ab5e15b1f6..fce01df132 100644
> --- a/tests/networkxml2xmlin/routed-network.xml
> +++ b/tests/networkxml2xmlin/routed-network.xml
> @@ -1,7 +1,7 @@
> <network>
> <name>local</name>
> <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
> - <bridge name="virbr1"/>
> + <bridge name="virbr1" zone="myzone"/>
> <mac address='12:34:56:78:9A:BC'/>
> <forward mode="route" dev="eth1"/>
> <ip address="192.168.122.1" netmask="255.255.255.0">
> diff --git a/tests/networkxml2xmlout/routed-network.xml b/tests/networkxml2xmlout/routed-network.xml
> index 81abf06e9f..2e13cf4ffa 100644
> --- a/tests/networkxml2xmlout/routed-network.xml
> +++ b/tests/networkxml2xmlout/routed-network.xml
> @@ -4,7 +4,7 @@
> <forward dev='eth1' mode='route'>
> <interface dev='eth1'/>
> </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'/>
> <ip address='192.168.122.1' netmask='255.255.255.0'>
> </ip>
> --
> 2.20.1
>
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
More information about the libvir-list
mailing list