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

bb602c
From eeb2b58b84e6a61d5c212e78e2cf1a44846d5301 Mon Sep 17 00:00:00 2001
bb602c
From: Eric Garver <eric@garver.life>
bb602c
Date: Sun, 19 Jan 2020 14:13:36 -0500
bb602c
Subject: [PATCH 139/146] feat: AllowZoneDrifting config option
bb602c
bb602c
Older versions of firewalld had undocumented behavior known as "zone
bb602c
drifting". This allowed packets to ingress multiple zones - this is a
bb602c
violation of zone based firewalls. However, some users rely on this
bb602c
behavior to have a "catch-all" zone, e.g. the default zone. You can
bb602c
enable this if you desire such behavior. It's disabled by default for
bb602c
security reasons.
bb602c
bb602c
Note: If "yes" packets will only drift from source based zones to
bb602c
interface based zones (including the default zone). Packets never drift
bb602c
from interface based zones to other interfaces based zones (including
bb602c
the default zone).
bb602c
bb602c
(cherry picked from commit afadd377b09dc62b340d24bcf891d31f040d1a18)
bb602c
(cherry picked from commit 3bbd15a5317b59e175e2a060d1a6ecf4c2129b32)
bb602c
---
bb602c
 config/firewalld.conf                  | 12 ++++++++++++
bb602c
 doc/xml/firewalld.conf.xml             | 19 +++++++++++++++++++
bb602c
 doc/xml/firewalld.dbus.xml             | 16 ++++++++++++++++
bb602c
 src/firewall/config/__init__.py.in     |  1 +
bb602c
 src/firewall/core/fw.py                | 14 ++++++++++++++
bb602c
 src/firewall/core/io/firewalld_conf.py | 13 +++++++++++--
bb602c
 src/firewall/server/config.py          | 20 +++++++++++++++++---
bb602c
 src/tests/dbus/firewalld.conf.at       |  3 +++
bb602c
 8 files changed, 93 insertions(+), 5 deletions(-)
bb602c
bb602c
diff --git a/config/firewalld.conf b/config/firewalld.conf
bb602c
index 63df409bf567..02be07b9b892 100644
bb602c
--- a/config/firewalld.conf
bb602c
+++ b/config/firewalld.conf
bb602c
@@ -55,3 +55,15 @@ LogDenied=off
bb602c
 # will be used. Possible values are: yes, no and system.
bb602c
 # Default: system
bb602c
 AutomaticHelpers=system
bb602c
+
bb602c
+# AllowZoneDrifting
bb602c
+# Older versions of firewalld had undocumented behavior known as "zone
bb602c
+# drifting". This allowed packets to ingress multiple zones - this is a
bb602c
+# violation of zone based firewalls. However, some users rely on this behavior
bb602c
+# to have a "catch-all" zone, e.g. the default zone. You can enable this if you
bb602c
+# desire such behavior. It's disabled by default for security reasons.
bb602c
+# Note: If "yes" packets will only drift from source based zones to interface
bb602c
+# based zones (including the default zone). Packets never drift from interface
bb602c
+# based zones to other interfaces based zones (including the default zone).
bb602c
+# Possible values; "yes", "no". Defaults to "no".
bb602c
+AllowZoneDrifting=no
bb602c
diff --git a/doc/xml/firewalld.conf.xml b/doc/xml/firewalld.conf.xml
bb602c
index afb94b90937f..9d8017df3112 100644
bb602c
--- a/doc/xml/firewalld.conf.xml
bb602c
+++ b/doc/xml/firewalld.conf.xml
bb602c
@@ -144,6 +144,25 @@
bb602c
 	</listitem>
bb602c
       </varlistentry>
bb602c
 
bb602c
+        <varlistentry>
bb602c
+            <term><option>AllowZoneDrifting</option></term>
bb602c
+            <listitem>
bb602c
+                <para>
bb602c
+                Older versions of firewalld had undocumented behavior known
bb602c
+                as "zone drifting". This allowed packets to ingress multiple
bb602c
+                zones - this is a violation of zone based firewalls. However,
bb602c
+                some users rely on this behavior to have a "catch-all" zone,
bb602c
+                e.g. the default zone. You can enable this if you desire such
bb602c
+                behavior. It's disabled by default for security reasons.
bb602c
+                Note: If "yes" packets will only drift from source based zones
bb602c
+                to interface based zones (including the default zone). Packets
bb602c
+                never drift from interface based zones to other interfaces
bb602c
+                based zones (including the default zone).
bb602c
+                Valid values; "yes", "no". Defaults to "no".
bb602c
+                </para>
bb602c
+            </listitem>
bb602c
+        </varlistentry>
bb602c
+
bb602c
     </variablelist>
bb602c
 
bb602c
   </refsect1>
