Blame SOURCES/0030-feat-AllowZoneDrifting-config-option.patch

66253d
From 982024e6775c9a9c78713be82519c729107ca4e2 Mon Sep 17 00:00:00 2001
66253d
From: Eric Garver <eric@garver.life>
66253d
Date: Sun, 19 Jan 2020 14:13:36 -0500
66253d
Subject: [PATCH 30/37] feat: AllowZoneDrifting config option
66253d
66253d
Older versions of firewalld had undocumented behavior known as "zone
66253d
drifting". This allowed packets to ingress multiple zones - this is a
66253d
violation of zone based firewalls. However, some users rely on this
66253d
behavior to have a "catch-all" zone, e.g. the default zone. You can
66253d
enable this if you desire such behavior. It's disabled by default for
66253d
security reasons.
66253d
66253d
Note: If "yes" packets will only drift from source based zones to
66253d
interface based zones (including the default zone). Packets never drift
66253d
from interface based zones to other interfaces based zones (including
66253d
the default zone).
66253d
66253d
(cherry picked from commit afadd377b09dc62b340d24bcf891d31f040d1a18)
66253d
(cherry picked from commit afbd6c0e82b77ca9b687169d69bf6c2dc17a9317)
66253d
---
66253d
 config/firewalld.conf                  | 12 ++++++++++++
66253d
 doc/xml/firewalld.conf.xml             | 19 +++++++++++++++++++
66253d
 doc/xml/firewalld.dbus.xml             | 16 ++++++++++++++++
66253d
 src/firewall/config/__init__.py.in     |  1 +
66253d
 src/firewall/core/fw.py                | 14 ++++++++++++++
66253d
 src/firewall/core/io/firewalld_conf.py | 13 +++++++++++--
66253d
 src/firewall/server/config.py          | 20 +++++++++++++++++---
66253d
 src/tests/dbus/firewalld.conf.at       |  3 +++
66253d
 8 files changed, 93 insertions(+), 5 deletions(-)
66253d
66253d
diff --git a/config/firewalld.conf b/config/firewalld.conf
66253d
index 82ad062b8a66..532f0452212e 100644
66253d
--- a/config/firewalld.conf
66253d
+++ b/config/firewalld.conf
66253d
@@ -61,3 +61,15 @@ FlushAllOnReload=yes
66253d
 # internet.
66253d
 # Defaults to "yes".
66253d
 RFC3964_IPv4=yes
66253d
+
66253d
+# AllowZoneDrifting
66253d
+# Older versions of firewalld had undocumented behavior known as "zone
66253d
+# drifting". This allowed packets to ingress multiple zones - this is a
66253d
+# violation of zone based firewalls. However, some users rely on this behavior
66253d
+# to have a "catch-all" zone, e.g. the default zone. You can enable this if you
66253d
+# desire such behavior. It's disabled by default for security reasons.
66253d
+# Note: If "yes" packets will only drift from source based zones to interface
66253d
+# based zones (including the default zone). Packets never drift from interface
66253d
+# based zones to other interfaces based zones (including the default zone).
66253d
+# Possible values; "yes", "no". Defaults to "no".
66253d
+AllowZoneDrifting=no
66253d
diff --git a/doc/xml/firewalld.conf.xml b/doc/xml/firewalld.conf.xml
66253d
index 6003a6fae855..fcfbfd2b68c1 100644
66253d
--- a/doc/xml/firewalld.conf.xml
66253d
+++ b/doc/xml/firewalld.conf.xml
66253d
@@ -183,6 +183,25 @@
66253d
             </listitem>
66253d
         </varlistentry>
66253d
 
66253d
+        <varlistentry>
66253d
+            <term><option>AllowZoneDrifting</option></term>
66253d
+            <listitem>
66253d
+                <para>
66253d
+                Older versions of firewalld had undocumented behavior known
66253d
+                as "zone drifting". This allowed packets to ingress multiple
66253d
+                zones - this is a violation of zone based firewalls. However,
66253d
+                some users rely on this behavior to have a "catch-all" zone,
66253d
+                e.g. the default zone. You can enable this if you desire such
66253d
+                behavior. It's disabled by default for security reasons.
66253d
+                Note: If "yes" packets will only drift from source based zones
66253d
+                to interface based zones (including the default zone). Packets
66253d
+                never drift from interface based zones to other interfaces
66253d
+                based zones (including the default zone).
66253d
+                Valid values; "yes", "no". Defaults to "no".
66253d
+                </para>
66253d
+            </listitem>
66253d
+        </varlistentry>
66253d
+
66253d
     </variablelist>
66253d
 
66253d
   </refsect1>
