From c8b5bf402d20077a73c15d55fc90c26e97119711 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 8 May 2020 09:09:25 +0200 Subject: [PATCH 1/3] build: install a firewalld zone for shared mode Install a NM-specific firewalld zone to be used for interfaces that are used for connection sharing. The zone blocks all traffic to the local machine except some protocols (DHCP, DNS and ICMP) and allows all forwarded traffic. --- Makefile.am | 6 ++++++ config.h.meson | 3 +++ configure.ac | 13 +++++++++++++ data/meson.build | 7 +++++++ data/nm-shared.xml | 23 +++++++++++++++++++++++ meson.build | 4 ++++ meson_options.txt | 1 + 7 files changed, 57 insertions(+) create mode 100644 data/nm-shared.xml diff --git a/Makefile.am b/Makefile.am index d8cd32fab9..ae3f1fc006 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4903,6 +4903,11 @@ data/server.conf: $(srcdir)/data/server.conf.in @$(MKDIR_P) data/ $(AM_V_GEN) $(data_edit) $< >$@ +if WITH_FIREWALLD_ZONE +firewalldzonedir = $(prefix)/lib/firewalld/zones +firewalldzone_DATA = data/nm-shared.xml +endif + EXTRA_DIST += \ data/84-nm-drivers.rules \ data/85-nm-unmanaged.rules \ @@ -4912,6 +4917,7 @@ EXTRA_DIST += \ data/NetworkManager-wait-online.service.in \ data/NetworkManager.service.in \ data/meson.build \ + data/nm-shared.xml \ data/server.conf.in \ $(NULL) diff --git a/config.h.meson b/config.h.meson index 009c635da4..b421ee1e71 100644 --- a/config.h.meson +++ b/config.h.meson @@ -233,6 +233,9 @@ /* Define if you have iwd support */ #mesondefine WITH_IWD +/* Define if NetworkManager uses a custom zone for shared mode */ +#mesondefine WITH_FIREWALLD_ZONE + /* Define to 1 if on MINIX. */ #mesondefine _MINIX diff --git a/configure.ac b/configure.ac index 960f957afd..5b11a13b76 100644 --- a/configure.ac +++ b/configure.ac @@ -673,6 +673,18 @@ else fi AC_SUBST(NM_MODIFY_SYSTEM_POLICY) +AC_ARG_ENABLE(firewalld-zone, + AS_HELP_STRING([--enable-firewalld-zone], [Install and use firewalld zone for shared mode]), + [enable_firewalld_zone=${enableval}], + [enable_firewalld_zone=yes]) + +if test "${enable_firewalld_zone}" = "yes"; then + AC_DEFINE(WITH_FIREWALLD_ZONE, 1, [Define if NetworkManager uses a custom zone for shared mode]) +else + AC_DEFINE(WITH_FIREWALLD_ZONE, 0, [Define if NetworkManager uses a custom zone for shared mode]) +fi +AM_CONDITIONAL(WITH_FIREWALLD_ZONE, test "${enable_firewalld_zone}" = "yes") + PKG_CHECK_MODULES(GNUTLS, [gnutls >= 2.12], [have_crypto_gnutls=yes], [have_crypto_gnutls=no]) PKG_CHECK_MODULES(NSS, [nss], [have_crypto_nss=yes], [have_crypto_nss=yes]) if test "${have_crypto_nss}" = "yes"; then @@ -1370,6 +1382,7 @@ echo "Miscellaneous:" echo " have introspection: $have_introspection" echo " build documentation and manpages: $build_docs" echo " install pregenerated documentation and manpages: $use_pregen_docs" +echo " install and use firewalld shared zone: $enable_firewalld_zone" echo " tests: $enable_tests" echo " more-asserts: $more_asserts" echo " more-logging: $enable_more_logging" diff --git a/data/meson.build b/data/meson.build index de08c91c62..b713a03c5a 100644 --- a/data/meson.build +++ b/data/meson.build @@ -67,3 +67,10 @@ if enable_polkit install_dir: polkit_gobject_policydir, ) endif + +if enable_firewalld_zone + install_data( + 'nm-shared.xml', + install_dir: join_paths(nm_prefix, 'lib', 'firewalld', 'zones') + ) +endif diff --git a/data/nm-shared.xml b/data/nm-shared.xml new file mode 100644 index 0000000000..0dea5dd6ee --- /dev/null +++ b/data/nm-shared.xml @@ -0,0 +1,23 @@ + + + NetworkManager Shared + + + This zone is used internally by NetworkManager when activating a + profile that uses connection sharing and doesn't have an explicit + firewall zone set. + Block all traffic to the local machine except ICMP, ICMPv6, DHCP + and DNS. Allow all forwarded traffic. + Note that future package updates may change the definition of the + zone unless you overwrite it with your own definition. + + + + + + + + + + + diff --git a/meson.build b/meson.build index a2d925a7e5..e2c83d2b57 100644 --- a/meson.build +++ b/meson.build @@ -550,6 +550,9 @@ endif dbus_interfaces_dir = dbus_dep.get_pkgconfig_variable('interfaces_dir', define_variable: ['datadir', nm_datadir]) dbus_system_bus_services_dir = dbus_dep.get_pkgconfig_variable('system_bus_services_dir', define_variable: ['datadir', nm_datadir]) +enable_firewalld_zone = get_option('firewalld_zone') +config_h.set10('WITH_FIREWALLD_ZONE', enable_firewalld_zone) + # pppd enable_ppp = get_option('ppp') if enable_ppp @@ -1028,6 +1031,7 @@ output += '\n' output += '\nMiscellaneous:\n' output += ' have introspection: ' + enable_introspection.to_string() + '\n' output += ' build documentation and manpages: ' + enable_docs.to_string() + '\n' +output += ' firewalld zone for shared mode: ' + enable_firewalld_zone.to_string() + '\n' # FIXME #output += ' install pregenerated documentation and manpages: no output += ' tests: ' + tests + '\n' diff --git a/meson_options.txt b/meson_options.txt index 041d9bfc38..a5c6a22fb0 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -62,6 +62,7 @@ option('introspection', type: 'boolean', value: true, description: 'Enable intro option('vapi', type : 'combo', choices : ['auto', 'true', 'false'], description: 'build Vala bindings') option('docs', type: 'boolean', value: false, description: 'use to build documentation') option('tests', type: 'combo', choices: ['yes', 'no', 'root'], value: 'yes', description: 'Build NetworkManager tests') +option('firewalld_zone', type: 'boolean', value: true, description: 'Install and use firewalld zone for shared mode') option('more_asserts', type: 'string', value: 'all', description: 'Enable more assertions for debugging (0 = none, 100 = all, default: all)') option('more_logging', type: 'boolean', value: true, description: 'Enable more debug logging') option('valgrind', type: 'array', value: ['no'], description: 'Use valgrind to memory-check the tests') From 3e2b723532a0fa390b533eccb72084adf3911c9c Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 8 May 2020 09:12:33 +0200 Subject: [PATCH 2/3] device: use the nm-shared firewalld zone in shared mode When the interface is in IPv4 or IPv6 shared mode and the user didn't specify an explicit zone, use the nm-shared one. Note that masquerade is still done through iptables direct calls because at the moment it is not possible for a firewalld zone to do masquerade based on the input interface. The firewalld zone is needed on systems where firewalld is using the nftables backend and the 'iptables' binary uses the iptables API (instead of the nftables one). On such systems, even if the traffic is allowed in iptables by our direct rules, it can still be dropped in nftables by firewalld. --- NEWS | 8 ++++++++ src/devices/nm-device.c | 13 ++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 2b87553835..c63f24581a 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,14 @@ The API is subject to change and not guaranteed to be compatible with the later release. USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE! +* Add a new build option 'firewalld-zone'; when enabled, + NetworkManager installs a firewalld zone for connection sharing and + puts interfaces using IPv4 or IPv6 shared mode in this zone during + activation. The option is enabled by default. + Note that NetworkManager still calls to iptables to enable + masquerading and open needed ports for DHCP and DNS. The new option + is useful on systems using firewalld with the nftables backend, + where the iptables rules would not be sufficient. * Add MUD URL property for connection profiles (RFC 8520) and set it for DHCP and DHCPv6 requests. * IPv6 SLAAC: improved the reaction of IPv6 SLAAC to renumbering events: diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index de72b1d15a..66eea16ce4 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -11156,6 +11156,7 @@ fw_change_zone (NMDevice *self) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *applied_connection; NMSettingConnection *s_con; + const char *zone; nm_assert (priv->fw_state >= FIREWALL_STATE_INITIALIZED); @@ -11173,9 +11174,19 @@ fw_change_zone (NMDevice *self) if (G_UNLIKELY (!priv->fw_mgr)) priv->fw_mgr = g_object_ref (nm_firewall_manager_get ()); + zone = nm_setting_connection_get_zone (s_con); +#if WITH_FIREWALLD_ZONE + if (!zone || zone[0] == '\0') { + if ( nm_streq0 (nm_device_get_effective_ip_config_method (self, AF_INET), + NM_SETTING_IP4_CONFIG_METHOD_SHARED) + || nm_streq0 (nm_device_get_effective_ip_config_method (self, AF_INET6), + NM_SETTING_IP6_CONFIG_METHOD_SHARED)) + zone = "nm-shared"; + } +#endif priv->fw_call = nm_firewall_manager_add_or_change_zone (priv->fw_mgr, nm_device_get_ip_iface (self), - nm_setting_connection_get_zone (s_con), + zone, FALSE, /* change zone */ fw_change_zone_cb, self); From 016a82e6dd8e4f8b0d87a59868ca1231efec27ee Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 8 May 2020 09:20:25 +0200 Subject: [PATCH 3/3] contrib/rpm: enable the firewalld zone in F32 and RHEL8 --- contrib/fedora/REQUIRED_PACKAGES | 1 + contrib/fedora/rpm/NetworkManager.spec | 27 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/contrib/fedora/REQUIRED_PACKAGES b/contrib/fedora/REQUIRED_PACKAGES index 0850bc345f..f03eebfb00 100755 --- a/contrib/fedora/REQUIRED_PACKAGES +++ b/contrib/fedora/REQUIRED_PACKAGES @@ -47,6 +47,7 @@ install \ dbus-devel \ dbus-x11 \ dhclient \ + firewalld-filesystem \ gcc-c++ \ gettext-devel \ git \ diff --git a/contrib/fedora/rpm/NetworkManager.spec b/contrib/fedora/rpm/NetworkManager.spec index ffbd1092c9..59406e5b23 100644 --- a/contrib/fedora/rpm/NetworkManager.spec +++ b/contrib/fedora/rpm/NetworkManager.spec @@ -81,6 +81,11 @@ %else %bcond_without iwd %endif +%if 0%{?fedora} > 31 || 0%{?rhel} > 7 +%bcond_without firewalld_zone +%else +%bcond_with firewalld_zone +%endif ############################################################################### @@ -242,6 +247,9 @@ BuildRequires: libasan BuildRequires: libubsan %endif %endif +%if %{with firewalld_zone} +BuildRequires: firewalld-filesystem +%endif Provides: %{name}-dispatcher%{?_isa} = %{epoch}:%{version}-%{release} @@ -609,6 +617,11 @@ This tool is still experimental. -Dpppd_plugin_dir=%{_libdir}/pppd/%{ppp_version} \ -Dppp=true \ %endif +%if %{with firewalld_zone} + -Dfirewalld_zone=true \ +%else + -Dfirewalld_zone=false \ +%endif -Ddist_version=%{version}-%{release} \ -Dconfig_plugins_default=%{config_plugins_default} \ -Dconfig_dns_rc_manager_default=%{dns_rc_manager_default} \ @@ -742,6 +755,11 @@ intltoolize --automake --copy --force --with-pppd-plugin-dir=%{_libdir}/pppd/%{ppp_version} \ --enable-ppp=yes \ %endif +%if %{with firewalld_zone} + --enable-firewalld-zone \ +%else + --disable-firewalld-zone \ +%endif --with-dist-version=%{version}-%{release} \ --with-config-plugins-default=%{config_plugins_default} \ --with-config-dns-rc-manager-default=%{dns_rc_manager_default} \ @@ -824,6 +842,9 @@ fi %post /usr/bin/udevadm control --reload-rules || : /usr/bin/udevadm trigger --subsystem-match=net || : +%if %{with firewalld_zone} +%firewalld_reload +%endif %systemd_post %{systemd_units} @@ -865,6 +886,9 @@ fi %postun /usr/bin/udevadm control --reload-rules || : /usr/bin/udevadm trigger --subsystem-match=net || : +%if %{with firewalld_zone} +%firewalld_reload +%endif %systemd_postun %{systemd_units} @@ -930,6 +954,9 @@ fi %{_datadir}/dbus-1/system-services/org.freedesktop.nm_dispatcher.service %{_datadir}/polkit-1/actions/*.policy %{_prefix}/lib/udev/rules.d/*.rules +%if %{with firewalld_zone} +%{_prefix}/lib/firewalld/zones/nm-shared.xml +%endif # systemd stuff %{systemd_dir}/NetworkManager.service %{systemd_dir}/NetworkManager-wait-online.service