From nobody Fri Apr 26 14:11:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1548984316371986.6828152484715; Thu, 31 Jan 2019 17:25:16 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4006F7E446; Fri, 1 Feb 2019 01:25:13 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A5CFC1048127; Fri, 1 Feb 2019 01:25:12 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id E240B3F7D0; Fri, 1 Feb 2019 01:25:09 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x111P7iF002408 for ; Thu, 31 Jan 2019 20:25:07 -0500 Received: by smtp.corp.redhat.com (Postfix) id 579E619742; Fri, 1 Feb 2019 01:25:07 +0000 (UTC) Received: from vhost2.laine.org (ovpn-117-140.phx2.redhat.com [10.3.117.140]) by smtp.corp.redhat.com (Postfix) with ESMTP id DB56519741; Fri, 1 Feb 2019 01:25:06 +0000 (UTC) From: Laine Stump To: libvir-list@redhat.com Date: Thu, 31 Jan 2019 20:24:52 -0500 Message-Id: <20190201012458.25703-2-laine@laine.org> In-Reply-To: <20190201012458.25703-1-laine@laine.org> References: <20190201012458.25703-1-laine@laine.org> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-loop: libvir-list@redhat.com Cc: Eric Garver Subject: [libvirt] [PATCH v2 1/7] configure: change HAVE_FIREWALLD to WITH_FIREWALLD X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Fri, 01 Feb 2019 01:25:14 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Support for firewalld is a feature that can be selectively enabled or disabled (using --with-firewalld/--without-firewalld), not merely something that must be accounted for in the code if it is present with no exceptions. It is more consistent with other usage in libvirt to use WITH_FIREWALLD rather than HAVE_FIREWALLD. Signed-off-by: Laine Stump Reviewed-by: Daniel P. Berrang=C3=A9 --- New patch in V2 (NB, I already pushed patch 1 from V1, as it was ACKed, and not directly related to the rest of the series) m4/virt-firewalld.m4 | 4 ++-- src/network/bridge_driver.c | 6 +++--- src/nwfilter/nwfilter_driver.c | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/m4/virt-firewalld.m4 b/m4/virt-firewalld.m4 index 08d2ff83d6..89efa47589 100644 --- a/m4/virt-firewalld.m4 +++ b/m4/virt-firewalld.m4 @@ -32,10 +32,10 @@ AC_DEFUN([LIBVIRT_CHECK_FIREWALLD], [ if test "x$with_dbus" !=3D "xyes" ; then AC_MSG_ERROR([You must have dbus enabled for firewalld support]) fi - AC_DEFINE_UNQUOTED([HAVE_FIREWALLD], [1], [whether firewalld support i= s enabled]) + AC_DEFINE_UNQUOTED([WITH_FIREWALLD], [1], [whether firewalld support i= s enabled]) fi =20 - AM_CONDITIONAL([HAVE_FIREWALLD], [test "x$with_firewalld" !=3D "xno"]) + AM_CONDITIONAL([WITH_FIREWALLD], [test "x$with_firewalld" !=3D "xno"]) ]) =20 AC_DEFUN([LIBVIRT_RESULT_FIREWALLD], [ diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 20a0f65e65..238ea2e68e 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -536,7 +536,7 @@ networkAutostartConfig(virNetworkObjPtr obj, } =20 =20 -#if HAVE_FIREWALLD +#ifdef WITH_FIREWALLD static DBusHandlerResult firewalld_dbus_filter_bridge(DBusConnection *connection ATTRIBUTE_UNUSED, DBusMessage *message, @@ -571,7 +571,7 @@ networkStateInitialize(bool privileged, int ret =3D -1; char *configdir =3D NULL; char *rundir =3D NULL; -#ifdef HAVE_FIREWALLD +#ifdef WITH_FIREWALLD DBusConnection *sysbus =3D NULL; #endif =20 @@ -662,7 +662,7 @@ networkStateInitialize(bool privileged, =20 network_driver->networkEventState =3D virObjectEventStateNew(); =20 -#ifdef HAVE_FIREWALLD +#ifdef WITH_FIREWALLD if (!(sysbus =3D virDBusGetSystemBus())) { VIR_WARN("DBus not available, disabling firewalld support " "in bridge_network_driver: %s", virGetLastErrorMessage()); diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c index 0e29d3e19e..fdfc6f48fa 100644 --- a/src/nwfilter/nwfilter_driver.c +++ b/src/nwfilter/nwfilter_driver.c @@ -76,7 +76,7 @@ static void nwfilterDriverUnlock(void) virMutexUnlock(&driver->lock); } =20 -#if HAVE_FIREWALLD +#ifdef WITH_FIREWALLD =20 static DBusHandlerResult nwfilterFirewalldDBusFilter(DBusConnection *connection ATTRIBUTE_UNUSED, @@ -145,7 +145,7 @@ nwfilterDriverInstallDBusMatches(DBusConnection *sysbus) return ret; } =20 -#else /* HAVE_FIREWALLD */ +#else /* WITH_FIREWALLD */ =20 static void nwfilterDriverRemoveDBusMatches(void) @@ -158,7 +158,7 @@ nwfilterDriverInstallDBusMatches(DBusConnection *sysbus= ATTRIBUTE_UNUSED) return 0; } =20 -#endif /* HAVE_FIREWALLD */ +#endif /* WITH_FIREWALLD */ =20 static int virNWFilterTriggerRebuildImpl(void *opaque) --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Fri Apr 26 14:11:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 15489843148251014.7668781824121; Thu, 31 Jan 2019 17:25:14 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5147DC0CD16A; Fri, 1 Feb 2019 01:25:12 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 6D4B160C54; Fri, 1 Feb 2019 01:25:11 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id E21D218033A2; Fri, 1 Feb 2019 01:25:09 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x111P8W4002416 for ; Thu, 31 Jan 2019 20:25:08 -0500 Received: by smtp.corp.redhat.com (Postfix) id 1B6B919742; Fri, 1 Feb 2019 01:25:08 +0000 (UTC) Received: from vhost2.laine.org (ovpn-117-140.phx2.redhat.com [10.3.117.140]) by smtp.corp.redhat.com (Postfix) with ESMTP id 846B71992A; Fri, 1 Feb 2019 01:25:07 +0000 (UTC) From: Laine Stump To: libvir-list@redhat.com Date: Thu, 31 Jan 2019 20:24:53 -0500 Message-Id: <20190201012458.25703-3-laine@laine.org> In-Reply-To: <20190201012458.25703-1-laine@laine.org> References: <20190201012458.25703-1-laine@laine.org> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-loop: libvir-list@redhat.com Cc: Eric Garver Subject: [libvirt] [PATCH v2 2/7] util: move all firewalld-specific stuff into its own files X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Fri, 01 Feb 2019 01:25:13 +0000 (UTC) Content-Type: text/plain; charset="utf-8" In preparation for adding several other firewalld-specific functions, separate the code that's unique to firewalld from the more-generic "firewall" file. Signed-off-by: Laine Stump Reviewed-by: Daniel P. Berrang=C3=A9 --- Change from V1: define VIR_FIREWALL_FIREWALLD_SERVICE in virfirewalldpriv.h, since it should only be used by virfirewalld.c and unit test programs. (no, I haven't done anything about the awkward error checking that was already existing in the code I moved - not only is that a separate issue, but there no existing way to fix it anyway - that would take changes to firewalld) include/libvirt/virterror.h | 1 + src/libvirt_private.syms | 5 ++ src/util/Makefile.inc.am | 3 + src/util/virerror.c | 3 +- src/util/virfirewall.c | 86 +------------------- src/util/virfirewalld.c | 151 ++++++++++++++++++++++++++++++++++++ src/util/virfirewalld.h | 33 ++++++++ src/util/virfirewalldpriv.h | 30 +++++++ src/util/virfirewallpriv.h | 2 - tests/virfirewalltest.c | 2 + 10 files changed, 231 insertions(+), 85 deletions(-) create mode 100644 src/util/virfirewalld.c create mode 100644 src/util/virfirewalld.h create mode 100644 src/util/virfirewalldpriv.h diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index fbbe2d5624..3c19ff5e2e 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -131,6 +131,7 @@ typedef enum { VIR_FROM_PERF =3D 65, /* Error from perf */ VIR_FROM_LIBSSH =3D 66, /* Error from libssh connection transpor= t */ VIR_FROM_RESCTRL =3D 67, /* Error from resource control */ + VIR_FROM_FIREWALLD =3D 68, /* Error from firewalld */ =20 # ifdef VIR_ENUM_SENTINELS VIR_ERR_DOMAIN_LAST diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index e53ae0dbeb..d52e2412fa 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1921,6 +1921,11 @@ virFirewallStartRollback; virFirewallStartTransaction; =20 =20 +# util/virfirewalld.h +virFirewallDApplyRule; +virFirewallDIsRegistered; + + # util/virfirmware.h virFirmwareFreeList; virFirmwareParse; diff --git a/src/util/Makefile.inc.am b/src/util/Makefile.inc.am index 4295babac3..aa5c6cbe03 100644 --- a/src/util/Makefile.inc.am +++ b/src/util/Makefile.inc.am @@ -64,6 +64,9 @@ UTIL_SOURCES =3D \ util/virfirewall.c \ util/virfirewall.h \ util/virfirewallpriv.h \ + util/virfirewalld.c \ + util/virfirewalld.h \ + util/virfirewalldpriv.h \ util/virfirmware.c \ util/virfirmware.h \ util/virgettext.c \ diff --git a/src/util/virerror.c b/src/util/virerror.c index 61b47d2be0..740f3b84b3 100644 --- a/src/util/virerror.c +++ b/src/util/virerror.c @@ -138,7 +138,8 @@ VIR_ENUM_IMPL(virErrorDomain, VIR_ERR_DOMAIN_LAST, "Perf", /* 65 */ "Libssh transport layer", "Resource control", - ) + "FirewallD", + ); =20 =20 /* diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c index 0ed54d6228..7582ce5b5d 100644 --- a/src/util/virfirewall.c +++ b/src/util/virfirewall.c @@ -24,12 +24,12 @@ =20 #define LIBVIRT_VIRFIREWALLPRIV_H_ALLOW #include "virfirewallpriv.h" +#include "virfirewalld.h" #include "virerror.h" #include "virutil.h" #include "virstring.h" #include "vircommand.h" #include "virlog.h" -#include "virdbus.h" #include "virfile.h" #include "virthread.h" =20 @@ -46,11 +46,6 @@ VIR_ENUM_IMPL(virFirewallLayerCommand, VIR_FIREWALL_LAYE= R_LAST, IPTABLES_PATH, IP6TABLES_PATH); =20 -VIR_ENUM_DECL(virFirewallLayerFirewallD) -VIR_ENUM_IMPL(virFirewallLayerFirewallD, VIR_FIREWALL_LAYER_LAST, - "eb", "ipv4", "ipv6") - - struct _virFirewallRule { virFirewallLayer layer; =20 @@ -152,7 +147,7 @@ virFirewallValidateBackend(virFirewallBackend backend) VIR_DEBUG("Validating backend %d", backend); if (backend =3D=3D VIR_FIREWALL_BACKEND_AUTOMATIC || backend =3D=3D VIR_FIREWALL_BACKEND_FIREWALLD) { - int rv =3D virDBusIsServiceRegistered(VIR_FIREWALL_FIREWALLD_SERVI= CE); + int rv =3D virFirewallDIsRegistered(); =20 VIR_DEBUG("Firewalld is registered ? %d", rv); if (rv < 0) { @@ -712,81 +707,8 @@ virFirewallApplyRuleFirewallD(virFirewallRulePtr rule, bool ignoreErrors, char **output) { - const char *ipv =3D virFirewallLayerFirewallDTypeToString(rule->layer); - DBusConnection *sysbus =3D virDBusGetSystemBus(); - DBusMessage *reply =3D NULL; - virError error; - int ret =3D -1; - - if (!sysbus) - return -1; - - memset(&error, 0, sizeof(error)); - - if (!ipv) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Unknown firewall layer %d"), - rule->layer); - goto cleanup; - } - - if (virDBusCallMethod(sysbus, - &reply, - &error, - VIR_FIREWALL_FIREWALLD_SERVICE, - "/org/fedoraproject/FirewallD1", - "org.fedoraproject.FirewallD1.direct", - "passthrough", - "sa&s", - ipv, - (int)rule->argsLen, - rule->args) < 0) - goto cleanup; - - if (error.level =3D=3D VIR_ERR_ERROR) { - /* - * As of firewalld-0.3.9.3-1.fc20.noarch the name and - * message fields in the error look like - * - * name=3D"org.freedesktop.DBus.Python.dbus.exceptions.DBusExce= ption" - * message=3D"COMMAND_FAILED: '/sbin/iptables --table filter --del= ete - * INPUT --in-interface virbr0 --protocol udp --destinati= on-port 53 - * --jump ACCEPT' failed: iptables: Bad rule (does a matc= hing rule - * exist in that chain?)." - * - * We'd like to only ignore DBus errors precisely related to the f= ailure - * of iptables/ebtables commands. A well designed DBus interface w= ould - * return specific named exceptions not the top level generic pyth= on dbus - * exception name. With this current scheme our only option is tod= o a - * sub-string match for 'COMMAND_FAILED' on the message. eg like - * - * if (ignoreErrors && - * STREQ(error.name, - * "org.freedesktop.DBus.Python.dbus.exceptions.DBusExce= ption") && - * STRPREFIX(error.message, "COMMAND_FAILED")) - * ... - * - * But this risks our error detecting code being broken if firewal= ld changes - * ever alter the message string, so we're avoiding doing that. - */ - if (ignoreErrors) { - VIR_DEBUG("Ignoring error '%s': '%s'", - error.str1, error.message); - } else { - virReportErrorObject(&error); - goto cleanup; - } - } else { - if (virDBusMessageRead(reply, "s", output) < 0) - goto cleanup; - } - - ret =3D 0; - - cleanup: - virResetError(&error); - virDBusMessageUnref(reply); - return ret; + /* wrapper necessary because virFirewallRule is a private struct */ + return virFirewallDApplyRule(rule->layer, rule->args, rule->argsLen, i= gnoreErrors, output); } =20 static int diff --git a/src/util/virfirewalld.c b/src/util/virfirewalld.c new file mode 100644 index 0000000000..f27ec9c124 --- /dev/null +++ b/src/util/virfirewalld.c @@ -0,0 +1,151 @@ +/* + * virfirewalld.c: support for firewalld (https://firewalld.org) + * + * Copyright (C) 2019 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#include + +#include + +#include "virfirewall.h" +#include "virfirewalld.h" +#define LIBVIRT_VIRFIREWALLDPRIV_H_ALLOW +#include "virfirewalldpriv.h" +#include "virerror.h" +#include "virutil.h" +#include "virlog.h" +#include "virdbus.h" + +#define VIR_FROM_THIS VIR_FROM_FIREWALLD + +VIR_LOG_INIT("util.firewalld"); + +/* used to convert virFirewallLayer enum values to strings + * understood by the firewalld.direct "passthrough" method + */ +VIR_ENUM_DECL(virFirewallLayerFirewallD); +VIR_ENUM_IMPL(virFirewallLayerFirewallD, VIR_FIREWALL_LAYER_LAST, + "eb", + "ipv4", + "ipv6", + ); + + +/** + * virFirewallDIsRegistered: + * + * Returns 0 if service is registered, -1 on fatal error, or -2 if service= is not registered + */ +int +virFirewallDIsRegistered(void) +{ + return virDBusIsServiceRegistered(VIR_FIREWALL_FIREWALLD_SERVICE); +} + + +/** + * virFirewallDApplyRule: + * @layer: which layer to apply the rule to + * @args: list of args to send to this layer's passthrough command. + * @argsLen: number of items in @args + * @ignoreErrors: true to suppress logging of errors and return success + * false to log errors and return actual status + * @output: output of the direct passthrough command, if it was succ= essful + */ +int +virFirewallDApplyRule(virFirewallLayer layer, + char **args, size_t argsLen, + bool ignoreErrors, + char **output) +{ + const char *ipv =3D virFirewallLayerFirewallDTypeToString(layer); + DBusConnection *sysbus =3D virDBusGetSystemBus(); + DBusMessage *reply =3D NULL; + virError error; + int ret =3D -1; + + if (!sysbus) + return -1; + + memset(&error, 0, sizeof(error)); + + if (!ipv) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown firewall layer %d"), + layer); + goto cleanup; + } + + if (virDBusCallMethod(sysbus, + &reply, + &error, + VIR_FIREWALL_FIREWALLD_SERVICE, + "/org/fedoraproject/FirewallD1", + "org.fedoraproject.FirewallD1.direct", + "passthrough", + "sa&s", + ipv, + (int)argsLen, + args) < 0) + goto cleanup; + + if (error.level =3D=3D VIR_ERR_ERROR) { + /* + * As of firewalld-0.3.9.3-1.fc20.noarch the name and + * message fields in the error look like + * + * name=3D"org.freedesktop.DBus.Python.dbus.exceptions.DBusExce= ption" + * message=3D"COMMAND_FAILED: '/sbin/iptables --table filter --del= ete + * INPUT --in-interface virbr0 --protocol udp --destinati= on-port 53 + * --jump ACCEPT' failed: iptables: Bad rule (does a matc= hing rule + * exist in that chain?)." + * + * We'd like to only ignore DBus errors precisely related to the f= ailure + * of iptables/ebtables commands. A well designed DBus interface w= ould + * return specific named exceptions not the top level generic pyth= on dbus + * exception name. With this current scheme our only option is tod= o a + * sub-string match for 'COMMAND_FAILED' on the message. eg like + * + * if (ignoreErrors && + * STREQ(error.name, + * "org.freedesktop.DBus.Python.dbus.exceptions.DBusExce= ption") && + * STRPREFIX(error.message, "COMMAND_FAILED")) + * ... + * + * But this risks our error detecting code being broken if firewal= ld changes + * ever alter the message string, so we're avoiding doing that. + */ + if (ignoreErrors) { + VIR_DEBUG("Ignoring error '%s': '%s'", + error.str1, error.message); + } else { + virReportErrorObject(&error); + goto cleanup; + } + } else { + if (virDBusMessageRead(reply, "s", output) < 0) + goto cleanup; + } + + ret =3D 0; + + cleanup: + virResetError(&error); + virDBusMessageUnref(reply); + return ret; +} diff --git a/src/util/virfirewalld.h b/src/util/virfirewalld.h new file mode 100644 index 0000000000..83fe1149cc --- /dev/null +++ b/src/util/virfirewalld.h @@ -0,0 +1,33 @@ +/* + * virfirewalld.h: support for firewalld (https://firewalld.org) + * + * Copyright (C) 2019 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#ifndef LIBVIRT_VIRFIREWALLD_H +# define LIBVIRT_VIRFIREWALLD_H + +# define VIR_FIREWALL_FIREWALLD_SERVICE "org.fedoraproject.FirewallD1" + +int virFirewallDIsRegistered(void); + +int virFirewallDApplyRule(virFirewallLayer layer, + char **args, size_t argsLen, + bool ignoreErrors, + char **output); + +#endif /* LIBVIRT_VIRFIREWALLD_H */ diff --git a/src/util/virfirewalldpriv.h b/src/util/virfirewalldpriv.h new file mode 100644 index 0000000000..6c03b467c9 --- /dev/null +++ b/src/util/virfirewalldpriv.h @@ -0,0 +1,30 @@ +/* + * virfirewalldpriv.h: private APIs for firewalld + * + * Copyright (C) 2019 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + */ + +#ifndef LIBVIRT_VIRFIREWALLDPRIV_H_ALLOW +# error "virfirewalldpriv.h may only be included by virfirewalld.c or test= suites" +#endif /* LIBVIRT_VIRFIREWALLDPRIV_H_ALLOW */ + +#ifndef LIBVIRT_VIRFIREWALLDPRIV_H +# define LIBVIRT_VIRFIREWALLDPRIV_H + +# define VIR_FIREWALL_FIREWALLD_SERVICE "org.fedoraproject.FirewallD1" + +#endif /* LIBVIRT_VIRFIREWALLDPRIV_H */ diff --git a/src/util/virfirewallpriv.h b/src/util/virfirewallpriv.h index efa94a7da4..7c31d0680d 100644 --- a/src/util/virfirewallpriv.h +++ b/src/util/virfirewallpriv.h @@ -27,8 +27,6 @@ =20 # include "virfirewall.h" =20 -# define VIR_FIREWALL_FIREWALLD_SERVICE "org.fedoraproject.FirewallD1" - typedef enum { VIR_FIREWALL_BACKEND_AUTOMATIC, VIR_FIREWALL_BACKEND_DIRECT, diff --git a/tests/virfirewalltest.c b/tests/virfirewalltest.c index 5fde25d8f6..7c586877d3 100644 --- a/tests/virfirewalltest.c +++ b/tests/virfirewalltest.c @@ -27,6 +27,8 @@ # include "vircommandpriv.h" # define LIBVIRT_VIRFIREWALLPRIV_H_ALLOW # include "virfirewallpriv.h" +# define LIBVIRT_VIRFIREWALLDPRIV_H_ALLOW +# include "virfirewalldpriv.h" # include "virmock.h" # define LIBVIRT_VIRDBUSPRIV_H_ALLOW # include "virdbuspriv.h" --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Fri Apr 26 14:11:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 15489843321581023.8583885267805; Thu, 31 Jan 2019 17:25:32 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 758EE8E678; Fri, 1 Feb 2019 01:25:30 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3048E104811A; Fri, 1 Feb 2019 01:25:30 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id C442E18033A5; Fri, 1 Feb 2019 01:25:29 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x111PCAP002435 for ; Thu, 31 Jan 2019 20:25:12 -0500 Received: by smtp.corp.redhat.com (Postfix) id 0F8C31974A; Fri, 1 Feb 2019 01:25:12 +0000 (UTC) Received: from vhost2.laine.org (ovpn-117-140.phx2.redhat.com [10.3.117.140]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9196019742; Fri, 1 Feb 2019 01:25:08 +0000 (UTC) From: Laine Stump To: libvir-list@redhat.com Date: Thu, 31 Jan 2019 20:24:54 -0500 Message-Id: <20190201012458.25703-4-laine@laine.org> In-Reply-To: <20190201012458.25703-1-laine@laine.org> References: <20190201012458.25703-1-laine@laine.org> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-loop: libvir-list@redhat.com Cc: Eric Garver Subject: [libvirt] [PATCH v2 3/7] util: new virFirewallD APIs + docs X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Fri, 01 Feb 2019 01:25:31 +0000 (UTC) Content-Type: text/plain; charset="utf-8" virFirewallDGetBackend() reports whether firewalld is currently using an iptables or an nftables backend. virFirewallDGetVersion() learns the version of the firewalld running on this system and returns it as 1000000*major + 1000*minor + micro. virFirewallDGetZones() gets a list of all currently active firewalld zones. virFirewallDInterfaceSetZone() sets the firewalld zone of the given interface. virFirewallDZoneExists() can be used to learn whether or not a particular zone is present and active in firewalld. Signed-off-by: Laine Stump --- Change from V1: define several new functions (previously was just a single function, now there are 5) src/libvirt_private.syms | 5 + src/util/virfirewalld.c | 222 +++++++++++++++++++++++++++++++++++++++ src/util/virfirewalld.h | 15 ++- 3 files changed, 241 insertions(+), 1 deletion(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index d52e2412fa..bfae73878f 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1923,7 +1923,12 @@ virFirewallStartTransaction; =20 # util/virfirewalld.h virFirewallDApplyRule; +virFirewallDGetBackend; +virFirewallDGetVersion; +virFirewallDGetZones; +virFirewallDInterfaceSetZone; virFirewallDIsRegistered; +virFirewallDZoneExists; =20 =20 # util/virfirmware.h diff --git a/src/util/virfirewalld.c b/src/util/virfirewalld.c index f27ec9c124..89cfaddd9a 100644 --- a/src/util/virfirewalld.c +++ b/src/util/virfirewalld.c @@ -46,6 +46,14 @@ VIR_ENUM_IMPL(virFirewallLayerFirewallD, VIR_FIREWALL_LA= YER_LAST, ); =20 =20 +VIR_ENUM_DECL(virFirewallDBackend); +VIR_ENUM_IMPL(virFirewallDBackend, VIR_FIREWALLD_BACKEND_LAST, + "", + "iptables", + "nftables", + ); + + /** * virFirewallDIsRegistered: * @@ -57,6 +65,197 @@ virFirewallDIsRegistered(void) return virDBusIsServiceRegistered(VIR_FIREWALL_FIREWALLD_SERVICE); } =20 +/** + * virFirewallDGetVersion: + * @version: pointer to location to save version in the form of: + * 1000000 * major + 1000 * minor + micro + * + * queries the firewalld version property from dbus, and converts it + * from a string into a number. + * + * Returns 0 if version was successfully retrieved, or -1 on error + */ +int +virFirewallDGetVersion(unsigned long *version) +{ + int ret =3D -1; + DBusConnection *sysbus =3D virDBusGetSystemBus(); + DBusMessage *reply =3D NULL; + VIR_AUTOFREE(char *) versionStr =3D NULL; + + if (!sysbus) + return -1; + + if (virDBusCallMethod(sysbus, + &reply, + NULL, + VIR_FIREWALL_FIREWALLD_SERVICE, + "/org/fedoraproject/FirewallD1", + "org.freedesktop.DBus.Properties", + "Get", + "ss", + "org.fedoraproject.FirewallD1", + "version") < 0) + goto cleanup; + + if (virDBusMessageRead(reply, "v", "s", &versionStr) < 0) + goto cleanup; + + if (virParseVersionString(versionStr, version, false) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to parse firewalld version '%s'"), + versionStr); + goto cleanup; + } + + VIR_DEBUG("FirewallD version: %s - %lu", versionStr, *version); + + ret =3D 0; + cleanup: + virDBusMessageUnref(reply); + return ret; +} + +/** + * virFirewallDGetBackend: + * + * Returns virVirewallDBackendType value representing which packet + * filtering backend is currently in use by firewalld, or -1 on error. + */ +int +virFirewallDGetBackend(void) +{ + DBusConnection *sysbus =3D virDBusGetSystemBus(); + DBusMessage *reply =3D NULL; + virError error; + VIR_AUTOFREE(char *) backendStr =3D NULL; + int backend =3D -1; + + if (!sysbus) + return -1; + + memset(&error, 0, sizeof(error)); + + if (virDBusCallMethod(sysbus, + &reply, + &error, + VIR_FIREWALL_FIREWALLD_SERVICE, + "/org/fedoraproject/FirewallD1/config", + "org.freedesktop.DBus.Properties", + "Get", + "ss", + "org.fedoraproject.FirewallD1.config", + "FirewallBackend") < 0) + goto cleanup; + + if (error.level =3D=3D VIR_ERR_ERROR) { + /* we don't want to log any error in the case that + * FirewallBackend isn't implemented in this firewalld, since + * that just means that it is an old version, and only has an + * iptables backend. + */ + VIR_DEBUG("Failed to get FirewallBackend setting, assuming 'iptabl= es'"); + backend =3D VIR_FIREWALLD_BACKEND_IPTABLES; + goto cleanup; + } + + if (virDBusMessageRead(reply, "v", "s", &backendStr) < 0) + goto cleanup; + + VIR_DEBUG("FirewallD backend: %s", backendStr); + + if ((backend =3D virFirewallDBackendTypeFromString(backendStr)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unrecognized firewalld backend type: %s"), + backendStr); + } + + cleanup: + virResetError(&error); + virDBusMessageUnref(reply); + return backend; +} + + +/** + * virFirewallDGetZones: + * @zones: array of char *, each entry is a null-terminated zone name + * @nzones: number of entries in @zones + * + * Get the number of currently active firewalld zones, and their names in = an + * array of null-terminated strings. + * + * Returns 0 on success, -1 (and failure logged) on error + */ +int +virFirewallDGetZones(char ***zones, size_t *nzones) +{ + DBusConnection *sysbus =3D virDBusGetSystemBus(); + DBusMessage *reply =3D NULL; + int ret =3D -1; + + *nzones =3D 0; + *zones =3D NULL; + + if (!sysbus) + return -1; + + if (virDBusCallMethod(sysbus, + &reply, + NULL, + VIR_FIREWALL_FIREWALLD_SERVICE, + "/org/fedoraproject/FirewallD1", + "org.fedoraproject.FirewallD1.zone", + "getZones", + NULL) < 0) + goto cleanup; + + if (virDBusMessageRead(reply, "a&s", nzones, zones) < 0) + goto cleanup; + + ret =3D 0; + cleanup: + virDBusMessageUnref(reply); + return ret; +} + + +/** + * virFirewallDZoneExists: + * @match: name of zone to look for + * + * Returns true if the requested zone exists, or false if it doesn't exist + */ +bool +virFirewallDZoneExists(const char *match) +{ + size_t nzones =3D 0, i; + char **zones =3D NULL; + bool result =3D false; + + return true; + + if (virFirewallDGetZones(&zones, &nzones) < 0) + goto cleanup; + + for (i =3D 0; i < nzones; i++) { + VIR_DEBUG("FirewallD zone: %s", zones[i]); + if (STREQ_NULLABLE(zones[i], match)) + result =3D true; + } + + cleanup: + /* NB: zones points to memory inside reply, so it is cleaned + * up by virDBusMessageUnref, and doesn't need to be freed + */ + VIR_DEBUG("Requested zone '%s' %s exist", + match, result ? "does" : "doesn't"); + for (i =3D 0; i < nzones; i++) + VIR_FREE(zones[i]); + VIR_FREE(zones); + return result; +} + =20 /** * virFirewallDApplyRule: @@ -149,3 +348,26 @@ virFirewallDApplyRule(virFirewallLayer layer, virDBusMessageUnref(reply); return ret; } + + +int +virFirewallDInterfaceSetZone(const char *iface, + const char *zone) +{ + DBusConnection *sysbus =3D virDBusGetSystemBus(); + DBusMessage *reply =3D NULL; + + if (!sysbus) + return -1; + + return virDBusCallMethod(sysbus, + &reply, + NULL, + VIR_FIREWALL_FIREWALLD_SERVICE, + "/org/fedoraproject/FirewallD1", + "org.fedoraproject.FirewallD1.zone", + "changeZoneOfInterface", + "ss", + zone, + iface); +} diff --git a/src/util/virfirewalld.h b/src/util/virfirewalld.h index 83fe1149cc..f05f5f2f08 100644 --- a/src/util/virfirewalld.h +++ b/src/util/virfirewalld.h @@ -23,11 +23,24 @@ =20 # define VIR_FIREWALL_FIREWALLD_SERVICE "org.fedoraproject.FirewallD1" =20 -int virFirewallDIsRegistered(void); +typedef enum { + VIR_FIREWALLD_BACKEND_NONE, + VIR_FIREWALLD_BACKEND_IPTABLES, + VIR_FIREWALLD_BACKEND_NFTABLES, + VIR_FIREWALLD_BACKEND_LAST, +} virFirewallDBackendType; =20 +int virFirewallDGetVersion(unsigned long *version); +int virFirewallDGetBackend(void); +int virFirewallDIsRegistered(void); +int virFirewallDGetZones(char ***zones, size_t *nzones); +bool virFirewallDZoneExists(const char *match); int virFirewallDApplyRule(virFirewallLayer layer, char **args, size_t argsLen, bool ignoreErrors, char **output); =20 +int virFirewallDInterfaceSetZone(const char *iface, + const char *zone); + #endif /* LIBVIRT_VIRFIREWALLD_H */ --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Fri Apr 26 14:11:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1548984332463275.0433727009589; Thu, 31 Jan 2019 17:25:32 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 71B8D148807; Fri, 1 Feb 2019 01:25:30 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 335C960152; Fri, 1 Feb 2019 01:25:30 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id CBE793F603; Fri, 1 Feb 2019 01:25:29 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x111PC3P002440 for ; Thu, 31 Jan 2019 20:25:12 -0500 Received: by smtp.corp.redhat.com (Postfix) id A73F21974A; Fri, 1 Feb 2019 01:25:12 +0000 (UTC) Received: from vhost2.laine.org (ovpn-117-140.phx2.redhat.com [10.3.117.140]) by smtp.corp.redhat.com (Postfix) with ESMTP id 38AC319741; Fri, 1 Feb 2019 01:25:12 +0000 (UTC) From: Laine Stump To: libvir-list@redhat.com Date: Thu, 31 Jan 2019 20:24:55 -0500 Message-Id: <20190201012458.25703-5-laine@laine.org> In-Reply-To: <20190201012458.25703-1-laine@laine.org> References: <20190201012458.25703-1-laine@laine.org> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-loop: libvir-list@redhat.com Cc: Eric Garver Subject: [libvirt] [PATCH v2 4/7] configure: selectively install a firewalld 'libvirt' zone X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Fri, 01 Feb 2019 01:25:31 +0000 (UTC) Content-Type: text/plain; charset="utf-8" In the past (when both libvirt and firewalld used iptables), if either libvirt's rules *OR* firewalld's rules accepted a packet, it would be accepted. This was because libvirt and firewalld rules were processed during the same kernel hook, and a single ACCEPT result would terminate the rule traversal and cause the packet to be accepted. But now firewalld can use nftables for its backend, while libvirt's firewall rules are still using iptables; iptables rules are still processed, but at a different time during packet processing (i.e. during a different hook) than the firewalld nftables rules. The result is that a packet must be accepted by *BOTH* the libvirt iptables rules *AND* the firewalld nftable rules in order to be accepted. This causes pain because 1) libvirt always adds rules to permit DNS and DHCP (and sometimes TFTP) from guests to the host network's bridge interface. But libvirt's bridges are in firewalld's "default" zone (which is usually the zone called "public"). The public zone allows ssh, but doesn't allow DNS, DHCP, or TFTP. So even though libvirt's rules allow the DHCP and DNS traffic, the firewalld rules (now processed during a different hook) dont, thus guests connected to libvirt's bridges can't acquire an IP address from DHCP, nor can they make DNS queries to the DNS server libvirt has setup on the host. (This could be solved by modifying the default firewalld zone to allow DNS and DHCP, but that would open *all* interfaces in the default zone to those services, which is most likely not what the host's admin wants.) 2) Even though libvirt adds iptables rules to allow forwarded traffic to pass the iptables hook, firewalld's higher level "rich rules" don't yet have the ability to configure the acceptance of forwarded traffic (traffic that is going somewhere beyond the host), so any traffic that needs to be forwarded from guests to the network beyond the host is rejected during the nftables hook by the default zone's "default reject" policy (which rejects all traffic in the zone not specifically allowed by the rules in the zone, whether that traffic is destined to be forwarded or locally received by the host). libvirt can't send "direct" nftables rules (firewalld only supports direct/passthrough rules for iptables), so we can't solve this problem by just sending explicit nftables rules instead of explicit iptables rules (which, if it could be done, would place libvirt's rules in the same hook as firewalld's native rules, and thus eliminate the need for packets to be accepted by both libvirt's and firewalld's own rules). However, we can take advantage of a quirk in firewalld zones that have a default policy of "accept" (meaning any packet that doesn't match a specific rule in the zone will be *accepted*) - this default accept will also accept forwarded traffic (not just traffic destined for the host). Of course we don't want to modify firewalld's default zone in that way, because that would affect the filtering of traffic coming into the host from other interfaces using that zone. Instead, we will create a new zone called "libvirt". The libvirt zone will have a default policy of accept so that forwarded traffic can pass andn list specific services that will be allowed into the host from guests (DNS, DHCP, SSH, and TFTP). But the same default accept policy that fixes forwarded traffic also causes *all* traffic from guest to host to be accepted. To close this new hole, the libvirt zone can take advantage of a new feature in firewalld (currently slated for firewalld-0.7.0) - priorities for rich rules - to add a low priority rule that rejects all local traffic (but leaves alone all forwarded traffic). So, our new zone will start with a list of services that are allowed (dhcp, dns, tftp, and ssh to start, but configurable via any firewalld management application, or direct editing of the zone file in /etc/firewalld/zones/libvirt.xml), followed by a low priority rule (to reject all other traffic from guest to host), and finally with a default policy of accept (to allow forwarded traffic). This patch only creates the zonefile for the new zone, and implements a configure.ac option to selectively enable/disable installation of the new zone. A separate patch contains the necessary code to actually place bridge interfaces in the libvirt zone. Why do we need a configure option to disable installation of the new libvirt zone? It uses a new firewalld attribute that sets the priority of a rich rule; this feature first appears in firewalld-0.7.0 (unless it has been backported to am earlier firewalld by a downstream maintainer). If the file were installed on a system with firewalld that didn't support rule priorities, firewalld would log an error every time it restarted, causing confusion and lots of extra bug reports. So we add two new configure.ac switches to avoid polluting the system logs with this error on systems that don't support rule priorities - "--with-firewalld-zone" and "--without-firewalld-zone". A package builder can use these to include/exclude the libvirt zone file in the installation. If firewalld is enabled (--with-firewalld), the default is --with-firewalld-zone, but it can be disabled during configure (using --without-firewalld-zone). Targets that are using a firewalld version too old to support the rule priority setting in the libvirt zone file can simply add --without-firewalld-zone to their configure commandline. These switches only affect whether or not the libvirt zone file is *installed* in /usr/lib/firewalld/zones, but have no effect on whether or not libvirt looks for a zone called libvirt and tries to use it. NB: firewalld zones can only be added to the permanent config of firewalld, and won't be loaded/enabled until firewalld is restarted, so at package install/upgrade time we have to restart firewalld. For rpm-based distros, this is done in the libvirt.spec file by calling the %firewalld_restart rpm macro, which is a part of the firewalld-filesystem package. (For distros that don't use rpm packages, the command "firewalld-cmd --reload" will have the same effect). Signed-off-by: Laine Stump Reviewed-by: Daniel P. Berrang=C3=A9 --- Changes from V1: * only BuildRequire: firewalld-system if we are going to need it * make installation of the zone file optional, based on configure.ac options * make the rule's priority 32767 instead of 127. * move the code that actually sets the new zone to a separate patch configure.ac | 3 +++ libvirt.spec.in | 31 +++++++++++++++++++++++++ m4/virt-firewalld-zone.m4 | 45 +++++++++++++++++++++++++++++++++++++ src/network/Makefile.inc.am | 10 ++++++++- src/network/libvirt.zone | 23 +++++++++++++++++++ 5 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 m4/virt-firewalld-zone.m4 create mode 100644 src/network/libvirt.zone diff --git a/configure.ac b/configure.ac index 808884f2f7..4dcdd12069 100644 --- a/configure.ac +++ b/configure.ac @@ -246,6 +246,7 @@ LIBVIRT_ARG_CAPNG LIBVIRT_ARG_CURL LIBVIRT_ARG_DBUS LIBVIRT_ARG_FIREWALLD +LIBVIRT_ARG_FIREWALLD_ZONE LIBVIRT_ARG_FUSE LIBVIRT_ARG_GLUSTER LIBVIRT_ARG_HAL @@ -286,6 +287,7 @@ LIBVIRT_CHECK_DBUS LIBVIRT_CHECK_DEVMAPPER LIBVIRT_CHECK_DLOPEN LIBVIRT_CHECK_FIREWALLD +LIBVIRT_CHECK_FIREWALLD_ZONE LIBVIRT_CHECK_FUSE LIBVIRT_CHECK_GLUSTER LIBVIRT_CHECK_GNUTLS @@ -1000,6 +1002,7 @@ LIBVIRT_RESULT_CURL LIBVIRT_RESULT_DBUS LIBVIRT_RESULT_DLOPEN LIBVIRT_RESULT_FIREWALLD +LIBVIRT_RESULT_FIREWALLD_ZONE LIBVIRT_RESULT_FUSE LIBVIRT_RESULT_GLUSTER LIBVIRT_RESULT_GNUTLS diff --git a/libvirt.spec.in b/libvirt.spec.in index 879e315f49..c0e538d92d 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -82,6 +82,7 @@ %define with_sanlock 0%{!?_without_sanlock:0} %define with_numad 0%{!?_without_numad:0} %define with_firewalld 0%{!?_without_firewalld:0} +%define with_firewalld_zone 0%{!?_without_firewalld_zone:0} %define with_libssh2 0%{!?_without_libssh2:0} %define with_wireshark 0%{!?_without_wireshark:0} %define with_libssh 0%{!?_without_libssh:0} @@ -136,6 +137,11 @@ =20 %define with_firewalld 1 =20 +%if 0%{?fedora} >=3D 30 || 0%{?rhel} > 7 + %define with_firewalld_zone 0%{!?_without_firewalld_zone:1} +%endif + + # fuse is used to provide virtualized /proc for LXC %if %{with_lxc} %define with_fuse 0%{!?_without_fuse:1} @@ -395,6 +401,10 @@ BuildRequires: rpcgen BuildRequires: libtirpc-devel %endif =20 +%if %{with_firewalld_zone} +BuildRequires: firewalld-filesystem +%endif + Provides: bundled(gnulib) =20 %description @@ -1093,6 +1103,12 @@ exit 1 %define arg_firewalld --without-firewalld %endif =20 +%if %{with_firewalld_zone} + %define arg_firewalld_zone --with-firewalld-zone +%else + %define arg_firewalld_zone --without-firewalld-zone +%endif + %if %{with_wireshark} %define arg_wireshark --with-wireshark-dissector %else @@ -1191,6 +1207,7 @@ rm -f po/stamp-po --with-dtrace \ --with-driver-modules \ %{?arg_firewalld} \ + %{?arg_firewalld_zone} \ %{?arg_wireshark} \ --without-pm-utils \ --with-nss-plugin \ @@ -1358,6 +1375,16 @@ if [ -f %{_localstatedir}/lib/rpm-state/libvirt/rest= art ]; then fi rm -rf %{_localstatedir}/lib/rpm-state/libvirt || : =20 +%post daemon-driver-network +%if %{with_firewalld} + %firewalld_reload +%endif + +%postun daemon-driver-network +%if %{with_firewalld} + %firewalld_reload +%endif + %post daemon-config-network if test $1 -eq 1 && test ! -f %{_sysconfdir}/libvirt/qemu/networks/default= .xml ; then # see if the network used by default network creates a conflict, @@ -1596,6 +1623,10 @@ exit 0 %attr(0755, root, root) %{_libexecdir}/libvirt_leaseshelper %{_libdir}/%{name}/connection-driver/libvirt_driver_network.so =20 +%if %{with_firewalld_zone} +%{_prefix}/lib/firewalld/zones/libvirt.xml +%endif + %files daemon-driver-nodedev %{_libdir}/%{name}/connection-driver/libvirt_driver_nodedev.so =20 diff --git a/m4/virt-firewalld-zone.m4 b/m4/virt-firewalld-zone.m4 new file mode 100644 index 0000000000..b67d1a0b2f --- /dev/null +++ b/m4/virt-firewalld-zone.m4 @@ -0,0 +1,45 @@ +dnl firewalld_zone check - whether or not to install the firewall "libvirt= " zone +dnl +dnl Copyright (C) 2019 Red Hat, Inc. +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License, or (at your option) any later version. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library. If not, see +dnl . +dnl + +AC_DEFUN([LIBVIRT_ARG_FIREWALLD_ZONE], [ + LIBVIRT_ARG_WITH([FIREWALLD_ZONE], [Whether to install firewalld libvirt= zone], [check]) +]) + +AC_DEFUN([LIBVIRT_CHECK_FIREWALLD_ZONE], [ + AC_REQUIRE([LIBVIRT_CHECK_FIREWALLD]) + AC_MSG_CHECKING([for whether to install firewalld libvirt zone]) + + if test "x$with_firewalld_zone" =3D "xcheck" ; then + with_firewalld_zone=3D$with_firewalld + fi + + if test "x$with_firewalld_zone" =3D "xyes" ; then + if test "x$with_firewalld" !=3D "xyes" ; then + AC_MSG_ERROR([You must have firewalld support enabled to enable fire= walld-zone]) + fi + AC_DEFINE_UNQUOTED([WITH_FIREWALLD_ZONE], [1], [whether firewalld libv= irt zone is installed]) + fi + + AM_CONDITIONAL([WITH_FIREWALLD_ZONE], [test "x$with_firewalld_zone" !=3D= "xno"]) + AC_MSG_RESULT($with_firewalld_zone) +]) + +AC_DEFUN([LIBVIRT_RESULT_FIREWALLD_ZONE], [ + LIBVIRT_RESULT([firewalld-zone], [$with_firewalld_zone]) +]) diff --git a/src/network/Makefile.inc.am b/src/network/Makefile.inc.am index 508c8c0422..cbaaa7ea68 100644 --- a/src/network/Makefile.inc.am +++ b/src/network/Makefile.inc.am @@ -87,6 +87,11 @@ install-data-network: ( cd $(DESTDIR)$(confdir)/qemu/networks/autostart && \ rm -f default.xml && \ $(LN_S) ../default.xml default.xml ) +if WITH_FIREWALLD_ZONE + $(MKDIR_P) "$(DESTDIR)$(prefix)/lib/firewalld/zones" + $(INSTALL_DATA) $(srcdir)/network/libvirt.zone \ + $(DESTDIR)$(prefix)/lib/firewalld/zones/libvirt.xml +endif WITH_FIREWALLD_ZONE =20 uninstall-data-network: rm -f $(DESTDIR)$(confdir)/qemu/networks/autostart/default.xml @@ -95,10 +100,13 @@ uninstall-data-network: rmdir "$(DESTDIR)$(confdir)/qemu/networks" || : rmdir "$(DESTDIR)$(localstatedir)/lib/libvirt/network" ||: rmdir "$(DESTDIR)$(localstatedir)/run/libvirt/network" ||: +if WITH_FIREWALLD_ZONE + rm -f $(DESTDIR)$(prefix)/lib/firewalld/zones/libvirt.xml +endif WITH_FIREWALLD_ZONE =20 endif WITH_NETWORK =20 -EXTRA_DIST +=3D network/default.xml +EXTRA_DIST +=3D network/default.xml network/libvirt.zone =20 .PHONY: \ install-data-network \ diff --git a/src/network/libvirt.zone b/src/network/libvirt.zone new file mode 100644 index 0000000000..bf81db1b6e --- /dev/null +++ b/src/network/libvirt.zone @@ -0,0 +1,23 @@ + + + libvirt + + + The default policy of "ACCEPT" allows all packets to/from + interfaces in the zone to be forwarded, while the (*low priority*) + reject rule blocks any traffic destined for the host, except those + services explicitly listed (that list can be modified as required + by the local admin). This zone is intended to be used only by + libvirt virtual networks - libvirt will add the bridge devices for + all new virtual networks to this zone by default. + + + + + + + + + + + --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Fri Apr 26 14:11:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1548984338722340.13948007072463; Thu, 31 Jan 2019 17:25:38 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B52A12DC34E; Fri, 1 Feb 2019 01:25:36 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 32124608C8; Fri, 1 Feb 2019 01:25:36 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id BB74C18033A6; Fri, 1 Feb 2019 01:25:35 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x111PD2Z002445 for ; Thu, 31 Jan 2019 20:25:13 -0500 Received: by smtp.corp.redhat.com (Postfix) id 51AB91974E; Fri, 1 Feb 2019 01:25:13 +0000 (UTC) Received: from vhost2.laine.org (ovpn-117-140.phx2.redhat.com [10.3.117.140]) by smtp.corp.redhat.com (Postfix) with ESMTP id D138819741; Fri, 1 Feb 2019 01:25:12 +0000 (UTC) From: Laine Stump To: libvir-list@redhat.com Date: Thu, 31 Jan 2019 20:24:56 -0500 Message-Id: <20190201012458.25703-6-laine@laine.org> In-Reply-To: <20190201012458.25703-1-laine@laine.org> References: <20190201012458.25703-1-laine@laine.org> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-loop: libvir-list@redhat.com Cc: Eric Garver Subject: [libvirt] [PATCH v2 5/7] network: set firewalld zone of bridges to "libvirt" zone when appropriate X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Fri, 01 Feb 2019 01:25:37 +0000 (UTC) Content-Type: text/plain; charset="utf-8" From: Laine Stump This patch restores broken guest network connectivity after a host firewalld is switched to using an nftables backend. It does this by adding libvirt networks' bridge interfaces to the new "libvirt" zone in firewalld. After this patch, the bridge interface of any network created by libvirt (when firewalld is active) will be added to the firewalld zone called "libvirt" if it exists (regardless of the firewalld backend setting). This behavior does *not* depend on whether or not libvirt has installed the libvirt zone file (set with "--with[out]-firewalld-zone" during the configure phase of the package build). If the libvirt zone doesn't exist (either because the package was configured to not install it, or possibly it was installed, but firewalld doesn't support rule priorities, resulting in a parse error), the bridge will remain in firewalld's default zone, which could be innocuous (in the case that the firewalld backend is iptables, guest networking will still function properly with the bridge in the default zone), or it could be disastrous (if the firewalld backend is nftables, we can be assured that guest networking will fail). In order to be unobtrusive in the former case, and informative in the latter, when the libvirt zone doesn't exist we then check the firewalld version to see if it's new enough to support the nftables backend, and then if the backend is actually set to nftables, before logging an error (and failing the net-start operation, since the network couldn't possibly work anyway). When the libvirt zone is used, network behavior is *slightly* different from behavior of previous libvirt. In the past, libvirt network behavior would be affected by the configuration of firewalld's default zone (usually "public"), but now it is affected only by the "libvirt" zone), and thus almost surely warrants a release note for any distro upgrading to libvirt 5.1 or above. Although it's unfortunate that we have to deal with a mandatory behavior change, the architecture of multiple hooks makes it impossible to *not* change behavior in some way, and the new behavior is arguably better (since it will now be possible to manage access to the host from virtual machines vs from public interfaces separately). Resolves: https://bugzilla.redhat.com/1638342 Creates-and-Resolves: https://bugzilla.redhat.com/1650320 Signed-off-by: Laine Stump Reviewed-by: Daniel P. Berrang=C3=A9 --- NB: I had considered that it might be useful to cache the results of checking the list of active zones, the firewalld version, or the firewalld backend, but in my tests of restarting libvirtd with 100 active networks, the full startup time (from the beginning of "systemctl restart libvirtd.service" until successful return from a subsequent "virsh list") showed 42 seconds and a bit regardless of whether or not I made those checks. This tells me that the amount of time to be saved by caching the results of a single call vs calling once for each network are insignificant relative to everything else that is being done. Because any cached values would need to be stored in the network driver state object, and thus require acquiring the driver-wide lock to update at potentially very different times (e.g. in the response to a dbus message informing us that firewalld was restarted, as well as while starting a new network from an API call) I consider the chance of a bug in my code causing an obscure deadlock sometime in the future to be a much greater concern than maybe saving 1/10th of a second out of 42 (and lock contention might eliminate the gain anyway(), so I have left the code to retrieve the list of zones once for each network start. Changes in V2: * split off from Patch 5. This patch only sets the libvirt zone if it exists (and attempts to somewhat document the behavior in firewall.html), it doesn't install the libvirt zone. * check for existence of libvirt zone before attempting to set it. * if libvirt zone doesn't exist, only log an error in the case that the firewalld version is new enough to have an nftables backend, and the backend is actually set to nftables. docs/firewall.html.in | 33 +++++++++++++++++++++ src/network/bridge_driver_linux.c | 48 +++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/docs/firewall.html.in b/docs/firewall.html.in index 0a50687c26..5d584e582e 100644 --- a/docs/firewall.html.in +++ b/docs/firewall.html.in @@ -129,6 +129,39 @@ MASQUERADE all -- * * 192.168.122.0/24 = !192.168.122.0/24 =20 +

firewalld and th= e virtual network driver +

+

+ If firewalld is active on + the host, libvirt will attempt to place the bridge interface of + a libvirt virtual network into the firewalld zone named + "libvirt" (thus making all guest->host traffic on that network + subject to the rules of the "libvirt" zone). This is done + because, if firewalld is using its nftables backend (available + since firewalld 0.6.0) the default firewalld zone (which would + be used if libvirt didn't explicitly set the zone) prevents + forwarding traffic from guests through the bridge, as well as + preventing DHCP, DNS, and most other traffic from guests to + host. The zone named "libvirt" is installed into the firewalld + configuration by libvirt (not by firewalld), and allows + forwarded traffic through the bridge as well as DHCP, DNS, TFTP, + and SSH traffic to the host - depending on firewalld's backend + this will be implemented via either iptables or nftables + rules. libvirt's own rules outlined above will *always* be + iptables rules regardless of which backend is in use by + firewalld. +

+

+ 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 + the "libvirt" zone operate properly (rich rule priority + settings) was not implemented in firewalld. In cases where one + or the other of the two packages is missing the necessary + functionality, it's still possible to have functional guest + networking by setting the firewalld backend to "iptables" (in + firewalld prior to 0.6.0, this was the only backend available). +

+

The network filter driver

This driver provides a fully configurable network filtering capabil= ity diff --git a/src/network/bridge_driver_linux.c b/src/network/bridge_driver_= linux.c index e5e48c90f1..9d2e6877ae 100644 --- a/src/network/bridge_driver_linux.c +++ b/src/network/bridge_driver_linux.c @@ -27,6 +27,7 @@ #include "virstring.h" #include "virlog.h" #include "virfirewall.h" +#include "virfirewalld.h" =20 #define VIR_FROM_THIS VIR_FROM_NONE =20 @@ -670,6 +671,53 @@ int networkAddFirewallRules(virNetworkDefPtr def) virFirewallPtr fw =3D NULL; int ret =3D -1; =20 + /* 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() =3D=3D 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 (virFirewallDZoneExists("libvirt")) { + if (virFirewallDInterfaceSetZone(def->bridge, "libvirt") <= 0) + goto cleanup; + } else { + unsigned long version; + int vresult =3D virFirewallDGetVersion(&version); + + if (vresult < 0) + 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 >=3D 6000 && + virFirewallDGetBackend() =3D=3D 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 se= t " + "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; + } + } + } + fw =3D virFirewallNew(); =20 virFirewallStartTransaction(fw, 0); --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Fri Apr 26 14:11:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 154898433563537.31534465452364; Thu, 31 Jan 2019 17:25:35 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C3237CDDEC; Fri, 1 Feb 2019 01:25:33 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7B38F60C45; Fri, 1 Feb 2019 01:25:33 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 266263F606; Fri, 1 Feb 2019 01:25:33 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x111PEZ3002460 for ; Thu, 31 Jan 2019 20:25:14 -0500 Received: by smtp.corp.redhat.com (Postfix) id EE73E19742; Fri, 1 Feb 2019 01:25:13 +0000 (UTC) Received: from vhost2.laine.org (ovpn-117-140.phx2.redhat.com [10.3.117.140]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7D6A919741; Fri, 1 Feb 2019 01:25:13 +0000 (UTC) From: Laine Stump To: libvir-list@redhat.com Date: Thu, 31 Jan 2019 20:24:57 -0500 Message-Id: <20190201012458.25703-7-laine@laine.org> In-Reply-To: <20190201012458.25703-1-laine@laine.org> References: <20190201012458.25703-1-laine@laine.org> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-loop: libvir-list@redhat.com Cc: Eric Garver Subject: [libvirt] [PATCH v2 6/7] network: allow configuring firewalld zone for virtual network bridge device X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Fri, 01 Feb 2019 01:25:34 +0000 (UTC) Content-Type: text/plain; charset="utf-8" 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.: ... ... If a zone is specified in the config and it can't be honored, this will be an error. Signed-off-by: Laine Stump Reviewed-by: Daniel P. Berrang=C3=A9 --- Change from V1: move news.xml additions to a separate patch, as requested. docs/firewall.html.in | 5 +++++ docs/formatnetwork.html.in | 17 +++++++++++++++++ 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 | 19 +++++++++++++++++++ tests/networkxml2xmlin/routed-network.xml | 2 +- tests/networkxml2xmlout/routed-network.xml | 2 +- 9 files changed, 68 insertions(+), 4 deletions(-) diff --git a/docs/firewall.html.in b/docs/firewall.html.in index 5d584e582e..e86ab0d974 100644 --- a/docs/firewall.html.in +++ b/docs/firewall.html.in @@ -151,6 +151,11 @@ MASQUERADE all -- * * 192.168.122.0/24 = !192.168.122.0/24 iptables rules regardless of which backend is in use by firewalld.

+

+ 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. +

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 diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in index 156cfae4ec..509cca9e8b 100644 --- a/docs/formatnetwork.html.in +++ b/docs/formatnetwork.html.in @@ -152,6 +152,23 @@ Since 1.2.11, requires kernel 3.17 or newer

+ +

+ The optional zone attribute of + the bridge element is used to specify + the firewalld + zone for the bridge of a network with forward + mode of "nat", "route", "open", or one with + no forward 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). + Since 5.1.0 +

=20
mtu
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 @@ =20 + + + [a-zA-Z0-9_\-]+ + + + .+ 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 @@ =20 + + + + + + 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) =20 VIR_FREE(def->name); VIR_FREE(def->bridge); + VIR_FREE(def->bridgeZone); VIR_FREE(def->domain); =20 virNetworkForwardDefClear(&def->forward); @@ -1684,6 +1685,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) =20 /* Parse bridge information */ def->bridge =3D virXPathString("string(./bridge[1]/@name)", ctxt); + def->bridgeZone =3D virXPathString("string(./bridge[1]/@zone)", ctxt); stp =3D virXPathString("string(./bridge[1]/@stp)", ctxt); def->stp =3D (stp && STREQ(stp, "off")) ? false : true; =20 @@ -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; =20 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 i= n " "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, " zone=3D'%s'", def->bridgeZone); if (hasbridge) virBufferAsprintf(buf, " stp=3D'%s' delay=3D'%ld'", def->stp ? "on" : "off", def->delay); diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index c630674300..673f70cc68 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 = */ =20 char *bridge; /* Name of bridge device */ + char *bridgeZone; /* name of firewalld zone for bridge */ int macTableManager; /* enum virNetworkBridgeMACTableManager */ char *domain; int domainLocalOnly; /* enum virTristateBool: yes disables dns forward= ing */ diff --git a/src/network/bridge_driver_linux.c b/src/network/bridge_driver_= linux.c index 9d2e6877ae..b10d0a6c4d 100644 --- a/src/network/bridge_driver_linux.c +++ b/src/network/bridge_driver_linux.c @@ -671,6 +671,24 @@ int networkAddFirewallRules(virNetworkDefPtr def) virFirewallPtr fw =3D NULL; int ret =3D -1; =20 + 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 %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; + + } 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 @@ -717,6 +735,7 @@ int networkAddFirewallRules(virNetworkDefPtr def) } } } + } =20 fw =3D virFirewallNew(); =20 diff --git a/tests/networkxml2xmlin/routed-network.xml b/tests/networkxml2x= mlin/routed-network.xml index ab5e15b1f6..fce01df132 100644 --- a/tests/networkxml2xmlin/routed-network.xml +++ b/tests/networkxml2xmlin/routed-network.xml @@ -1,7 +1,7 @@ local 81ff0d90-c91e-6742-64da-4a736edb9a9b - + diff --git a/tests/networkxml2xmlout/routed-network.xml b/tests/networkxml2= xmlout/routed-network.xml index 81abf06e9f..2e13cf4ffa 100644 --- a/tests/networkxml2xmlout/routed-network.xml +++ b/tests/networkxml2xmlout/routed-network.xml @@ -4,7 +4,7 @@ - + --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Fri Apr 26 14:11:00 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1548984339090450.05502041941213; Thu, 31 Jan 2019 17:25:39 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 706477BDB1; Fri, 1 Feb 2019 01:25:36 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2313560C65; Fri, 1 Feb 2019 01:25:36 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id A629A18033A5; Fri, 1 Feb 2019 01:25:35 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x111PE36002465 for ; Thu, 31 Jan 2019 20:25:14 -0500 Received: by smtp.corp.redhat.com (Postfix) id 9CC941974C; Fri, 1 Feb 2019 01:25:14 +0000 (UTC) Received: from vhost2.laine.org (ovpn-117-140.phx2.redhat.com [10.3.117.140]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2A5DA19741; Fri, 1 Feb 2019 01:25:14 +0000 (UTC) From: Laine Stump To: libvir-list@redhat.com Date: Thu, 31 Jan 2019 20:24:58 -0500 Message-Id: <20190201012458.25703-8-laine@laine.org> In-Reply-To: <20190201012458.25703-1-laine@laine.org> References: <20190201012458.25703-1-laine@laine.org> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-loop: libvir-list@redhat.com Cc: Eric Garver Subject: [libvirt] [PATCH v2 7/7] docs: update news.xml for firewalld zone changes X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Fri, 01 Feb 2019 01:25:37 +0000 (UTC) Content-Type: text/plain; charset="utf-8" Signed-off-by: Laine Stump Reviewed-by: Daniel P. Berrang=C3=A9 --- New in V2. Split off from previous patch. docs/news.xml | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/docs/news.xml b/docs/news.xml index 5759a9e178..f47fec90b3 100644 --- a/docs/news.xml +++ b/docs/news.xml @@ -46,10 +46,50 @@ configuration. + + + network: support setting a firewalld "zone" for virtual network = bridges + + + All libvirt virtual networks with bridges managed by libvirt + (i.e. those with forward mode of "nat", "route", "open", or + no forward mode) will now be placed in a special firewalld + zone called "libvirt" by default. The zone of any network + bridge can be changed using the zone attribute + of the network's bridge element. + +
+ + + network: fix virtual networks on systems using firewalld+nftables + + + 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. However, 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 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 zone + attribute of the network bridge element). + +
--=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list