66253d
diff --git a/doc/xml/firewalld.dbus.xml b/doc/xml/firewalld.dbus.xml
66253d
index 66b0475ec0c8..5d77af976443 100644
66253d
--- a/doc/xml/firewalld.dbus.xml
66253d
+++ b/doc/xml/firewalld.dbus.xml
66253d
@@ -2578,6 +2578,22 @@
66253d
       <refsect3 id="FirewallD1.config.Properties">
66253d
         <title>Properties</title>
66253d
         <variablelist>
66253d
+          <varlistentry id="FirewallD1.config.Properties.AllowZoneDrifting">
66253d
+            <term><parameter>AllowZoneDrifting</parameter> - s - (rw)</term>
66253d
+            <listitem><para>
66253d
+                Older versions of firewalld had undocumented behavior known
66253d
+                as "zone drifting". This allowed packets to ingress multiple
66253d
+                zones - this is a violation of zone based firewalls. However,
66253d
+                some users rely on this behavior to have a "catch-all" zone,
66253d
+                e.g. the default zone. You can enable this if you desire such
66253d
+                behavior. It's disabled by default for security reasons.
66253d
+                Note: If "yes" packets will only drift from source based zones
66253d
+                to interface based zones (including the default zone). Packets
66253d
+                never drift from interface based zones to other interfaces
66253d
+                based zones (including the default zone).
66253d
+                Valid values; "yes", "no". Defaults to "no".
66253d
+            </para></listitem>
66253d
+          </varlistentry>
66253d
           <varlistentry id="FirewallD1.config.Properties.AutomaticHelpers">
66253d
             <term>AutomaticHelpers - s - (rw)</term>
66253d
             <listitem>
66253d
diff --git a/src/firewall/config/__init__.py.in b/src/firewall/config/__init__.py.in
66253d
index 3274dd430e4e..481eb8de758d 100644
66253d
--- a/src/firewall/config/__init__.py.in
66253d
+++ b/src/firewall/config/__init__.py.in
66253d
@@ -130,3 +130,4 @@ FALLBACK_AUTOMATIC_HELPERS = "no"
66253d
 FALLBACK_FIREWALL_BACKEND = "nftables"
66253d
 FALLBACK_FLUSH_ALL_ON_RELOAD = True
66253d
 FALLBACK_RFC3964_IPV4 = True
66253d
+FALLBACK_ALLOW_ZONE_DRIFTING = False
66253d
diff --git a/src/firewall/core/fw.py b/src/firewall/core/fw.py
66253d
index 050fb9cd976d..6206ed586988 100644
66253d
--- a/src/firewall/core/fw.py
66253d
+++ b/src/firewall/core/fw.py
66253d
@@ -123,6 +123,7 @@ class Firewall(object):
66253d
         self._firewall_backend = config.FALLBACK_FIREWALL_BACKEND
66253d
         self._flush_all_on_reload = config.FALLBACK_FLUSH_ALL_ON_RELOAD
66253d
         self._rfc3964_ipv4 = config.FALLBACK_RFC3964_IPV4
66253d
+        self._allow_zone_drifting = config.FALLBACK_ALLOW_ZONE_DRIFTING
66253d
 
66253d
     def individual_calls(self):
66253d
         return self._individual_calls
66253d
@@ -286,6 +287,19 @@ class Firewall(object):
66253d
                 log.debug1("RFC3964_IPv4 is set to '%s'",
66253d
                            self._rfc3964_ipv4)
66253d
 
66253d
+            if self._firewalld_conf.get("AllowZoneDrifting"):
66253d
+                value = self._firewalld_conf.get("AllowZoneDrifting")
66253d
+                if value.lower() in [ "no", "false" ]:
66253d
+                    self._allow_zone_drifting = False
66253d
+                else:
66253d
+                    self._allow_zone_drifting = True
66253d
+                    log.warning("AllowZoneDrifting is enabled. This is considered "
66253d
+                                "an insecure configuration option. It will be "
66253d
+                                "removed in a future release. Please consider "
66253d
+                                "disabling it now.")
66253d
+                log.debug1("AllowZoneDrifting is set to '%s'",
66253d
+                           self._allow_zone_drifting)
66253d
+
66253d
         self.config.set_firewalld_conf(copy.deepcopy(self._firewalld_conf))
66253d
 
66253d
         self._select_firewall_backend(self._firewall_backend)
66253d
diff --git a/src/firewall/core/io/firewalld_conf.py b/src/firewall/core/io/firewalld_conf.py
66253d
index 9e2205f93d63..7c7092120676 100644
66253d
--- a/src/firewall/core/io/firewalld_conf.py
66253d
+++ b/src/firewall/core/io/firewalld_conf.py
66253d
@@ -28,10 +28,10 @@ from firewall import config
66253d
 from firewall.core.logger import log