bb602c
diff --git a/doc/xml/firewalld.dbus.xml b/doc/xml/firewalld.dbus.xml
bb602c
index ec82d4cad077..ea0be9cefd1c 100644
bb602c
--- a/doc/xml/firewalld.dbus.xml
bb602c
+++ b/doc/xml/firewalld.dbus.xml
bb602c
@@ -2558,6 +2558,22 @@
bb602c
       <refsect3 id="FirewallD1.config.Properties">
bb602c
         <title>Properties</title>
bb602c
         <variablelist>
bb602c
+          <varlistentry id="FirewallD1.config.Properties.AllowZoneDrifting">
bb602c
+            <term><parameter>AllowZoneDrifting</parameter> - s - (rw)</term>
bb602c
+            <listitem><para>
bb602c
+                Older versions of firewalld had undocumented behavior known
bb602c
+                as "zone drifting". This allowed packets to ingress multiple
bb602c
+                zones - this is a violation of zone based firewalls. However,
bb602c
+                some users rely on this behavior to have a "catch-all" zone,
bb602c
+                e.g. the default zone. You can enable this if you desire such
bb602c
+                behavior. It's disabled by default for security reasons.
bb602c
+                Note: If "yes" packets will only drift from source based zones
bb602c
+                to interface based zones (including the default zone). Packets
bb602c
+                never drift from interface based zones to other interfaces
bb602c
+                based zones (including the default zone).
bb602c
+                Valid values; "yes", "no". Defaults to "no".
bb602c
+            </para></listitem>
bb602c
+          </varlistentry>
bb602c
           <varlistentry id="FirewallD1.config.Properties.AutomaticHelpers">
bb602c
             <term>AutomaticHelpers - s - (rw)</term>
bb602c
             <listitem>
bb602c
diff --git a/src/firewall/config/__init__.py.in b/src/firewall/config/__init__.py.in
bb602c
index 1b2168bde44d..3926c8fdb3a3 100644
bb602c
--- a/src/firewall/config/__init__.py.in
bb602c
+++ b/src/firewall/config/__init__.py.in
bb602c
@@ -128,3 +128,4 @@ FALLBACK_INDIVIDUAL_CALLS = False
bb602c
 FALLBACK_LOG_DENIED = "off"
bb602c
 FALLBACK_AUTOMATIC_HELPERS = "system"
bb602c
 FALLBACK_FIREWALL_BACKEND = "iptables"
bb602c
+FALLBACK_ALLOW_ZONE_DRIFTING = False
bb602c
diff --git a/src/firewall/core/fw.py b/src/firewall/core/fw.py
bb602c
index b1643a1ebff4..5d3cf6e6ce44 100644
bb602c
--- a/src/firewall/core/fw.py
bb602c
+++ b/src/firewall/core/fw.py
bb602c
@@ -114,6 +114,7 @@ class Firewall(object):
bb602c
         self._automatic_helpers = config.FALLBACK_AUTOMATIC_HELPERS
bb602c
         self._firewall_backend = config.FALLBACK_FIREWALL_BACKEND
bb602c
         self.nf_conntrack_helper_setting = 0
bb602c
+        self._allow_zone_drifting = config.FALLBACK_ALLOW_ZONE_DRIFTING
bb602c
 
bb602c
     def individual_calls(self):
bb602c
         return self._individual_calls
bb602c
@@ -269,6 +270,19 @@ class Firewall(object):
bb602c
                     log.debug1("AutomaticHelpers is set to '%s'",
bb602c
                                self._automatic_helpers)
bb602c
 
bb602c
+            if self._firewalld_conf.get("AllowZoneDrifting"):
bb602c
+                value = self._firewalld_conf.get("AllowZoneDrifting")
bb602c
+                if value.lower() in [ "no", "false" ]:
bb602c
+                    self._allow_zone_drifting = False
bb602c
+                else:
bb602c
+                    self._allow_zone_drifting = True
bb602c
+                    log.warning("AllowZoneDrifting is enabled. This is considered "
bb602c
+                                "an insecure configuration option. It will be "
bb602c
+                                "removed in a future release. Please consider "
bb602c
+                                "disabling it now.")
bb602c
+                log.debug1("AllowZoneDrifting is set to '%s'",
bb602c
+                           self._allow_zone_drifting)
bb602c
+
bb602c
         self.config.set_firewalld_conf(copy.deepcopy(self._firewalld_conf))
bb602c
 
bb602c
         self._select_firewall_backend(self._firewall_backend)
bb602c
diff --git a/src/firewall/core/io/firewalld_conf.py b/src/firewall/core/io/firewalld_conf.py
bb602c
index 9aee2dc6f9b7..a640d8e2f201 100644
bb602c
--- a/src/firewall/core/io/firewalld_conf.py
bb602c
+++ b/src/firewall/core/io/firewalld_conf.py
bb602c
@@ -28,9 +28,9 @@ from firewall import config
bb602c
 from firewall.core.logger import log