66253d
 from firewall.functions import b2u, u2b, PY2
66253d
 
66253d
-valid_keys = [ "DefaultZone", "MinimalMark", "CleanupOnExit", "Lockdown", 
66253d
+valid_keys = [ "DefaultZone", "MinimalMark", "CleanupOnExit", "Lockdown",
66253d
                "IPv6_rpfilter", "IndividualCalls", "LogDenied",
66253d
                "AutomaticHelpers", "FirewallBackend", "FlushAllOnReload",
66253d
-               "RFC3964_IPv4" ]
66253d
+               "RFC3964_IPv4", "AllowZoneDrifting" ]
66253d
 
66253d
 class firewalld_conf(object):
66253d
     def __init__(self, filename):
66253d
@@ -83,6 +83,7 @@ class firewalld_conf(object):
66253d
             self.set("FirewallBackend", config.FALLBACK_FIREWALL_BACKEND)
66253d
             self.set("FlushAllOnReload", "yes" if config.FALLBACK_FLUSH_ALL_ON_RELOAD else "no")
66253d
             self.set("RFC3964_IPv4", "yes" if config.FALLBACK_RFC3964_IPV4 else "no")
66253d
+            self.set("AllowZoneDrifting", "yes" if config.FALLBACK_ALLOW_ZONE_DRIFTING else "no")
66253d
             raise
66253d
 
66253d
         for line in f:
66253d
@@ -202,6 +203,14 @@ class firewalld_conf(object):
66253d
                             config.FALLBACK_RFC3964_IPV4)
66253d
             self.set("RFC3964_IPv4", str(config.FALLBACK_RFC3964_IPV4))
66253d
 
66253d
+        value = self.get("AllowZoneDrifting")
66253d
+        if not value or value.lower() not in [ "yes", "true", "no", "false" ]:
66253d
+            if value is not None:
66253d
+                log.warning("AllowZoneDrifting '%s' is not valid, using default "
66253d
+                            "value %s", value if value else '',
66253d
+                            config.FALLBACK_ALLOW_ZONE_DRIFTING)
66253d
+            self.set("AllowZoneDrifting", str(config.FALLBACK_ALLOW_ZONE_DRIFTING))
66253d
+
66253d
     # save to self.filename if there are key/value changes
66253d
     def write(self):
66253d
         if len(self._config) < 1:
66253d
diff --git a/src/firewall/server/config.py b/src/firewall/server/config.py
66253d
index 1c35f5663d29..b3e193d7e468 100644
66253d
--- a/src/firewall/server/config.py
66253d
+++ b/src/firewall/server/config.py
66253d
@@ -107,6 +107,7 @@ class FirewallDConfig(slip.dbus.service.Object):
66253d
                                                 "FirewallBackend": "readwrite",
66253d
                                                 "FlushAllOnReload": "readwrite",
66253d
                                                 "RFC3964_IPv4": "readwrite",
66253d
+                                                "AllowZoneDrifting": "readwrite",
66253d
                                               })
66253d
 
66253d
     @handle_exceptions
66253d
@@ -487,7 +488,8 @@ class FirewallDConfig(slip.dbus.service.Object):
66253d
         if prop not in [ "DefaultZone", "MinimalMark", "CleanupOnExit",
66253d
                          "Lockdown", "IPv6_rpfilter", "IndividualCalls",
66253d
                          "LogDenied", "AutomaticHelpers", "FirewallBackend",
66253d
-                         "FlushAllOnReload", "RFC3964_IPv4" ]:
66253d
+                         "FlushAllOnReload", "RFC3964_IPv4",
66253d
+                         "AllowZoneDrifting" ]:
66253d
             raise dbus.exceptions.DBusException(
66253d
                 "org.freedesktop.DBus.Error.InvalidArgs: "
66253d
                 "Property '%s' does not exist" % prop)
66253d
@@ -540,6 +542,10 @@ class FirewallDConfig(slip.dbus.service.Object):
66253d
             if value is None:
66253d
                 value = "yes" if config.FALLBACK_RFC3964_IPV4 else "no"
66253d
             return dbus.String(value)
66253d
+        elif prop == "AllowZoneDrifting":
66253d
+            if value is None:
66253d
+                value = "yes" if config.FALLBACK_ALLOW_ZONE_DRIFTING else "no"
66253d
+            return dbus.String(value)
66253d
 
66253d
     @dbus_handle_exceptions
66253d
     def _get_dbus_property(self, prop):
66253d
@@ -565,6 +571,8 @@ class FirewallDConfig(slip.dbus.service.Object):
66253d
             return dbus.String(self._get_property(prop))
66253d
         elif prop == "RFC3964_IPv4":
66253d
             return dbus.String(self._get_property(prop))
66253d
+        elif prop == "AllowZoneDrifting":
66253d
+            return dbus.String(self._get_property(prop))
66253d
         else:
66253d
             raise dbus.exceptions.DBusException(
66253d
                 "org.freedesktop.DBus.Error.InvalidArgs: "
66253d
@@ -605,7 +613,8 @@ class FirewallDConfig(slip.dbus.service.Object):
66253d
             for x in [ "DefaultZone", "MinimalMark", "CleanupOnExit",
66253d
                        "Lockdown", "IPv6_rpfilter", "IndividualCalls",
66253d
                        "LogDenied", "AutomaticHelpers", "FirewallBackend",
66253d
-                       "FlushAllOnReload", "RFC3964_IPv4" ]:
66253d
+                       "FlushAllOnReload", "RFC3964_IPv4",
66253d
+                       "AllowZoneDrifting" ]:
66253d
                 ret[x] = self._get_property(x)
66253d
         elif interface_name in [ config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
66253d
                                  config.dbus.DBUS_INTERFACE_CONFIG_POLICIES ]:
66253d
@@ -633,7 +642,7 @@ class FirewallDConfig(slip.dbus.service.Object):
66253d
                                   "IPv6_rpfilter", "IndividualCalls",
66253d
                                   "LogDenied", "AutomaticHelpers",
66253d
                                   "FirewallBackend", "FlushAllOnReload",
66253d
-                                  "RFC3964_IPv4" ]:
66253d
+                                  "RFC3964_IPv4", "AllowZoneDrifting" ]:
66253d
                 if property_name == "MinimalMark":
66253d
                     try:
66253d
                         int(new_value)
66253d
@@ -677,6 +686,11 @@ class FirewallDConfig(slip.dbus.service.Object):
66253d
                         raise FirewallError(errors.INVALID_VALUE,
66253d
                                             "'%s' for %s" % \
66253d
                                             (new_value, property_name))
66253d
+                if property_name == "AllowZoneDrifting":
66253d
+                    if new_value.lower() not in ["yes", "true", "no", "false"]:
66253d
+                        raise FirewallError(errors.INVALID_VALUE,
66253d
+                                            "'%s' for %s" % \
66253d
+                                            (new_value, property_name))
66253d
 
66253d
                 self.config.get_firewalld_conf().set(property_name, new_value)
66253d
                 self.config.get_firewalld_conf().write()
66253d
diff --git a/src/tests/dbus/firewalld.conf.at b/src/tests/dbus/firewalld.conf.at
66253d
index 06f6df9bdd70..35aead759a9c 100644
66253d
--- a/src/tests/dbus/firewalld.conf.at
66253d
+++ b/src/tests/dbus/firewalld.conf.at
66253d
@@ -4,6 +4,7 @@ AT_KEYWORDS(dbus)
66253d
 dnl Verify defaults over dbus. Should be inline with default firewalld.conf.
66253d
 IF_HOST_SUPPORTS_NFT_FIB([
66253d
 DBUS_GETALL([config], [config], 0, [dnl
66253d
+string "AllowZoneDrifting" : variant string "no"
66253d
 string "AutomaticHelpers" : variant string "no"
66253d
 string "CleanupOnExit" : variant string "no"
66253d
 string "DefaultZone" : variant string "public"
66253d
@@ -17,6 +18,7 @@ string "MinimalMark" : variant int32 100
66253d
 string "RFC3964_IPv4" : variant string "yes"
66253d
 ])], [
66253d
 DBUS_GETALL([config], [config], 0, [dnl
66253d
+string "AllowZoneDrifting" : variant string "no"
66253d
 string "AutomaticHelpers" : variant string "no"
66253d
 string "CleanupOnExit" : variant string "no"
66253d
 string "DefaultZone" : variant string "public"
66253d
@@ -49,6 +51,7 @@ _helper([FirewallBackend], [string:"iptables"], [variant string "iptables"])
66253d
 _helper([FlushAllOnReload], [string:"no"], [variant string "no"])
66253d
 _helper([CleanupOnExit], [string:"yes"], [variant string "yes"])
66253d
 _helper([RFC3964_IPv4], [string:"no"], [variant string "no"])
66253d
+_helper([AllowZoneDrifting], [string:"yes"], [variant string "yes"])
66253d
 dnl Note: DefaultZone is RO
66253d
 m4_undefine([_helper])
66253d
 
66253d
-- 
66253d
2.23.0
66253d