bb602c
 from firewall.functions import b2u, u2b, PY2
bb602c
 
bb602c
-valid_keys = [ "DefaultZone", "MinimalMark", "CleanupOnExit", "Lockdown", 
bb602c
+valid_keys = [ "DefaultZone", "MinimalMark", "CleanupOnExit", "Lockdown",
bb602c
                "IPv6_rpfilter", "IndividualCalls", "LogDenied",
bb602c
-               "AutomaticHelpers" ]
bb602c
+               "AutomaticHelpers", "AllowZoneDrifting" ]
bb602c
 
bb602c
 class firewalld_conf(object):
bb602c
     def __init__(self, filename):
bb602c
@@ -79,6 +79,7 @@ class firewalld_conf(object):
bb602c
             self.set("IndividualCalls", "yes" if config.FALLBACK_INDIVIDUAL_CALLS else "no")
bb602c
             self.set("LogDenied", config.FALLBACK_LOG_DENIED)
bb602c
             self.set("AutomaticHelpers", config.FALLBACK_AUTOMATIC_HELPERS)
bb602c
+            self.set("AllowZoneDrifting", "yes" if config.FALLBACK_ALLOW_ZONE_DRIFTING else "no")
bb602c
             raise
bb602c
 
bb602c
         for line in f:
bb602c
@@ -174,6 +175,14 @@ class firewalld_conf(object):
bb602c
                             config.FALLBACK_AUTOMATIC_HELPERS)
bb602c
             self.set("AutomaticHelpers", str(config.FALLBACK_AUTOMATIC_HELPERS))
bb602c
 
bb602c
+        value = self.get("AllowZoneDrifting")
bb602c
+        if not value or value.lower() not in [ "yes", "true", "no", "false" ]:
bb602c
+            if value is not None:
bb602c
+                log.warning("AllowZoneDrifting '%s' is not valid, using default "
bb602c
+                            "value %s", value if value else '',
bb602c
+                            config.FALLBACK_ALLOW_ZONE_DRIFTING)
bb602c
+            self.set("AllowZoneDrifting", str(config.FALLBACK_ALLOW_ZONE_DRIFTING))
bb602c
+
bb602c
     # save to self.filename if there are key/value changes
bb602c
     def write(self):
bb602c
         if len(self._config) < 1:
bb602c
diff --git a/src/firewall/server/config.py b/src/firewall/server/config.py
bb602c
index cd640ba881ca..86b4e4428748 100644
bb602c
--- a/src/firewall/server/config.py
bb602c
+++ b/src/firewall/server/config.py
bb602c
@@ -105,6 +105,7 @@ class FirewallDConfig(slip.dbus.service.Object):
bb602c
                                                 "IndividualCalls": "readwrite",
bb602c
                                                 "LogDenied": "readwrite",
bb602c
                                                 "AutomaticHelpers": "readwrite",
bb602c
+                                                "AllowZoneDrifting": "readwrite",
bb602c
                                               })
bb602c
 
bb602c
     @handle_exceptions
bb602c
@@ -484,7 +485,7 @@ class FirewallDConfig(slip.dbus.service.Object):
bb602c
     def _get_property(self, prop):
bb602c
         if prop not in [ "DefaultZone", "MinimalMark", "CleanupOnExit",
bb602c
                          "Lockdown", "IPv6_rpfilter", "IndividualCalls",
bb602c
-                         "LogDenied", "AutomaticHelpers" ]:
bb602c
+                         "LogDenied", "AutomaticHelpers", "AllowZoneDrifting"]:
bb602c
             raise dbus.exceptions.DBusException(
bb602c
                 "org.freedesktop.DBus.Error.InvalidArgs: "
bb602c
                 "Property '%s' does not exist" % prop)
bb602c
@@ -525,6 +526,10 @@ class FirewallDConfig(slip.dbus.service.Object):
bb602c
             if value is None:
bb602c
                 value = config.FALLBACK_AUTOMATIC_HELPERS
bb602c
             return dbus.String(value)
bb602c
+        elif prop == "AllowZoneDrifting":
bb602c
+            if value is None:
bb602c
+                value = "yes" if config.FALLBACK_ALLOW_ZONE_DRIFTING else "no"
bb602c
+            return dbus.String(value)
bb602c
 
bb602c
     @dbus_handle_exceptions
bb602c
     def _get_dbus_property(self, prop):
bb602c
@@ -544,6 +549,8 @@ class FirewallDConfig(slip.dbus.service.Object):
bb602c
             return dbus.String(self._get_property(prop))
bb602c
         elif prop == "AutomaticHelpers":
bb602c
             return dbus.String(self._get_property(prop))
bb602c
+        elif prop == "AllowZoneDrifting":
bb602c
+            return dbus.String(self._get_property(prop))
bb602c
         else:
bb602c
             raise dbus.exceptions.DBusException(
bb602c
                 "org.freedesktop.DBus.Error.InvalidArgs: "
bb602c
@@ -583,7 +590,7 @@ class FirewallDConfig(slip.dbus.service.Object):
bb602c
         if interface_name == config.dbus.DBUS_INTERFACE_CONFIG:
bb602c
             for x in [ "DefaultZone", "MinimalMark", "CleanupOnExit",
bb602c
                        "Lockdown", "IPv6_rpfilter", "IndividualCalls",
bb602c
-                       "LogDenied", "AutomaticHelpers" ]:
bb602c
+                       "LogDenied", "AutomaticHelpers", "AllowZoneDrifting" ]:
bb602c
                 ret[x] = self._get_property(x)
bb602c
         elif interface_name in [ config.dbus.DBUS_INTERFACE_CONFIG_DIRECT,
bb602c
                                  config.dbus.DBUS_INTERFACE_CONFIG_POLICIES ]:
bb602c
@@ -609,7 +616,8 @@ class FirewallDConfig(slip.dbus.service.Object):
bb602c
         if interface_name == config.dbus.DBUS_INTERFACE_CONFIG:
bb602c
             if property_name in [ "MinimalMark", "CleanupOnExit", "Lockdown",
bb602c
                                   "IPv6_rpfilter", "IndividualCalls",
bb602c
-                                  "LogDenied", "AutomaticHelpers" ]:
bb602c
+                                  "LogDenied", "AutomaticHelpers",
bb602c
+                                  "AllowZoneDrifting" ]:
bb602c
                 if property_name == "MinimalMark":
bb602c
                     try:
bb602c
                         int(new_value)
bb602c
@@ -638,6 +646,12 @@ class FirewallDConfig(slip.dbus.service.Object):
bb602c
                         raise FirewallError(errors.INVALID_VALUE,
bb602c
                                             "'%s' for %s" % \
bb602c
                                             (new_value, property_name))
bb602c
+                if property_name == "AllowZoneDrifting":
bb602c
+                    if new_value.lower() not in ["yes", "true", "no", "false"]:
bb602c
+                        raise FirewallError(errors.INVALID_VALUE,
bb602c
+                                            "'%s' for %s" % \
bb602c
+                                            (new_value, property_name))
bb602c
+
bb602c
                 self.config.get_firewalld_conf().set(property_name, new_value)
bb602c
                 self.config.get_firewalld_conf().write()
bb602c
                 self.PropertiesChanged(interface_name,
bb602c
diff --git a/src/tests/dbus/firewalld.conf.at b/src/tests/dbus/firewalld.conf.at
bb602c
index 05eb3dd5f650..0884e21b6368 100644
bb602c
--- a/src/tests/dbus/firewalld.conf.at
bb602c
+++ b/src/tests/dbus/firewalld.conf.at
bb602c
@@ -3,6 +3,7 @@ FWD_START_TEST([firewalld.conf])
bb602c
 dnl Verify defaults over dbus. Should be inline with default firewalld.conf.
bb602c
 IF_HOST_SUPPORTS_NFT_FIB([
bb602c
 DBUS_GETALL([config], [config], 0, [dnl
bb602c
+string "AllowZoneDrifting" : variant string "no"
bb602c
 string "AutomaticHelpers" : variant string "system"
bb602c
 string "CleanupOnExit" : variant string "no"
bb602c
 string "DefaultZone" : variant string "public"
bb602c
@@ -13,6 +14,7 @@ string "LogDenied" : variant string "off"
bb602c
 string "MinimalMark" : variant int32 100
bb602c
 ])], [
bb602c
 DBUS_GETALL([config], [config], 0, [dnl
bb602c
+string "AllowZoneDrifting" : variant string "no"
bb602c
 string "AutomaticHelpers" : variant string "system"
bb602c
 string "CleanupOnExit" : variant string "no"
bb602c
 string "DefaultZone" : variant string "public"
bb602c
@@ -39,6 +41,7 @@ _helper([LogDenied], [string:"all"], [variant string "all"])
bb602c
 _helper([IPv6_rpfilter], [string:"yes"], [variant string "yes"])
bb602c
 _helper([IndividualCalls], [string:"yes"], [variant string "yes"])
bb602c
 _helper([CleanupOnExit], [string:"yes"], [variant string "yes"])
bb602c
+_helper([AllowZoneDrifting], [string:"yes"], [variant string "yes"])
bb602c
 dnl Note: DefaultZone is RO
bb602c
 m4_undefine([_helper])
bb602c
 
bb602c
-- 
bb602c
2.23.0
bb602c