diff --git a/SOURCES/0030-feat-AllowZoneDrifting-config-option.patch b/SOURCES/0030-feat-AllowZoneDrifting-config-option.patch new file mode 100644 index 0000000..ce1f3a7 --- /dev/null +++ b/SOURCES/0030-feat-AllowZoneDrifting-config-option.patch @@ -0,0 +1,284 @@ +From 3fbf366505d866c042e9dbc29a3fb6f30aff5459 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Sun, 19 Jan 2020 14:13:36 -0500 +Subject: [PATCH 30/35] feat: AllowZoneDrifting config option + +Older versions of firewalld had undocumented behavior known as "zone +drifting". This allowed packets to ingress multiple zones - this is a +violation of zone based firewalls. However, some users rely on this +behavior to have a "catch-all" zone, e.g. the default zone. You can +enable this if you desire such behavior. It's disabled by default for +security reasons. + +Note: If "yes" packets will only drift from source based zones to +interface based zones (including the default zone). Packets never drift +from interface based zones to other interfaces based zones (including +the default zone). + +(cherry picked from commit afadd377b09dc62b340d24bcf891d31f040d1a18) +(cherry picked from commit cb71601436854404b59e53fbdf3eaea1dec9bd80) +--- + config/firewalld.conf | 12 ++++++++++++ + doc/xml/firewalld.conf.xml | 19 +++++++++++++++++++ + doc/xml/firewalld.dbus.xml | 16 ++++++++++++++++ + src/firewall/config/__init__.py.in | 1 + + src/firewall/core/fw.py | 14 ++++++++++++++ + src/firewall/core/io/firewalld_conf.py | 13 +++++++++++-- + src/firewall/server/config.py | 20 +++++++++++++++++--- + src/tests/dbus/firewalld.conf.at | 2 ++ + 8 files changed, 92 insertions(+), 5 deletions(-) + +diff --git a/config/firewalld.conf b/config/firewalld.conf +index 423b7ea0733a..ebf8021226b7 100644 +--- a/config/firewalld.conf ++++ b/config/firewalld.conf +@@ -71,3 +71,15 @@ FlushAllOnReload=yes + # internet. + # Defaults to "yes". + RFC3964_IPv4=yes ++ ++# AllowZoneDrifting ++# Older versions of firewalld had undocumented behavior known as "zone ++# drifting". This allowed packets to ingress multiple zones - this is a ++# violation of zone based firewalls. However, some users rely on this behavior ++# to have a "catch-all" zone, e.g. the default zone. You can enable this if you ++# desire such behavior. It's disabled by default for security reasons. ++# Note: If "yes" packets will only drift from source based zones to interface ++# based zones (including the default zone). Packets never drift from interface ++# based zones to other interfaces based zones (including the default zone). ++# Possible values; "yes", "no". Defaults to "no". ++AllowZoneDrifting=no +diff --git a/doc/xml/firewalld.conf.xml b/doc/xml/firewalld.conf.xml +index 1e229ed1d8b6..8108066e88bf 100644 +--- a/doc/xml/firewalld.conf.xml ++++ b/doc/xml/firewalld.conf.xml +@@ -183,6 +183,25 @@ + + + ++ ++ ++ ++ ++ Older versions of firewalld had undocumented behavior known ++ as "zone drifting". This allowed packets to ingress multiple ++ zones - this is a violation of zone based firewalls. However, ++ some users rely on this behavior to have a "catch-all" zone, ++ e.g. the default zone. You can enable this if you desire such ++ behavior. It's disabled by default for security reasons. ++ Note: If "yes" packets will only drift from source based zones ++ to interface based zones (including the default zone). Packets ++ never drift from interface based zones to other interfaces ++ based zones (including the default zone). ++ Valid values; "yes", "no". Defaults to "no". ++ ++ ++ ++ + + + +diff --git a/doc/xml/firewalld.dbus.xml b/doc/xml/firewalld.dbus.xml +index 4a81e8e61858..f72bad526d65 100644 +--- a/doc/xml/firewalld.dbus.xml ++++ b/doc/xml/firewalld.dbus.xml +@@ -2577,6 +2577,22 @@ + + Properties + ++ ++ AllowZoneDrifting - s - (rw) ++ ++ Older versions of firewalld had undocumented behavior known ++ as "zone drifting". This allowed packets to ingress multiple ++ zones - this is a violation of zone based firewalls. However, ++ some users rely on this behavior to have a "catch-all" zone, ++ e.g. the default zone. You can enable this if you desire such ++ behavior. It's disabled by default for security reasons. ++ Note: If "yes" packets will only drift from source based zones ++ to interface based zones (including the default zone). Packets ++ never drift from interface based zones to other interfaces ++ based zones (including the default zone). ++ Valid values; "yes", "no". Defaults to "no". ++ ++ + + AutomaticHelpers - s - (rw) + +diff --git a/src/firewall/config/__init__.py.in b/src/firewall/config/__init__.py.in +index 5bb318c5b269..c009d93e4164 100644 +--- a/src/firewall/config/__init__.py.in ++++ b/src/firewall/config/__init__.py.in +@@ -132,3 +132,4 @@ FALLBACK_AUTOMATIC_HELPERS = "system" + FALLBACK_FIREWALL_BACKEND = "nftables" + FALLBACK_FLUSH_ALL_ON_RELOAD = True + FALLBACK_RFC3964_IPV4 = True ++FALLBACK_ALLOW_ZONE_DRIFTING = False +diff --git a/src/firewall/core/fw.py b/src/firewall/core/fw.py +index a09c022a2baf..07bc9f375771 100644 +--- a/src/firewall/core/fw.py ++++ b/src/firewall/core/fw.py +@@ -127,6 +127,7 @@ class Firewall(object): + self.nf_conntrack_helper_setting = 0 + self.nf_conntrack_helpers = { } + self.nf_nat_helpers = { } ++ self._allow_zone_drifting = config.FALLBACK_ALLOW_ZONE_DRIFTING + + def individual_calls(self): + return self._individual_calls +@@ -324,6 +325,19 @@ class Firewall(object): + log.debug1("RFC3964_IPv4 is set to '%s'", + self._rfc3964_ipv4) + ++ if self._firewalld_conf.get("AllowZoneDrifting"): ++ value = self._firewalld_conf.get("AllowZoneDrifting") ++ if value.lower() in [ "no", "false" ]: ++ self._allow_zone_drifting = False ++ else: ++ self._allow_zone_drifting = True ++ log.warning("AllowZoneDrifting is enabled. This is considered " ++ "an insecure configuration option. It will be " ++ "removed in a future release. Please consider " ++ "disabling it now.") ++ log.debug1("AllowZoneDrifting is set to '%s'", ++ self._allow_zone_drifting) ++ + self.config.set_firewalld_conf(copy.deepcopy(self._firewalld_conf)) + + self._select_firewall_backend(self._firewall_backend) +diff --git a/src/firewall/core/io/firewalld_conf.py b/src/firewall/core/io/firewalld_conf.py +index c7a7ba283e0e..aec62e3a753c 100644 +--- a/src/firewall/core/io/firewalld_conf.py ++++ b/src/firewall/core/io/firewalld_conf.py +@@ -28,10 +28,10 @@ from firewall import config + from firewall.core.logger import log + from firewall.functions import b2u, u2b, PY2 + +-valid_keys = [ "DefaultZone", "MinimalMark", "CleanupOnExit", "Lockdown", ++valid_keys = [ "DefaultZone", "MinimalMark", "CleanupOnExit", "Lockdown", + "IPv6_rpfilter", "IndividualCalls", "LogDenied", + "AutomaticHelpers", "FirewallBackend", "FlushAllOnReload", +- "RFC3964_IPv4" ] ++ "RFC3964_IPv4", "AllowZoneDrifting" ] + + class firewalld_conf(object): + def __init__(self, filename): +@@ -83,6 +83,7 @@ class firewalld_conf(object): + self.set("FirewallBackend", config.FALLBACK_FIREWALL_BACKEND) + self.set("FlushAllOnReload", "yes" if config.FALLBACK_FLUSH_ALL_ON_RELOAD else "no") + self.set("RFC3964_IPv4", "yes" if config.FALLBACK_RFC3964_IPV4 else "no") ++ self.set("AllowZoneDrifting", "yes" if config.FALLBACK_ALLOW_ZONE_DRIFTING else "no") + raise + + for line in f: +@@ -202,6 +203,14 @@ class firewalld_conf(object): + config.FALLBACK_RFC3964_IPV4) + self.set("RFC3964_IPv4", str(config.FALLBACK_RFC3964_IPV4)) + ++ value = self.get("AllowZoneDrifting") ++ if not value or value.lower() not in [ "yes", "true", "no", "false" ]: ++ if value is not None: ++ log.warning("AllowZoneDrifting '%s' is not valid, using default " ++ "value %s", value if value else '', ++ config.FALLBACK_ALLOW_ZONE_DRIFTING) ++ self.set("AllowZoneDrifting", str(config.FALLBACK_ALLOW_ZONE_DRIFTING)) ++ + # save to self.filename if there are key/value changes + def write(self): + if len(self._config) < 1: +diff --git a/src/firewall/server/config.py b/src/firewall/server/config.py +index b1b839da82ea..4315c6ac1589 100644 +--- a/src/firewall/server/config.py ++++ b/src/firewall/server/config.py +@@ -107,6 +107,7 @@ class FirewallDConfig(slip.dbus.service.Object): + "FirewallBackend": "readwrite", + "FlushAllOnReload": "readwrite", + "RFC3964_IPv4": "readwrite", ++ "AllowZoneDrifting": "readwrite", + }) + + @handle_exceptions +@@ -487,7 +488,8 @@ class FirewallDConfig(slip.dbus.service.Object): + if prop not in [ "DefaultZone", "MinimalMark", "CleanupOnExit", + "Lockdown", "IPv6_rpfilter", "IndividualCalls", + "LogDenied", "AutomaticHelpers", "FirewallBackend", +- "FlushAllOnReload", "RFC3964_IPv4" ]: ++ "FlushAllOnReload", "RFC3964_IPv4", ++ "AllowZoneDrifting" ]: + raise dbus.exceptions.DBusException( + "org.freedesktop.DBus.Error.InvalidArgs: " + "Property '%s' does not exist" % prop) +@@ -540,6 +542,10 @@ class FirewallDConfig(slip.dbus.service.Object): + if value is None: + value = "yes" if config.FALLBACK_RFC3964_IPV4 else "no" + return dbus.String(value) ++ elif prop == "AllowZoneDrifting": ++ if value is None: ++ value = "yes" if config.FALLBACK_ALLOW_ZONE_DRIFTING else "no" ++ return dbus.String(value) + + @dbus_handle_exceptions + def _get_dbus_property(self, prop): +@@ -565,6 +571,8 @@ class FirewallDConfig(slip.dbus.service.Object): + return dbus.String(self._get_property(prop)) + elif prop == "RFC3964_IPv4": + return dbus.String(self._get_property(prop)) ++ elif prop == "AllowZoneDrifting": ++ return dbus.String(self._get_property(prop)) + else: + raise dbus.exceptions.DBusException( + "org.freedesktop.DBus.Error.InvalidArgs: " +@@ -605,7 +613,8 @@ class FirewallDConfig(slip.dbus.service.Object): + for x in [ "DefaultZone", "MinimalMark", "CleanupOnExit", + "Lockdown", "IPv6_rpfilter", "IndividualCalls", + "LogDenied", "AutomaticHelpers", "FirewallBackend", +- "FlushAllOnReload", "RFC3964_IPv4" ]: ++ "FlushAllOnReload", "RFC3964_IPv4", ++ "AllowZoneDrifting" ]: + ret[x] = self._get_property(x) + elif interface_name in [ config.dbus.DBUS_INTERFACE_CONFIG_DIRECT, + config.dbus.DBUS_INTERFACE_CONFIG_POLICIES ]: +@@ -633,7 +642,7 @@ class FirewallDConfig(slip.dbus.service.Object): + "IPv6_rpfilter", "IndividualCalls", + "LogDenied", "AutomaticHelpers", + "FirewallBackend", "FlushAllOnReload", +- "RFC3964_IPv4" ]: ++ "RFC3964_IPv4", "AllowZoneDrifting" ]: + if property_name == "MinimalMark": + try: + int(new_value) +@@ -677,6 +686,11 @@ class FirewallDConfig(slip.dbus.service.Object): + raise FirewallError(errors.INVALID_VALUE, + "'%s' for %s" % \ + (new_value, property_name)) ++ if property_name == "AllowZoneDrifting": ++ if new_value.lower() not in ["yes", "true", "no", "false"]: ++ raise FirewallError(errors.INVALID_VALUE, ++ "'%s' for %s" % \ ++ (new_value, property_name)) + + self.config.get_firewalld_conf().set(property_name, new_value) + self.config.get_firewalld_conf().write() +diff --git a/src/tests/dbus/firewalld.conf.at b/src/tests/dbus/firewalld.conf.at +index 45559311eabb..65ac702f4713 100644 +--- a/src/tests/dbus/firewalld.conf.at ++++ b/src/tests/dbus/firewalld.conf.at +@@ -3,6 +3,7 @@ AT_KEYWORDS(dbus) + + dnl Verify defaults over dbus. Should be inline with default firewalld.conf. + DBUS_GETALL([config], [config], 0, [dnl ++string "AllowZoneDrifting" : variant string "no" + string "AutomaticHelpers" : variant string "system" + string "CleanupOnExit" : variant string "no" + string "DefaultZone" : variant string "public" +@@ -36,6 +37,7 @@ _helper([FirewallBackend], [string:"iptables"], [variant string "iptables"]) + _helper([FlushAllOnReload], [string:"no"], [variant string "no"]) + _helper([CleanupOnExit], [string:"yes"], [variant string "yes"]) + _helper([RFC3964_IPv4], [string:"no"], [variant string "no"]) ++_helper([AllowZoneDrifting], [string:"yes"], [variant string "yes"]) + dnl Note: DefaultZone is RO + m4_undefine([_helper]) + +-- +2.23.0 + diff --git a/SOURCES/0031-feat-nftables-support-AllowZoneDrifting-yes.patch b/SOURCES/0031-feat-nftables-support-AllowZoneDrifting-yes.patch new file mode 100644 index 0000000..84a953b --- /dev/null +++ b/SOURCES/0031-feat-nftables-support-AllowZoneDrifting-yes.patch @@ -0,0 +1,124 @@ +From 3c2ca67f86de7cd490ae25333e330b4aea0447f1 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Sun, 19 Jan 2020 14:37:31 -0500 +Subject: [PATCH 31/35] feat: nftables: support AllowZoneDrifting=yes + +(cherry picked from commit 517a061c5886f2ebfb4aa7d73804aa7f3c5a3004) +(cherry picked from commit d15fb2911a89477f26a800d498fa47d7c2e5ec5f) +--- + src/firewall/core/nftables.py | 44 +++++++++++++++++++++++------------ + 1 file changed, 29 insertions(+), 15 deletions(-) + +diff --git a/src/firewall/core/nftables.py b/src/firewall/core/nftables.py +index 33a170a76a98..79799388a923 100644 +--- a/src/firewall/core/nftables.py ++++ b/src/firewall/core/nftables.py +@@ -204,8 +204,11 @@ class nftables(object): + + index = zone_source_index_cache[family].index(zone_source) + else: +- index = len(zone_source_index_cache[family]) +- ++ if self._fw._allow_zone_drifting: ++ index = 0 ++ else: ++ index = len(zone_source_index_cache[family]) ++ + if index == 0: + rule[0] = "insert" + else: +@@ -488,8 +491,9 @@ class nftables(object): + IPTABLES_TO_NFT_HOOK["raw"][chain][1])) + + for chain in ["PREROUTING"]: +- default_rules.append("add chain inet %s raw_%s_ZONES" % (TABLE_NAME, chain)) +- default_rules.append("add rule inet %s raw_%s jump raw_%s_ZONES" % (TABLE_NAME, chain, chain)) ++ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]: ++ default_rules.append("add chain inet %s raw_%s_%s" % (TABLE_NAME, chain, dispatch_suffix)) ++ default_rules.append("add rule inet %s raw_%s jump raw_%s_%s" % (TABLE_NAME, chain, chain, dispatch_suffix)) + + for chain in IPTABLES_TO_NFT_HOOK["mangle"].keys(): + default_rules.append("add chain inet %s mangle_%s '{ type filter hook %s priority %d ; }'" % +@@ -497,8 +501,9 @@ class nftables(object): + IPTABLES_TO_NFT_HOOK["mangle"][chain][0], + IPTABLES_TO_NFT_HOOK["mangle"][chain][1])) + +- default_rules.append("add chain inet %s mangle_%s_ZONES" % (TABLE_NAME, chain)) +- default_rules.append("add rule inet %s mangle_%s jump mangle_%s_ZONES" % (TABLE_NAME, chain, chain)) ++ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]: ++ default_rules.append("add chain inet %s mangle_%s_%s" % (TABLE_NAME, chain, dispatch_suffix)) ++ default_rules.append("add rule inet %s mangle_%s jump mangle_%s_%s" % (TABLE_NAME, chain, chain, dispatch_suffix)) + + for family in ["ip", "ip6"]: + for chain in IPTABLES_TO_NFT_HOOK["nat"].keys(): +@@ -507,8 +512,9 @@ class nftables(object): + IPTABLES_TO_NFT_HOOK["nat"][chain][0], + IPTABLES_TO_NFT_HOOK["nat"][chain][1])) + +- default_rules.append("add chain %s %s nat_%s_ZONES" % (family, TABLE_NAME, chain)) +- default_rules.append("add rule %s %s nat_%s jump nat_%s_ZONES" % (family, TABLE_NAME, chain, chain)) ++ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]: ++ default_rules.append("add chain %s %s nat_%s_%s" % (family, TABLE_NAME, chain, dispatch_suffix)) ++ default_rules.append("add rule %s %s nat_%s jump nat_%s_%s" % (family, TABLE_NAME, chain, chain, dispatch_suffix)) + + for chain in IPTABLES_TO_NFT_HOOK["filter"].keys(): + default_rules.append("add chain inet %s filter_%s '{ type filter hook %s priority %d ; }'" % +@@ -517,11 +523,12 @@ class nftables(object): + IPTABLES_TO_NFT_HOOK["filter"][chain][1])) + + # filter, INPUT +- default_rules.append("add chain inet %s filter_%s_ZONES" % (TABLE_NAME, "INPUT")) + default_rules.append("add rule inet %s filter_%s ct state established,related accept" % (TABLE_NAME, "INPUT")) + default_rules.append("add rule inet %s filter_%s ct status dnat accept" % (TABLE_NAME, "INPUT")) + default_rules.append("add rule inet %s filter_%s iifname lo accept" % (TABLE_NAME, "INPUT")) +- default_rules.append("add rule inet %s filter_%s jump filter_%s_ZONES" % (TABLE_NAME, "INPUT", "INPUT")) ++ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]: ++ default_rules.append("add chain inet %s filter_%s_%s" % (TABLE_NAME, "INPUT", dispatch_suffix)) ++ default_rules.append("add rule inet %s filter_%s jump filter_%s_%s" % (TABLE_NAME, "INPUT", "INPUT", dispatch_suffix)) + if log_denied != "off": + default_rules.append("add rule inet %s filter_%s ct state invalid %%%%LOGTYPE%%%% log prefix '\"STATE_INVALID_DROP: \"'" % (TABLE_NAME, "INPUT")) + default_rules.append("add rule inet %s filter_%s ct state invalid drop" % (TABLE_NAME, "INPUT")) +@@ -530,13 +537,15 @@ class nftables(object): + default_rules.append("add rule inet %s filter_%s reject with icmpx type admin-prohibited" % (TABLE_NAME, "INPUT")) + + # filter, FORWARD +- default_rules.append("add chain inet %s filter_%s_IN_ZONES" % (TABLE_NAME, "FORWARD")) +- default_rules.append("add chain inet %s filter_%s_OUT_ZONES" % (TABLE_NAME, "FORWARD")) + default_rules.append("add rule inet %s filter_%s ct state established,related accept" % (TABLE_NAME, "FORWARD")) + default_rules.append("add rule inet %s filter_%s ct status dnat accept" % (TABLE_NAME, "FORWARD")) + default_rules.append("add rule inet %s filter_%s iifname lo accept" % (TABLE_NAME, "FORWARD")) +- default_rules.append("add rule inet %s filter_%s jump filter_%s_IN_ZONES" % (TABLE_NAME, "FORWARD", "FORWARD")) +- default_rules.append("add rule inet %s filter_%s jump filter_%s_OUT_ZONES" % (TABLE_NAME, "FORWARD", "FORWARD")) ++ for direction in ["IN", "OUT"]: ++ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]: ++ default_rules.append("add chain inet %s filter_%s_%s_%s" % (TABLE_NAME, "FORWARD", direction, dispatch_suffix)) ++ default_rules.append("add chain inet %s filter_%s_%s_%s" % (TABLE_NAME, "FORWARD", direction, dispatch_suffix)) ++ default_rules.append("add rule inet %s filter_%s jump filter_%s_%s_%s" % (TABLE_NAME, "FORWARD", "FORWARD", direction, dispatch_suffix)) ++ default_rules.append("add rule inet %s filter_%s jump filter_%s_%s_%s" % (TABLE_NAME, "FORWARD", "FORWARD", direction, dispatch_suffix)) + if log_denied != "off": + default_rules.append("add rule inet %s filter_%s ct state invalid %%%%LOGTYPE%%%% log prefix '\"STATE_INVALID_DROP: \"'" % (TABLE_NAME, "FORWARD")) + default_rules.append("add rule inet %s filter_%s ct state invalid drop" % (TABLE_NAME, "FORWARD")) +@@ -634,6 +643,11 @@ class nftables(object): + "OUTPUT": "daddr", + }[chain] + ++ if self._fw._allow_zone_drifting: ++ zone_dispatch_chain = "%s_%s_ZONES_SOURCE" % (table, chain) ++ else: ++ zone_dispatch_chain = "%s_%s_ZONES" % (table, chain) ++ + target = DEFAULT_ZONE_TARGET.format(chain=SHORTCUTS[chain], zone=zone) + action = "goto" + +@@ -653,7 +667,7 @@ class nftables(object): + rule_family = "ip6" + + rule = [add_del, "rule", family, "%s" % TABLE_NAME, +- "%s_%s_ZONES" % (table, chain), ++ zone_dispatch_chain, + "%%ZONE_SOURCE%%", zone, + rule_family, opt, address, action, "%s_%s" % (table, target)] + return [rule] +-- +2.23.0 + diff --git a/SOURCES/0032-feat-ipXtables-support-AllowZoneDrifting-yes.patch b/SOURCES/0032-feat-ipXtables-support-AllowZoneDrifting-yes.patch new file mode 100644 index 0000000..083ef4e --- /dev/null +++ b/SOURCES/0032-feat-ipXtables-support-AllowZoneDrifting-yes.patch @@ -0,0 +1,178 @@ +From 8342a2b3fdea4f78e5c8f842550e87857ccaa277 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Sun, 19 Jan 2020 16:16:59 -0500 +Subject: [PATCH 32/35] feat: ipXtables: support AllowZoneDrifting=yes + +(cherry picked from commit 1f7b5ffcd40daf2a7f2ef1ec0cccb95080e74fb6) +(cherry picked from commit 0435bc024cf9ecf5aad7d3c37f7ef55396de73a4) +--- + src/firewall/core/ipXtables.py | 93 +++++++++++++++++++--------------- + 1 file changed, 51 insertions(+), 42 deletions(-) + +diff --git a/src/firewall/core/ipXtables.py b/src/firewall/core/ipXtables.py +index 2f4ec46d8339..c9c1acc44a4c 100644 +--- a/src/firewall/core/ipXtables.py ++++ b/src/firewall/core/ipXtables.py +@@ -323,8 +323,11 @@ class ip4tables(object): + + index = zone_source_index_cache.index(zone_source) + else: +- index = len(zone_source_index_cache) +- ++ if self._fw._allow_zone_drifting: ++ index = 0 ++ else: ++ index = len(zone_source_index_cache) ++ + rule[0] = "-I" + rule.insert(2, "%d" % (index + 1)) + +@@ -667,9 +670,10 @@ class ip4tables(object): + self.our_chains["raw"].add("%s_direct" % chain) + + if chain == "PREROUTING": +- default_rules["raw"].append("-N %s_ZONES" % chain) +- default_rules["raw"].append("-A %s -j %s_ZONES" % (chain, chain)) +- self.our_chains["raw"].update(set(["%s_ZONES" % chain])) ++ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]: ++ default_rules["raw"].append("-N %s_%s" % (chain, dispatch_suffix)) ++ default_rules["raw"].append("-A %s -j %s_%s" % (chain, chain, dispatch_suffix)) ++ self.our_chains["raw"].update(set(["%s_%s" % (chain, dispatch_suffix)])) + + if self.get_available_tables("mangle"): + default_rules["mangle"] = [ ] +@@ -680,9 +684,10 @@ class ip4tables(object): + self.our_chains["mangle"].add("%s_direct" % chain) + + if chain == "PREROUTING": +- default_rules["mangle"].append("-N %s_ZONES" % chain) +- default_rules["mangle"].append("-A %s -j %s_ZONES" % (chain, chain)) +- self.our_chains["mangle"].update(set(["%s_ZONES" % chain])) ++ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]: ++ default_rules["mangle"].append("-N %s_%s" % (chain, dispatch_suffix)) ++ default_rules["mangle"].append("-A %s -j %s_%s" % (chain, chain, dispatch_suffix)) ++ self.our_chains["mangle"].update(set(["%s_%s" % (chain, dispatch_suffix)])) + + if self.get_available_tables("nat"): + default_rules["nat"] = [ ] +@@ -693,19 +698,22 @@ class ip4tables(object): + self.our_chains["nat"].add("%s_direct" % chain) + + if chain in [ "PREROUTING", "POSTROUTING" ]: +- default_rules["nat"].append("-N %s_ZONES" % chain) +- default_rules["nat"].append("-A %s -j %s_ZONES" % (chain, chain)) +- self.our_chains["nat"].update(set(["%s_ZONES" % chain])) +- +- default_rules["filter"] = [ +- "-N INPUT_direct", +- "-N INPUT_ZONES", +- +- "-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED,DNAT -j ACCEPT", +- "-A INPUT -i lo -j ACCEPT", +- "-A INPUT -j INPUT_direct", +- "-A INPUT -j INPUT_ZONES", +- ] ++ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]: ++ default_rules["nat"].append("-N %s_%s" % (chain, dispatch_suffix)) ++ default_rules["nat"].append("-A %s -j %s_%s" % (chain, chain, dispatch_suffix)) ++ self.our_chains["nat"].update(set(["%s_%s" % (chain, dispatch_suffix)])) ++ ++ default_rules["filter"] = [] ++ self.our_chains["filter"] = set() ++ default_rules["filter"].append("-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED,DNAT -j ACCEPT") ++ default_rules["filter"].append("-A INPUT -i lo -j ACCEPT") ++ default_rules["filter"].append("-N INPUT_direct") ++ default_rules["filter"].append("-A INPUT -j INPUT_direct") ++ self.our_chains["filter"].update(set("INPUT_direct")) ++ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]: ++ default_rules["filter"].append("-N INPUT_%s" % (dispatch_suffix)) ++ default_rules["filter"].append("-A INPUT -j INPUT_%s" % (dispatch_suffix)) ++ self.our_chains["filter"].update(set("INPUT_%s" % (dispatch_suffix))) + if log_denied != "off": + default_rules["filter"].append("-A INPUT -m conntrack --ctstate INVALID %%LOGTYPE%% -j LOG --log-prefix 'STATE_INVALID_DROP: '") + default_rules["filter"].append("-A INPUT -m conntrack --ctstate INVALID -j DROP") +@@ -713,17 +721,16 @@ class ip4tables(object): + default_rules["filter"].append("-A INPUT %%LOGTYPE%% -j LOG --log-prefix 'FINAL_REJECT: '") + default_rules["filter"].append("-A INPUT -j %%REJECT%%") + +- default_rules["filter"] += [ +- "-N FORWARD_direct", +- "-N FORWARD_IN_ZONES", +- "-N FORWARD_OUT_ZONES", +- +- "-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED,DNAT -j ACCEPT", +- "-A FORWARD -i lo -j ACCEPT", +- "-A FORWARD -j FORWARD_direct", +- "-A FORWARD -j FORWARD_IN_ZONES", +- "-A FORWARD -j FORWARD_OUT_ZONES", +- ] ++ default_rules["filter"].append("-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED,DNAT -j ACCEPT") ++ default_rules["filter"].append("-A FORWARD -i lo -j ACCEPT") ++ default_rules["filter"].append("-N FORWARD_direct") ++ default_rules["filter"].append("-A FORWARD -j FORWARD_direct") ++ self.our_chains["filter"].update(set("FORWARD_direct")) ++ for direction in ["IN", "OUT"]: ++ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]: ++ default_rules["filter"].append("-N FORWARD_%s_%s" % (direction, dispatch_suffix)) ++ default_rules["filter"].append("-A FORWARD -j FORWARD_%s_%s" % (direction, dispatch_suffix)) ++ self.our_chains["filter"].update(set("FORWARD_%s_%s" % (direction, dispatch_suffix))) + if log_denied != "off": + default_rules["filter"].append("-A FORWARD -m conntrack --ctstate INVALID %%LOGTYPE%% -j LOG --log-prefix 'STATE_INVALID_DROP: '") + default_rules["filter"].append("-A FORWARD -m conntrack --ctstate INVALID -j DROP") +@@ -737,10 +744,7 @@ class ip4tables(object): + "-A OUTPUT -o lo -j ACCEPT", + "-A OUTPUT -j OUTPUT_direct", + ] +- +- self.our_chains["filter"] = set(["INPUT_direct", "INPUT_ZONES", +- "FORWARD_direct", "FORWARD_IN_ZONES", +- "FORWARD_OUT_ZONES", "OUTPUT_direct"]) ++ self.our_chains["filter"].update(set("OUTPUT_direct")) + + final_default_rules = [] + for table in default_rules: +@@ -806,6 +810,11 @@ class ip4tables(object): + "OUTPUT": "-d", + }[chain] + ++ if self._fw._allow_zone_drifting: ++ zone_dispatch_chain = "%s_ZONES_SOURCE" % (chain) ++ else: ++ zone_dispatch_chain = "%s_ZONES" % (chain) ++ + target = DEFAULT_ZONE_TARGET.format(chain=SHORTCUTS[chain], zone=zone) + action = "-g" + +@@ -816,8 +825,8 @@ class ip4tables(object): + else: + opt = "src" + flags = ",".join([opt] * self._fw.ipset.get_dimension(name)) +- rule = [ add_del, +- "%s_ZONES" % chain, "%%ZONE_SOURCE%%", zone, ++ rule = [ add_del, zone_dispatch_chain, ++ "%%ZONE_SOURCE%%", zone, + "-t", table, + "-m", "set", "--match-set", name, + flags, action, target ] +@@ -826,14 +835,14 @@ class ip4tables(object): + # outgoing can not be set + if opt == "-d": + return "" +- rule = [ add_del, +- "%s_ZONES" % chain, "%%ZONE_SOURCE%%", zone, ++ rule = [ add_del, zone_dispatch_chain, ++ "%%ZONE_SOURCE%%", zone, + "-t", table, + "-m", "mac", "--mac-source", address.upper(), + action, target ] + else: +- rule = [ add_del, +- "%s_ZONES" % chain, "%%ZONE_SOURCE%%", zone, ++ rule = [ add_del, zone_dispatch_chain, ++ "%%ZONE_SOURCE%%", zone, + "-t", table, + opt, address, action, target ] + return [rule] +-- +2.23.0 + diff --git a/SOURCES/0033-test-verify-AllowZoneDrifting-yes.patch b/SOURCES/0033-test-verify-AllowZoneDrifting-yes.patch new file mode 100644 index 0000000..8f860ad --- /dev/null +++ b/SOURCES/0033-test-verify-AllowZoneDrifting-yes.patch @@ -0,0 +1,939 @@ +From d5fb90bf13f46432292eeeb1fe48727f52333348 Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Sun, 19 Jan 2020 16:49:14 -0500 +Subject: [PATCH 33/35] test: verify AllowZoneDrifting=yes + +Verify the zone dispatch layout. + +(cherry picked from commit bca4e6af91fc4c6a55f7c2bce9e4fe7bcee526a1) +(cherry picked from commit f60b13d837d2726175d1dae213777dde8025e7ec) +--- + src/tests/regression/gh258.at | 536 +++++++++++++++++++++++++--- + src/tests/regression/rhbz1734765.at | 180 +++++++++- + 2 files changed, 671 insertions(+), 45 deletions(-) + +diff --git a/src/tests/regression/gh258.at b/src/tests/regression/gh258.at +index 1896a9bfc61c..01b717483d77 100644 +--- a/src/tests/regression/gh258.at ++++ b/src/tests/regression/gh258.at +@@ -1,12 +1,15 @@ + FWD_START_TEST([zone dispatch layout]) +-AT_KEYWORDS(zone gh258 gh441 rhbz1713823) ++AT_KEYWORDS(zone gh258 gh441 rhbz1713823 rhbz1772208 rhbz1796055) + +-FWD_CHECK([--zone=work --add-source="1.2.3.0/24"], 0, ignore) ++FWD_CHECK([--permanent --zone=trusted --add-source="1.2.3.0/24"], 0, ignore) + IF_IPV6_SUPPORTED([ +-FWD_CHECK([--zone=public --add-source="dead:beef::/54"], 0, ignore) ++FWD_CHECK([--permanent --zone=public --add-source="dead:beef::/54"], 0, ignore) + ]) +-FWD_CHECK([--zone=work --add-interface=dummy0], 0, ignore) +-FWD_CHECK([--zone=public --add-interface=dummy1], 0, ignore) ++FWD_CHECK([--permanent --zone=trusted --add-interface=dummy0], 0, ignore) ++FWD_CHECK([--permanent --zone=public --add-interface=dummy1], 0, ignore) ++ ++AT_CHECK([sed -i 's/^AllowZoneDrifting.*/AllowZoneDrifting=no/' ./firewalld.conf]) ++FWD_RELOAD + + dnl verify layout of zone dispatch + NFT_LIST_RULES([inet], [filter_INPUT], 0, [dnl +@@ -25,9 +28,9 @@ NFT_LIST_RULES([inet], [filter_INPUT_ZONES], 0, [dnl + table inet firewalld { + chain filter_INPUT_ZONES { + ip6 saddr dead:beef::/54 goto filter_IN_public +- ip saddr 1.2.3.0/24 goto filter_IN_work ++ ip saddr 1.2.3.0/24 goto filter_IN_trusted ++ iifname "dummy0" goto filter_IN_trusted + iifname "dummy1" goto filter_IN_public +- iifname "dummy0" goto filter_IN_work + goto filter_IN_public + } + } +@@ -50,9 +53,9 @@ NFT_LIST_RULES([inet], [filter_FORWARD_IN_ZONES], 0, [dnl + table inet firewalld { + chain filter_FORWARD_IN_ZONES { + ip6 saddr dead:beef::/54 goto filter_FWDI_public +- ip saddr 1.2.3.0/24 goto filter_FWDI_work ++ ip saddr 1.2.3.0/24 goto filter_FWDI_trusted ++ iifname "dummy0" goto filter_FWDI_trusted + iifname "dummy1" goto filter_FWDI_public +- iifname "dummy0" goto filter_FWDI_work + goto filter_FWDI_public + } + } +@@ -61,9 +64,9 @@ NFT_LIST_RULES([inet], [filter_FORWARD_OUT_ZONES], 0, [dnl + table inet firewalld { + chain filter_FORWARD_OUT_ZONES { + ip6 daddr dead:beef::/54 goto filter_FWDO_public +- ip daddr 1.2.3.0/24 goto filter_FWDO_work ++ ip daddr 1.2.3.0/24 goto filter_FWDO_trusted ++ oifname "dummy0" goto filter_FWDO_trusted + oifname "dummy1" goto filter_FWDO_public +- oifname "dummy0" goto filter_FWDO_work + goto filter_FWDO_public + } + } +@@ -83,9 +86,9 @@ NFT_LIST_RULES([inet], [raw_PREROUTING_ZONES], 0, [dnl + table inet firewalld { + chain raw_PREROUTING_ZONES { + ip6 saddr dead:beef::/54 goto raw_PRE_public +- ip saddr 1.2.3.0/24 goto raw_PRE_work ++ ip saddr 1.2.3.0/24 goto raw_PRE_trusted ++ iifname "dummy0" goto raw_PRE_trusted + iifname "dummy1" goto raw_PRE_public +- iifname "dummy0" goto raw_PRE_work + goto raw_PRE_public + } + } +@@ -101,9 +104,9 @@ NFT_LIST_RULES([inet], [mangle_PREROUTING_ZONES], 0, [dnl + table inet firewalld { + chain mangle_PREROUTING_ZONES { + ip6 saddr dead:beef::/54 goto mangle_PRE_public +- ip saddr 1.2.3.0/24 goto mangle_PRE_work ++ ip saddr 1.2.3.0/24 goto mangle_PRE_trusted ++ iifname "dummy0" goto mangle_PRE_trusted + iifname "dummy1" goto mangle_PRE_public +- iifname "dummy0" goto mangle_PRE_work + goto mangle_PRE_public + } + } +@@ -118,9 +121,9 @@ NFT_LIST_RULES([ip], [nat_PREROUTING], 0, [dnl + NFT_LIST_RULES([ip], [nat_PREROUTING_ZONES], 0, [dnl + table ip firewalld { + chain nat_PREROUTING_ZONES { +- ip saddr 1.2.3.0/24 goto nat_PRE_work ++ ip saddr 1.2.3.0/24 goto nat_PRE_trusted ++ iifname "dummy0" goto nat_PRE_trusted + iifname "dummy1" goto nat_PRE_public +- iifname "dummy0" goto nat_PRE_work + goto nat_PRE_public + } + } +@@ -135,9 +138,9 @@ NFT_LIST_RULES([ip], [nat_POSTROUTING], 0, [dnl + NFT_LIST_RULES([ip], [nat_POSTROUTING_ZONES], 0, [dnl + table ip firewalld { + chain nat_POSTROUTING_ZONES { +- ip daddr 1.2.3.0/24 goto nat_POST_work ++ ip daddr 1.2.3.0/24 goto nat_POST_trusted ++ oifname "dummy0" goto nat_POST_trusted + oifname "dummy1" goto nat_POST_public +- oifname "dummy0" goto nat_POST_work + goto nat_POST_public + } + } +@@ -153,8 +156,8 @@ NFT_LIST_RULES([ip6], [nat_PREROUTING_ZONES], 0, [dnl + table ip6 firewalld { + chain nat_PREROUTING_ZONES { + ip6 saddr dead:beef::/54 goto nat_PRE_public ++ iifname "dummy0" goto nat_PRE_trusted + iifname "dummy1" goto nat_PRE_public +- iifname "dummy0" goto nat_PRE_work + goto nat_PRE_public + } + } +@@ -170,8 +173,8 @@ NFT_LIST_RULES([ip6], [nat_POSTROUTING_ZONES], 0, [dnl + table ip6 firewalld { + chain nat_POSTROUTING_ZONES { + ip6 daddr dead:beef::/54 goto nat_POST_public ++ oifname "dummy0" goto nat_POST_trusted + oifname "dummy1" goto nat_POST_public +- oifname "dummy0" goto nat_POST_work + goto nat_POST_public + } + } +@@ -186,9 +189,9 @@ IPTABLES_LIST_RULES([filter], [INPUT], 0, [dnl + REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited + ]) + IPTABLES_LIST_RULES([filter], [INPUT_ZONES], 0, +- [[IN_work all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ [[IN_trusted all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ IN_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] + IN_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] +- IN_work all -- 0.0.0.0/0 0.0.0.0/0 [goto] + IN_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] + ]]) + IPTABLES_LIST_RULES([filter], [FORWARD], 0, [dnl +@@ -201,15 +204,15 @@ IPTABLES_LIST_RULES([filter], [FORWARD], 0, [dnl + REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited + ]) + IPTABLES_LIST_RULES([filter], [FORWARD_IN_ZONES], 0, +- [[FWDI_work all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ [[FWDI_trusted all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ FWDI_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] + FWDI_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] +- FWDI_work all -- 0.0.0.0/0 0.0.0.0/0 [goto] + FWDI_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] + ]]) + IPTABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES], 0, +- [[FWDO_work all -- 0.0.0.0/0 1.2.3.0/24 [goto] ++ [[FWDO_trusted all -- 0.0.0.0/0 1.2.3.0/24 [goto] ++ FWDO_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] + FWDO_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] +- FWDO_work all -- 0.0.0.0/0 0.0.0.0/0 [goto] + FWDO_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] + ]]) + IPTABLES_LIST_RULES([raw], [PREROUTING], 0, [dnl +@@ -217,9 +220,9 @@ IPTABLES_LIST_RULES([raw], [PREROUTING], 0, [dnl + PREROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0 + ]) + IPTABLES_LIST_RULES([raw], [PREROUTING_ZONES], 0, +- [[PRE_work all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ [[PRE_trusted all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ PRE_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] + PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] +- PRE_work all -- 0.0.0.0/0 0.0.0.0/0 [goto] + PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] + ]]) + IPTABLES_LIST_RULES([mangle], [PREROUTING], 0, [dnl +@@ -227,9 +230,9 @@ IPTABLES_LIST_RULES([mangle], [PREROUTING], 0, [dnl + PREROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0 + ]) + IPTABLES_LIST_RULES([mangle], [PREROUTING_ZONES], 0, +- [[PRE_work all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ [[PRE_trusted all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ PRE_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] + PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] +- PRE_work all -- 0.0.0.0/0 0.0.0.0/0 [goto] + PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] + ]]) + IPTABLES_LIST_RULES([nat], [PREROUTING], 0, [dnl +@@ -237,9 +240,9 @@ IPTABLES_LIST_RULES([nat], [PREROUTING], 0, [dnl + PREROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0 + ]) + IPTABLES_LIST_RULES([nat], [PREROUTING_ZONES], 0, +- [[PRE_work all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ [[PRE_trusted all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++ PRE_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] + PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] +- PRE_work all -- 0.0.0.0/0 0.0.0.0/0 [goto] + PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] + ]]) + IPTABLES_LIST_RULES([nat], [POSTROUTING], 0, [dnl +@@ -247,9 +250,9 @@ IPTABLES_LIST_RULES([nat], [POSTROUTING], 0, [dnl + POSTROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0 + ]) + IPTABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, +- [[POST_work all -- 0.0.0.0/0 1.2.3.0/24 [goto] ++ [[POST_trusted all -- 0.0.0.0/0 1.2.3.0/24 [goto] ++ POST_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] + POST_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] +- POST_work all -- 0.0.0.0/0 0.0.0.0/0 [goto] + POST_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] + ]]) + +@@ -263,8 +266,8 @@ IP6TABLES_LIST_RULES([filter], [INPUT], 0, [dnl + ]) + IP6TABLES_LIST_RULES([filter], [INPUT_ZONES], 0, + [[IN_public all dead:beef::/54 ::/0 [goto] ++ IN_trusted all ::/0 ::/0 [goto] + IN_public all ::/0 ::/0 [goto] +- IN_work all ::/0 ::/0 [goto] + IN_public all ::/0 ::/0 [goto] + ]]) + IP6TABLES_LIST_RULES([filter], [FORWARD], 0, [dnl +@@ -279,14 +282,14 @@ IP6TABLES_LIST_RULES([filter], [FORWARD], 0, [dnl + ]) + IP6TABLES_LIST_RULES([filter], [FORWARD_IN_ZONES], 0, + [[FWDI_public all dead:beef::/54 ::/0 [goto] ++ FWDI_trusted all ::/0 ::/0 [goto] + FWDI_public all ::/0 ::/0 [goto] +- FWDI_work all ::/0 ::/0 [goto] + FWDI_public all ::/0 ::/0 [goto] + ]]) + IP6TABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES], 0, + [[FWDO_public all ::/0 dead:beef::/54 [goto] ++ FWDO_trusted all ::/0 ::/0 [goto] + FWDO_public all ::/0 ::/0 [goto] +- FWDO_work all ::/0 ::/0 [goto] + FWDO_public all ::/0 ::/0 [goto] + ]]) + IP6TABLES_LIST_RULES([raw], [PREROUTING], 0, [dnl +@@ -298,8 +301,8 @@ IP6TABLES_LIST_RULES([raw], [PREROUTING], 0, [dnl + ]) + IP6TABLES_LIST_RULES([raw], [PREROUTING_ZONES], 0, + [[PRE_public all dead:beef::/54 ::/0 [goto] ++ PRE_trusted all ::/0 ::/0 [goto] + PRE_public all ::/0 ::/0 [goto] +- PRE_work all ::/0 ::/0 [goto] + PRE_public all ::/0 ::/0 [goto] + ]]) + IP6TABLES_LIST_RULES([mangle], [PREROUTING], 0, [dnl +@@ -308,8 +311,8 @@ IP6TABLES_LIST_RULES([mangle], [PREROUTING], 0, [dnl + ]) + IP6TABLES_LIST_RULES([mangle], [PREROUTING_ZONES], 0, + [[PRE_public all dead:beef::/54 ::/0 [goto] ++ PRE_trusted all ::/0 ::/0 [goto] + PRE_public all ::/0 ::/0 [goto] +- PRE_work all ::/0 ::/0 [goto] + PRE_public all ::/0 ::/0 [goto] + ]]) + IP6TABLES_LIST_RULES([nat], [PREROUTING], 0, [dnl +@@ -318,8 +321,8 @@ IP6TABLES_LIST_RULES([nat], [PREROUTING], 0, [dnl + ]) + IP6TABLES_LIST_RULES([nat], [PREROUTING_ZONES], 0, + [[PRE_public all dead:beef::/54 ::/0 [goto] ++ PRE_trusted all ::/0 ::/0 [goto] + PRE_public all ::/0 ::/0 [goto] +- PRE_work all ::/0 ::/0 [goto] + PRE_public all ::/0 ::/0 [goto] + ]]) + IP6TABLES_LIST_RULES([nat], [POSTROUTING], 0, [dnl +@@ -328,9 +331,456 @@ IP6TABLES_LIST_RULES([nat], [POSTROUTING], 0, [dnl + ]) + IP6TABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, + [[POST_public all ::/0 dead:beef::/54 [goto] ++ POST_trusted all ::/0 ::/0 [goto] ++ POST_public all ::/0 ::/0 [goto] ++ POST_public all ::/0 ::/0 [goto] ++]]) ++ ++dnl ########################################################################## ++dnl ########################################################################## ++dnl We also support zone drifting in which source based zones fall through to ++dnl interface based zones (including default zone). ++dnl ########################################################################## ++dnl ########################################################################## ++AT_CHECK([sed -i 's/^AllowZoneDrifting.*/AllowZoneDrifting=yes/' ./firewalld.conf]) ++FWD_RELOAD ++ ++NFT_LIST_RULES([inet], [filter_INPUT], 0, [dnl ++ table inet firewalld { ++ chain filter_INPUT { ++ ct state established,related accept ++ ct status dnat accept ++ iifname "lo" accept ++ jump filter_INPUT_ZONES_SOURCE ++ jump filter_INPUT_ZONES ++ ct state invalid drop ++ reject with icmpx type admin-prohibited ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_INPUT_ZONES_SOURCE], 0, [dnl ++ table inet firewalld { ++ chain filter_INPUT_ZONES_SOURCE { ++ ip6 saddr dead:beef::/54 goto filter_IN_public ++ ip saddr 1.2.3.0/24 goto filter_IN_trusted ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_INPUT_ZONES], 0, [dnl ++ table inet firewalld { ++ chain filter_INPUT_ZONES { ++ iifname "dummy0" goto filter_IN_trusted ++ iifname "dummy1" goto filter_IN_public ++ goto filter_IN_public ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_FORWARD], 0, [dnl ++ table inet firewalld { ++ chain filter_FORWARD { ++ ct state established,related accept ++ ct status dnat accept ++ iifname "lo" accept ++ ip6 daddr { ::/96, ::ffff:0.0.0.0/96, 2002::/24, 2002:a00::/24, 2002:7f00::/24, 2002:a9fe::/32, 2002:ac10::/28, 2002:c0a8::/32, 2002:e000::/19 } reject with icmpv6 type addr-unreachable ++ jump filter_FORWARD_IN_ZONES_SOURCE ++ jump filter_FORWARD_IN_ZONES ++ jump filter_FORWARD_OUT_ZONES_SOURCE ++ jump filter_FORWARD_OUT_ZONES ++ ct state invalid drop ++ reject with icmpx type admin-prohibited ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_FORWARD_IN_ZONES_SOURCE], 0, [dnl ++ table inet firewalld { ++ chain filter_FORWARD_IN_ZONES_SOURCE { ++ ip6 saddr dead:beef::/54 goto filter_FWDI_public ++ ip saddr 1.2.3.0/24 goto filter_FWDI_trusted ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_FORWARD_IN_ZONES], 0, [dnl ++ table inet firewalld { ++ chain filter_FORWARD_IN_ZONES { ++ iifname "dummy0" goto filter_FWDI_trusted ++ iifname "dummy1" goto filter_FWDI_public ++ goto filter_FWDI_public ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_FORWARD_OUT_ZONES_SOURCE], 0, [dnl ++ table inet firewalld { ++ chain filter_FORWARD_OUT_ZONES_SOURCE { ++ ip6 daddr dead:beef::/54 goto filter_FWDO_public ++ ip daddr 1.2.3.0/24 goto filter_FWDO_trusted ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_FORWARD_OUT_ZONES], 0, [dnl ++ table inet firewalld { ++ chain filter_FORWARD_OUT_ZONES { ++ oifname "dummy0" goto filter_FWDO_trusted ++ oifname "dummy1" goto filter_FWDO_public ++ goto filter_FWDO_public ++ } ++ } ++]) ++m4_if(yes, HOST_SUPPORTS_NFT_FIB, [dnl ++ NFT_LIST_RULES([inet], [raw_PREROUTING], 0, [dnl ++ table inet firewalld { ++ chain raw_PREROUTING { ++ icmpv6 type { nd-router-advert, nd-neighbor-solicit } accept ++ meta nfproto ipv6 fib saddr . iif oif missing drop ++ jump raw_PREROUTING_ZONES_SOURCE ++ jump raw_PREROUTING_ZONES ++ } ++ } ++ ]) ++], [ ++ NFT_LIST_RULES([inet], [raw_PREROUTING], 0, [dnl ++ table inet firewalld { ++ chain raw_PREROUTING { ++ jump raw_PREROUTING_ZONES_SOURCE ++ jump raw_PREROUTING_ZONES ++ } ++ } ++ ]) ++]) ++NFT_LIST_RULES([inet], [raw_PREROUTING_ZONES_SOURCE], 0, [dnl ++ table inet firewalld { ++ chain raw_PREROUTING_ZONES_SOURCE { ++ ip6 saddr dead:beef::/54 goto raw_PRE_public ++ ip saddr 1.2.3.0/24 goto raw_PRE_trusted ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [raw_PREROUTING_ZONES], 0, [dnl ++ table inet firewalld { ++ chain raw_PREROUTING_ZONES { ++ iifname "dummy0" goto raw_PRE_trusted ++ iifname "dummy1" goto raw_PRE_public ++ goto raw_PRE_public ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [mangle_PREROUTING], 0, [dnl ++ table inet firewalld { ++ chain mangle_PREROUTING { ++ jump mangle_PREROUTING_ZONES_SOURCE ++ jump mangle_PREROUTING_ZONES ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [mangle_PREROUTING_ZONES_SOURCE], 0, [dnl ++ table inet firewalld { ++ chain mangle_PREROUTING_ZONES_SOURCE { ++ ip6 saddr dead:beef::/54 goto mangle_PRE_public ++ ip saddr 1.2.3.0/24 goto mangle_PRE_trusted ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [mangle_PREROUTING_ZONES], 0, [dnl ++ table inet firewalld { ++ chain mangle_PREROUTING_ZONES { ++ iifname "dummy0" goto mangle_PRE_trusted ++ iifname "dummy1" goto mangle_PRE_public ++ goto mangle_PRE_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip], [nat_PREROUTING], 0, [dnl ++ table ip firewalld { ++ chain nat_PREROUTING { ++ jump nat_PREROUTING_ZONES_SOURCE ++ jump nat_PREROUTING_ZONES ++ } ++ } ++]) ++NFT_LIST_RULES([ip], [nat_PREROUTING_ZONES_SOURCE], 0, [dnl ++ table ip firewalld { ++ chain nat_PREROUTING_ZONES_SOURCE { ++ ip saddr 1.2.3.0/24 goto nat_PRE_trusted ++ } ++ } ++]) ++NFT_LIST_RULES([ip], [nat_PREROUTING_ZONES], 0, [dnl ++ table ip firewalld { ++ chain nat_PREROUTING_ZONES { ++ iifname "dummy0" goto nat_PRE_trusted ++ iifname "dummy1" goto nat_PRE_public ++ goto nat_PRE_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip], [nat_POSTROUTING], 0, [dnl ++ table ip firewalld { ++ chain nat_POSTROUTING { ++ jump nat_POSTROUTING_ZONES_SOURCE ++ jump nat_POSTROUTING_ZONES ++ } ++ } ++]) ++NFT_LIST_RULES([ip], [nat_POSTROUTING_ZONES_SOURCE], 0, [dnl ++ table ip firewalld { ++ chain nat_POSTROUTING_ZONES_SOURCE { ++ ip daddr 1.2.3.0/24 goto nat_POST_trusted ++ } ++ } ++]) ++NFT_LIST_RULES([ip], [nat_POSTROUTING_ZONES], 0, [dnl ++ table ip firewalld { ++ chain nat_POSTROUTING_ZONES { ++ oifname "dummy0" goto nat_POST_trusted ++ oifname "dummy1" goto nat_POST_public ++ goto nat_POST_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip6], [nat_PREROUTING], 0, [dnl ++ table ip6 firewalld { ++ chain nat_PREROUTING { ++ jump nat_PREROUTING_ZONES_SOURCE ++ jump nat_PREROUTING_ZONES ++ } ++ } ++]) ++NFT_LIST_RULES([ip6], [nat_PREROUTING_ZONES_SOURCE], 0, [dnl ++ table ip6 firewalld { ++ chain nat_PREROUTING_ZONES_SOURCE { ++ ip6 saddr dead:beef::/54 goto nat_PRE_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip6], [nat_PREROUTING_ZONES], 0, [dnl ++ table ip6 firewalld { ++ chain nat_PREROUTING_ZONES { ++ iifname "dummy0" goto nat_PRE_trusted ++ iifname "dummy1" goto nat_PRE_public ++ goto nat_PRE_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip6], [nat_POSTROUTING], 0, [dnl ++ table ip6 firewalld { ++ chain nat_POSTROUTING { ++ jump nat_POSTROUTING_ZONES_SOURCE ++ jump nat_POSTROUTING_ZONES ++ } ++ } ++]) ++NFT_LIST_RULES([ip6], [nat_POSTROUTING_ZONES_SOURCE], 0, [dnl ++ table ip6 firewalld { ++ chain nat_POSTROUTING_ZONES_SOURCE { ++ ip6 daddr dead:beef::/54 goto nat_POST_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip6], [nat_POSTROUTING_ZONES], 0, [dnl ++ table ip6 firewalld { ++ chain nat_POSTROUTING_ZONES { ++ oifname "dummy0" goto nat_POST_trusted ++ oifname "dummy1" goto nat_POST_public ++ goto nat_POST_public ++ } ++ } ++]) ++ ++IPTABLES_LIST_RULES([filter], [INPUT], 0, [dnl ++ ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED,DNAT ++ ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ++ INPUT_direct all -- 0.0.0.0/0 0.0.0.0/0 ++ INPUT_ZONES_SOURCE all -- 0.0.0.0/0 0.0.0.0/0 ++ INPUT_ZONES all -- 0.0.0.0/0 0.0.0.0/0 ++ DROP all -- 0.0.0.0/0 0.0.0.0/0 ctstate INVALID ++ REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited ++]) ++IPTABLES_LIST_RULES([filter], [INPUT_ZONES_SOURCE], 0, ++ [[IN_trusted all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([filter], [INPUT_ZONES], 0, ++ [[IN_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ IN_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ IN_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([filter], [FORWARD], 0, [dnl ++ ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED,DNAT ++ ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ++ FORWARD_direct all -- 0.0.0.0/0 0.0.0.0/0 ++ FORWARD_IN_ZONES_SOURCE all -- 0.0.0.0/0 0.0.0.0/0 ++ FORWARD_IN_ZONES all -- 0.0.0.0/0 0.0.0.0/0 ++ FORWARD_OUT_ZONES_SOURCE all -- 0.0.0.0/0 0.0.0.0/0 ++ FORWARD_OUT_ZONES all -- 0.0.0.0/0 0.0.0.0/0 ++ DROP all -- 0.0.0.0/0 0.0.0.0/0 ctstate INVALID ++ REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited ++]) ++IPTABLES_LIST_RULES([filter], [FORWARD_IN_ZONES_SOURCE], 0, ++ [[FWDI_trusted all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([filter], [FORWARD_IN_ZONES], 0, ++ [[FWDI_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ FWDI_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ FWDI_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES_SOURCE], 0, ++ [[FWDO_trusted all -- 0.0.0.0/0 1.2.3.0/24 [goto] ++]]) ++IPTABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES], 0, ++ [[FWDO_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ FWDO_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ FWDO_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([raw], [PREROUTING], 0, [dnl ++ PREROUTING_direct all -- 0.0.0.0/0 0.0.0.0/0 ++ PREROUTING_ZONES_SOURCE all -- 0.0.0.0/0 0.0.0.0/0 ++ PREROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0 ++]) ++IPTABLES_LIST_RULES([raw], [PREROUTING_ZONES_SOURCE], 0, ++ [[PRE_trusted all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([raw], [PREROUTING_ZONES], 0, ++ [[PRE_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([mangle], [PREROUTING], 0, [dnl ++ PREROUTING_direct all -- 0.0.0.0/0 0.0.0.0/0 ++ PREROUTING_ZONES_SOURCE all -- 0.0.0.0/0 0.0.0.0/0 ++ PREROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0 ++]) ++IPTABLES_LIST_RULES([mangle], [PREROUTING_ZONES_SOURCE], 0, ++ [[PRE_trusted all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([mangle], [PREROUTING_ZONES], 0, ++ [[PRE_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([nat], [PREROUTING], 0, [dnl ++ PREROUTING_direct all -- 0.0.0.0/0 0.0.0.0/0 ++ PREROUTING_ZONES_SOURCE all -- 0.0.0.0/0 0.0.0.0/0 ++ PREROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0 ++]) ++IPTABLES_LIST_RULES([nat], [PREROUTING_ZONES_SOURCE], 0, ++ [[PRE_trusted all -- 1.2.3.0/24 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([nat], [PREROUTING_ZONES], 0, ++ [[PRE_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ PRE_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([nat], [POSTROUTING], 0, [dnl ++ POSTROUTING_direct all -- 0.0.0.0/0 0.0.0.0/0 ++ POSTROUTING_ZONES_SOURCE all -- 0.0.0.0/0 0.0.0.0/0 ++ POSTROUTING_ZONES all -- 0.0.0.0/0 0.0.0.0/0 ++]) ++IPTABLES_LIST_RULES([nat], [POSTROUTING_ZONES_SOURCE], 0, ++ [[POST_trusted all -- 0.0.0.0/0 1.2.3.0/24 [goto] ++]]) ++IPTABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, ++ [[POST_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ POST_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ POST_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) ++ ++IP6TABLES_LIST_RULES([filter], [INPUT], 0, [dnl ++ ACCEPT all ::/0 ::/0 ctstate RELATED,ESTABLISHED,DNAT ++ ACCEPT all ::/0 ::/0 ++ INPUT_direct all ::/0 ::/0 ++ INPUT_ZONES_SOURCE all ::/0 ::/0 ++ INPUT_ZONES all ::/0 ::/0 ++ DROP all ::/0 ::/0 ctstate INVALID ++ REJECT all ::/0 ::/0 reject-with icmp6-adm-prohibited ++]) ++IP6TABLES_LIST_RULES([filter], [INPUT_ZONES_SOURCE], 0, ++ [[IN_public all dead:beef::/54 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([filter], [INPUT_ZONES], 0, ++ [[IN_trusted all ::/0 ::/0 [goto] ++ IN_public all ::/0 ::/0 [goto] ++ IN_public all ::/0 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([filter], [FORWARD], 0, [dnl ++ ACCEPT all ::/0 ::/0 ctstate RELATED,ESTABLISHED,DNAT ++ ACCEPT all ::/0 ::/0 ++ FORWARD_direct all ::/0 ::/0 ++ RFC3964_IPv4 all ::/0 ::/0 ++ FORWARD_IN_ZONES_SOURCE all ::/0 ::/0 ++ FORWARD_IN_ZONES all ::/0 ::/0 ++ FORWARD_OUT_ZONES_SOURCE all ::/0 ::/0 ++ FORWARD_OUT_ZONES all ::/0 ::/0 ++ DROP all ::/0 ::/0 ctstate INVALID ++ REJECT all ::/0 ::/0 reject-with icmp6-adm-prohibited ++]) ++IP6TABLES_LIST_RULES([filter], [FORWARD_IN_ZONES_SOURCE], 0, ++ [[FWDI_public all dead:beef::/54 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([filter], [FORWARD_IN_ZONES], 0, ++ [[FWDI_trusted all ::/0 ::/0 [goto] ++ FWDI_public all ::/0 ::/0 [goto] ++ FWDI_public all ::/0 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES_SOURCE], 0, ++ [[FWDO_public all ::/0 dead:beef::/54 [goto] ++]]) ++IP6TABLES_LIST_RULES([filter], [FORWARD_OUT_ZONES], 0, ++ [[FWDO_trusted all ::/0 ::/0 [goto] ++ FWDO_public all ::/0 ::/0 [goto] ++ FWDO_public all ::/0 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([raw], [PREROUTING], 0, [dnl ++ ACCEPT icmpv6 ::/0 ::/0 ipv6-icmptype 134 ++ ACCEPT icmpv6 ::/0 ::/0 ipv6-icmptype 135 ++ DROP all ::/0 ::/0 rpfilter invert ++ PREROUTING_direct all ::/0 ::/0 ++ PREROUTING_ZONES_SOURCE all ::/0 ::/0 ++ PREROUTING_ZONES all ::/0 ::/0 ++]) ++IP6TABLES_LIST_RULES([raw], [PREROUTING_ZONES_SOURCE], 0, ++ [[PRE_public all dead:beef::/54 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([raw], [PREROUTING_ZONES], 0, ++ [[PRE_trusted all ::/0 ::/0 [goto] ++ PRE_public all ::/0 ::/0 [goto] ++ PRE_public all ::/0 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([mangle], [PREROUTING], 0, [dnl ++ PREROUTING_direct all ::/0 ::/0 ++ PREROUTING_ZONES_SOURCE all ::/0 ::/0 ++ PREROUTING_ZONES all ::/0 ::/0 ++]) ++IP6TABLES_LIST_RULES([mangle], [PREROUTING_ZONES_SOURCE], 0, ++ [[PRE_public all dead:beef::/54 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([mangle], [PREROUTING_ZONES], 0, ++ [[PRE_trusted all ::/0 ::/0 [goto] ++ PRE_public all ::/0 ::/0 [goto] ++ PRE_public all ::/0 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([nat], [PREROUTING], 0, [dnl ++ PREROUTING_direct all ::/0 ::/0 ++ PREROUTING_ZONES_SOURCE all ::/0 ::/0 ++ PREROUTING_ZONES all ::/0 ::/0 ++]) ++IP6TABLES_LIST_RULES([nat], [PREROUTING_ZONES_SOURCE], 0, ++ [[PRE_public all dead:beef::/54 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([nat], [PREROUTING_ZONES], 0, ++ [[PRE_trusted all ::/0 ::/0 [goto] ++ PRE_public all ::/0 ::/0 [goto] ++ PRE_public all ::/0 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([nat], [POSTROUTING], 0, [dnl ++ POSTROUTING_direct all ::/0 ::/0 ++ POSTROUTING_ZONES_SOURCE all ::/0 ::/0 ++ POSTROUTING_ZONES all ::/0 ::/0 ++]) ++IP6TABLES_LIST_RULES([nat], [POSTROUTING_ZONES_SOURCE], 0, ++ [[POST_public all ::/0 dead:beef::/54 [goto] ++]]) ++IP6TABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, ++ [[POST_trusted all ::/0 ::/0 [goto] + POST_public all ::/0 ::/0 [goto] +- POST_work all ::/0 ::/0 [goto] + POST_public all ::/0 ::/0 [goto] + ]]) + +-FWD_END_TEST ++FWD_END_TEST([-e '/WARNING: AllowZoneDrifting is enabled. This is considered an insecure configuration option. It will be removed in a future release. Please consider disabling it now./d']) +diff --git a/src/tests/regression/rhbz1734765.at b/src/tests/regression/rhbz1734765.at +index 168be70a2900..3751e60204e4 100644 +--- a/src/tests/regression/rhbz1734765.at ++++ b/src/tests/regression/rhbz1734765.at +@@ -1,9 +1,12 @@ + FWD_START_TEST([zone sources ordered by name]) +-AT_KEYWORDS(zone rhbz1734765 rhbz1421222 gh166 rhbz1738545) ++AT_KEYWORDS(zone rhbz1734765 rhbz1421222 gh166 rhbz1738545 rhbz1772208 rhbz1796055) + dnl + dnl Users depend on firewalld ordering source-based zone dispatch by zone name. + dnl + ++AT_CHECK([sed -i 's/^AllowZoneDrifting.*/AllowZoneDrifting=no/' ./firewalld.conf]) ++FWD_RELOAD ++ + FWD_CHECK([-q --permanent --new-zone=foobar_00]) + FWD_CHECK([-q --permanent --new-zone=foobar_05]) + FWD_CHECK([-q --permanent --new-zone=foobar_02]) +@@ -196,4 +199,177 @@ IP6TABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, + POST_public all ::/0 ::/0 [goto] + ]]) + +-FWD_END_TEST ++dnl ########################################################################## ++dnl ########################################################################## ++dnl We also support zone drifting in which source based zones fall through to ++dnl interface based zones (including default zone). So make sure the zones are ++dnl sorted by name in this mode. ++dnl ########################################################################## ++dnl ########################################################################## ++AT_CHECK([sed -i 's/^AllowZoneDrifting.*/AllowZoneDrifting=yes/' ./firewalld.conf]) ++FWD_RELOAD ++ ++FWD_CHECK([-q --zone=foobar_010 --add-source="10.10.10.10"]) ++FWD_CHECK([-q --zone=public --add-source="20.20.20.20"]) ++IF_IPV6_SUPPORTED([ ++FWD_CHECK([-q --zone=foobar_010 --add-source="1234:5678::10:10:10"]) ++FWD_CHECK([-q --zone=public --add-source="1234:5678::20:20:20"]) ++FWD_CHECK([-q --zone=foobar_012 --add-source ipset:ipsetv6]) ++]) ++FWD_CHECK([-q --zone=foobar_010 --add-interface=foobar2]) ++ ++NFT_LIST_RULES([inet], [filter_INPUT_ZONES_SOURCE], 0, [dnl ++ table inet firewalld { ++ chain filter_INPUT_ZONES_SOURCE { ++ ip saddr 10.1.1.1 goto filter_IN_foobar_00 ++ ip6 saddr 1234:5678::1:1:1 goto filter_IN_foobar_00 ++ ip saddr 10.1.1.0/24 goto filter_IN_foobar_01 ++ ip6 saddr 1234:5678::1:1:0/112 goto filter_IN_foobar_01 ++ ip saddr 10.10.10.10 goto filter_IN_foobar_010 ++ ip6 saddr 1234:5678::10:10:10 goto filter_IN_foobar_010 ++ ip saddr @ipsetv4 goto filter_IN_foobar_011 ++ ip6 saddr @ipsetv6 goto filter_IN_foobar_012 ++ ip saddr 10.1.0.0/16 goto filter_IN_foobar_02 ++ ip6 saddr 1234:5678::1:0:0/96 goto filter_IN_foobar_02 ++ ip saddr 10.2.2.0/24 goto filter_IN_foobar_03 ++ ip6 saddr 1234:5678::2:2:0/112 goto filter_IN_foobar_03 ++ ip saddr 10.2.0.0/16 goto filter_IN_foobar_04 ++ ip6 saddr 1234:5678::2:0:0/96 goto filter_IN_foobar_04 ++ ip saddr 10.0.0.0/8 goto filter_IN_foobar_05 ++ ip6 saddr 1234:5678::/80 goto filter_IN_foobar_05 ++ ip saddr 20.20.20.20 goto filter_IN_public ++ ip6 saddr 1234:5678::20:20:20 goto filter_IN_public ++ } ++ } ++]) ++NFT_LIST_RULES([inet], [filter_INPUT_ZONES], 0, [dnl ++ table inet firewalld { ++ chain filter_INPUT_ZONES { ++ iifname "foobar2" goto filter_IN_foobar_010 ++ iifname "foobar1" goto filter_IN_trusted ++ iifname "foobar0" goto filter_IN_internal ++ goto filter_IN_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip], [nat_POSTROUTING_ZONES_SOURCE], 0, [dnl ++ table ip firewalld { ++ chain nat_POSTROUTING_ZONES_SOURCE { ++ ip daddr 10.1.1.1 goto nat_POST_foobar_00 ++ ip daddr 10.1.1.0/24 goto nat_POST_foobar_01 ++ ip daddr 10.10.10.10 goto nat_POST_foobar_010 ++ ip daddr @ipsetv4 goto nat_POST_foobar_011 ++ ip daddr 10.1.0.0/16 goto nat_POST_foobar_02 ++ ip daddr 10.2.2.0/24 goto nat_POST_foobar_03 ++ ip daddr 10.2.0.0/16 goto nat_POST_foobar_04 ++ ip daddr 10.0.0.0/8 goto nat_POST_foobar_05 ++ ip daddr 20.20.20.20 goto nat_POST_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip], [nat_POSTROUTING_ZONES], 0, [dnl ++ table ip firewalld { ++ chain nat_POSTROUTING_ZONES { ++ oifname "foobar2" goto nat_POST_foobar_010 ++ oifname "foobar1" goto nat_POST_trusted ++ oifname "foobar0" goto nat_POST_internal ++ goto nat_POST_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip6], [nat_POSTROUTING_ZONES_SOURCE], 0, [dnl ++ table ip6 firewalld { ++ chain nat_POSTROUTING_ZONES_SOURCE { ++ ip6 daddr 1234:5678::1:1:1 goto nat_POST_foobar_00 ++ ip6 daddr 1234:5678::1:1:0/112 goto nat_POST_foobar_01 ++ ip6 daddr 1234:5678::10:10:10 goto nat_POST_foobar_010 ++ ip6 daddr @ipsetv6 goto nat_POST_foobar_012 ++ ip6 daddr 1234:5678::1:0:0/96 goto nat_POST_foobar_02 ++ ip6 daddr 1234:5678::2:2:0/112 goto nat_POST_foobar_03 ++ ip6 daddr 1234:5678::2:0:0/96 goto nat_POST_foobar_04 ++ ip6 daddr 1234:5678::/80 goto nat_POST_foobar_05 ++ ip6 daddr 1234:5678::20:20:20 goto nat_POST_public ++ } ++ } ++]) ++NFT_LIST_RULES([ip6], [nat_POSTROUTING_ZONES], 0, [dnl ++ table ip6 firewalld { ++ chain nat_POSTROUTING_ZONES { ++ oifname "foobar2" goto nat_POST_foobar_010 ++ oifname "foobar1" goto nat_POST_trusted ++ oifname "foobar0" goto nat_POST_internal ++ goto nat_POST_public ++ } ++ } ++]) ++ ++IPTABLES_LIST_RULES([filter], [INPUT_ZONES_SOURCE], 0, ++ [[IN_foobar_00 all -- 10.1.1.1 0.0.0.0/0 [goto] ++ IN_foobar_01 all -- 10.1.1.0/24 0.0.0.0/0 [goto] ++ IN_foobar_010 all -- 10.10.10.10 0.0.0.0/0 [goto] ++ IN_foobar_011 all -- 0.0.0.0/0 0.0.0.0/0 [goto] match-set ipsetv4 src ++ IN_foobar_02 all -- 10.1.0.0/16 0.0.0.0/0 [goto] ++ IN_foobar_03 all -- 10.2.2.0/24 0.0.0.0/0 [goto] ++ IN_foobar_04 all -- 10.2.0.0/16 0.0.0.0/0 [goto] ++ IN_foobar_05 all -- 10.0.0.0/8 0.0.0.0/0 [goto] ++ IN_public all -- 20.20.20.20 0.0.0.0/0 [goto] ++]]) ++IPTABLES_LIST_RULES([filter], [INPUT_ZONES], 0, ++ [[IN_foobar_010 all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ IN_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ IN_internal all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ IN_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([filter], [INPUT_ZONES_SOURCE], 0, ++ [[IN_foobar_00 all 1234:5678::1:1:1 ::/0 [goto] ++ IN_foobar_01 all 1234:5678::1:1:0/112 ::/0 [goto] ++ IN_foobar_010 all 1234:5678::10:10:10 ::/0 [goto] ++ IN_foobar_012 all ::/0 ::/0 [goto] match-set ipsetv6 src ++ IN_foobar_02 all 1234:5678::1:0:0/96 ::/0 [goto] ++ IN_foobar_03 all 1234:5678::2:2:0/112 ::/0 [goto] ++ IN_foobar_04 all 1234:5678::2:0:0/96 ::/0 [goto] ++ IN_foobar_05 all 1234:5678::/80 ::/0 [goto] ++ IN_public all 1234:5678::20:20:20 ::/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([filter], [INPUT_ZONES], 0, ++ [[IN_foobar_010 all ::/0 ::/0 [goto] ++ IN_trusted all ::/0 ::/0 [goto] ++ IN_internal all ::/0 ::/0 [goto] ++ IN_public all ::/0 ::/0 [goto] ++]]) ++IPTABLES_LIST_RULES([nat], [POSTROUTING_ZONES_SOURCE], 0, ++ [[POST_foobar_00 all -- 0.0.0.0/0 10.1.1.1 [goto] ++ POST_foobar_01 all -- 0.0.0.0/0 10.1.1.0/24 [goto] ++ POST_foobar_010 all -- 0.0.0.0/0 10.10.10.10 [goto] ++ POST_foobar_011 all -- 0.0.0.0/0 0.0.0.0/0 [goto] match-set ipsetv4 dst ++ POST_foobar_02 all -- 0.0.0.0/0 10.1.0.0/16 [goto] ++ POST_foobar_03 all -- 0.0.0.0/0 10.2.2.0/24 [goto] ++ POST_foobar_04 all -- 0.0.0.0/0 10.2.0.0/16 [goto] ++ POST_foobar_05 all -- 0.0.0.0/0 10.0.0.0/8 [goto] ++ POST_public all -- 0.0.0.0/0 20.20.20.20 [goto] ++]]) ++IPTABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, ++ [[POST_foobar_010 all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ POST_trusted all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ POST_internal all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++ POST_public all -- 0.0.0.0/0 0.0.0.0/0 [goto] ++]]) ++IP6TABLES_LIST_RULES([nat], [POSTROUTING_ZONES_SOURCE], 0, ++ [[POST_foobar_00 all ::/0 1234:5678::1:1:1 [goto] ++ POST_foobar_01 all ::/0 1234:5678::1:1:0/112 [goto] ++ POST_foobar_010 all ::/0 1234:5678::10:10:10 [goto] ++ POST_foobar_012 all ::/0 ::/0 [goto] match-set ipsetv6 dst ++ POST_foobar_02 all ::/0 1234:5678::1:0:0/96 [goto] ++ POST_foobar_03 all ::/0 1234:5678::2:2:0/112 [goto] ++ POST_foobar_04 all ::/0 1234:5678::2:0:0/96 [goto] ++ POST_foobar_05 all ::/0 1234:5678::/80 [goto] ++ POST_public all ::/0 1234:5678::20:20:20 [goto] ++]]) ++IP6TABLES_LIST_RULES([nat], [POSTROUTING_ZONES], 0, ++ [[POST_foobar_010 all ::/0 ::/0 [goto] ++ POST_trusted all ::/0 ::/0 [goto] ++ POST_internal all ::/0 ::/0 [goto] ++ POST_public all ::/0 ::/0 [goto] ++]]) ++ ++FWD_END_TEST([-e '/WARNING: AllowZoneDrifting is enabled. This is considered an insecure configuration option. It will be removed in a future release. Please consider disabling it now./d']) +-- +2.23.0 + diff --git a/SOURCES/0034-fix-firewall-offline-cmd-Don-t-print-warning-about-A.patch b/SOURCES/0034-fix-firewall-offline-cmd-Don-t-print-warning-about-A.patch new file mode 100644 index 0000000..28f6915 --- /dev/null +++ b/SOURCES/0034-fix-firewall-offline-cmd-Don-t-print-warning-about-A.patch @@ -0,0 +1,39 @@ +From 8b332eae015f215f9db3f2cd2961ebfcec9e2b1a Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Tue, 4 Feb 2020 13:12:31 -0500 +Subject: [PATCH 34/35] fix: firewall-offline-cmd: Don't print warning about + AllowZoneDrifting + +If we're called from firewall-offline-cmd, don't log the warning. It's +overly verbose to warn on every invocation. + +Fixes: afadd377b09d ("feat: AllowZoneDrifting config option") +(cherry picked from commit eefcb1a712ffca5e08dcefa6aa17c935c16b835f) +(cherry picked from commit b6d3bd4c4359523b483eb630f9265cc4cbe408f2) +--- + src/firewall/core/fw.py | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/src/firewall/core/fw.py b/src/firewall/core/fw.py +index 07bc9f375771..969052bd92bd 100644 +--- a/src/firewall/core/fw.py ++++ b/src/firewall/core/fw.py +@@ -331,10 +331,11 @@ class Firewall(object): + self._allow_zone_drifting = False + else: + self._allow_zone_drifting = True +- log.warning("AllowZoneDrifting is enabled. This is considered " +- "an insecure configuration option. It will be " +- "removed in a future release. Please consider " +- "disabling it now.") ++ if not self._offline: ++ log.warning("AllowZoneDrifting is enabled. This is considered " ++ "an insecure configuration option. It will be " ++ "removed in a future release. Please consider " ++ "disabling it now.") + log.debug1("AllowZoneDrifting is set to '%s'", + self._allow_zone_drifting) + +-- +2.23.0 + diff --git a/SOURCES/0035-RHEL-only-default-to-AllowZoneDrifting-yes.patch b/SOURCES/0035-RHEL-only-default-to-AllowZoneDrifting-yes.patch new file mode 100644 index 0000000..98ac334 --- /dev/null +++ b/SOURCES/0035-RHEL-only-default-to-AllowZoneDrifting-yes.patch @@ -0,0 +1,138 @@ +From e9a5699dcb4e50dacbf1350b39a95dc9aef6cefa Mon Sep 17 00:00:00 2001 +From: Eric Garver +Date: Tue, 4 Feb 2020 09:12:17 -0500 +Subject: [PATCH 35/35] RHEL only: default to AllowZoneDrifting=yes + +--- + config/firewalld.conf | 4 ++-- + doc/xml/firewalld.conf.xml | 2 +- + doc/xml/firewalld.dbus.xml | 2 +- + src/firewall/config/__init__.py.in | 2 +- + src/tests/dbus/firewalld.conf.at | 2 +- + src/tests/features/rfc3964_ipv4.at | 4 ++++ + src/tests/firewall-cmd.at | 4 ++++ + src/tests/functions.at | 1 + + src/tests/regression/rhbz1514043.at | 4 ++++ + 9 files changed, 19 insertions(+), 6 deletions(-) + +diff --git a/config/firewalld.conf b/config/firewalld.conf +index ebf8021226b7..6d0feb88f7c3 100644 +--- a/config/firewalld.conf ++++ b/config/firewalld.conf +@@ -81,5 +81,5 @@ RFC3964_IPv4=yes + # Note: If "yes" packets will only drift from source based zones to interface + # based zones (including the default zone). Packets never drift from interface + # based zones to other interfaces based zones (including the default zone). +-# Possible values; "yes", "no". Defaults to "no". +-AllowZoneDrifting=no ++# Possible values; "yes", "no". Defaults to "yes". ++AllowZoneDrifting=yes +diff --git a/doc/xml/firewalld.conf.xml b/doc/xml/firewalld.conf.xml +index 8108066e88bf..9574c567867f 100644 +--- a/doc/xml/firewalld.conf.xml ++++ b/doc/xml/firewalld.conf.xml +@@ -197,7 +197,7 @@ + to interface based zones (including the default zone). Packets + never drift from interface based zones to other interfaces + based zones (including the default zone). +- Valid values; "yes", "no". Defaults to "no". ++ Valid values; "yes", "no". Defaults to "yes". + + + +diff --git a/doc/xml/firewalld.dbus.xml b/doc/xml/firewalld.dbus.xml +index f72bad526d65..408787594035 100644 +--- a/doc/xml/firewalld.dbus.xml ++++ b/doc/xml/firewalld.dbus.xml +@@ -2590,7 +2590,7 @@ + to interface based zones (including the default zone). Packets + never drift from interface based zones to other interfaces + based zones (including the default zone). +- Valid values; "yes", "no". Defaults to "no". ++ Valid values; "yes", "no". Defaults to "yes". + + + +diff --git a/src/firewall/config/__init__.py.in b/src/firewall/config/__init__.py.in +index c009d93e4164..fbef1828c8aa 100644 +--- a/src/firewall/config/__init__.py.in ++++ b/src/firewall/config/__init__.py.in +@@ -132,4 +132,4 @@ FALLBACK_AUTOMATIC_HELPERS = "system" + FALLBACK_FIREWALL_BACKEND = "nftables" + FALLBACK_FLUSH_ALL_ON_RELOAD = True + FALLBACK_RFC3964_IPV4 = True +-FALLBACK_ALLOW_ZONE_DRIFTING = False ++FALLBACK_ALLOW_ZONE_DRIFTING = True +diff --git a/src/tests/dbus/firewalld.conf.at b/src/tests/dbus/firewalld.conf.at +index 65ac702f4713..de3780e5b5e4 100644 +--- a/src/tests/dbus/firewalld.conf.at ++++ b/src/tests/dbus/firewalld.conf.at +@@ -3,7 +3,7 @@ AT_KEYWORDS(dbus) + + dnl Verify defaults over dbus. Should be inline with default firewalld.conf. + DBUS_GETALL([config], [config], 0, [dnl +-string "AllowZoneDrifting" : variant string "no" ++string "AllowZoneDrifting" : variant string "yes" + string "AutomaticHelpers" : variant string "system" + string "CleanupOnExit" : variant string "no" + string "DefaultZone" : variant string "public" +diff --git a/src/tests/features/rfc3964_ipv4.at b/src/tests/features/rfc3964_ipv4.at +index 54f5f756270b..15fef52612cc 100644 +--- a/src/tests/features/rfc3964_ipv4.at ++++ b/src/tests/features/rfc3964_ipv4.at +@@ -1,6 +1,10 @@ + FWD_START_TEST([RFC3964_IPv4]) + AT_KEYWORDS(rfc3964_ipv4) + ++dnl Expected test results assume this is set to "no" ++AT_CHECK([sed -i 's/^AllowZoneDrifting.*/AllowZoneDrifting=no/' ./firewalld.conf]) ++FWD_RELOAD ++ + AT_CHECK([sed -i 's/^LogDenied.*/LogDenied=all/' ./firewalld.conf]) + AT_CHECK([sed -i 's/^RFC3964_IPv4.*/RFC3964_IPv4=yes/' ./firewalld.conf]) + FWD_RELOAD +diff --git a/src/tests/firewall-cmd.at b/src/tests/firewall-cmd.at +index 53f2eb2c7c88..ad6ed9540c7f 100644 +--- a/src/tests/firewall-cmd.at ++++ b/src/tests/firewall-cmd.at +@@ -970,6 +970,10 @@ FWD_START_TEST([rich rules priority]) + + CHECK_LOG_AUDIT + ++ dnl Expected test results assume this is set to "no" ++ AT_CHECK([sed -i 's/^AllowZoneDrifting.*/AllowZoneDrifting=no/' ./firewalld.conf]) ++ FWD_RELOAD ++ + dnl Verify generic layout of zone + NFT_LIST_RULES([inet], [filter_IN_public], 0, [dnl + table inet firewalld { +diff --git a/src/tests/functions.at b/src/tests/functions.at +index 3771bb8bd5a7..ef7c696ddf73 100644 +--- a/src/tests/functions.at ++++ b/src/tests/functions.at +@@ -149,6 +149,7 @@ m4_define([FWD_END_TEST], [ + IF_IPV6_SUPPORTED([], [ + sed -i "/WARNING: ip6tables not usable, disabling IPv6 firewall/d" ./firewalld.log + ]) ++ sed -i "/WARNING: AllowZoneDrifting is enabled./d" ./firewalld.log + if test x"$1" != x"ignore"; then + if test -n "$1"; then + sed -i $1 ./firewalld.log +diff --git a/src/tests/regression/rhbz1514043.at b/src/tests/regression/rhbz1514043.at +index 241cf547f7f3..8e4846a078b8 100644 +--- a/src/tests/regression/rhbz1514043.at ++++ b/src/tests/regression/rhbz1514043.at +@@ -1,6 +1,10 @@ + FWD_START_TEST([--set-log-denied does not zero config]) + AT_KEYWORDS(log_denied rhbz1514043) + ++dnl Expected test results assume this is set to "no" ++AT_CHECK([sed -i 's/^AllowZoneDrifting.*/AllowZoneDrifting=no/' ./firewalld.conf]) ++FWD_RELOAD ++ + FWD_CHECK([-q --set-log-denied=all]) + FWD_CHECK([-q --permanent --zone=public --add-service=samba]) + FWD_RELOAD +-- +2.23.0 + diff --git a/SPECS/firewalld.spec b/SPECS/firewalld.spec index 14a9d87..dcba27d 100644 --- a/SPECS/firewalld.spec +++ b/SPECS/firewalld.spec @@ -1,7 +1,7 @@ Summary: A firewall daemon with D-Bus interface providing a dynamic firewall Name: firewalld Version: 0.7.0 -Release: 5%{?dist} +Release: 5%{?dist}.1 URL: http://www.firewalld.org License: GPLv2+ Source0: https://github.com/firewalld/firewalld/releases/download/v%{version}/firewalld-%{version}.tar.gz @@ -34,6 +34,12 @@ Patch26: 0025-test-verify-source-based-zone-dispatch-ordered-by-zo.patch Patch27: 0026-fix-test-regression-rhbz1734765-guard-IPv6-usage.patch Patch28: 0027-fix-nftables-fix-zone-dispatch-using-ipset-sources-i.patch Patch29: 0028-test-regression-rhbz1734765-add-coverage-for-rhbz-17.patch +Patch30: 0030-feat-AllowZoneDrifting-config-option.patch +Patch31: 0031-feat-nftables-support-AllowZoneDrifting-yes.patch +Patch32: 0032-feat-ipXtables-support-AllowZoneDrifting-yes.patch +Patch33: 0033-test-verify-AllowZoneDrifting-yes.patch +Patch34: 0034-fix-firewall-offline-cmd-Don-t-print-warning-about-A.patch +Patch35: 0035-RHEL-only-default-to-AllowZoneDrifting-yes.patch BuildArch: noarch BuildRequires: autoconf @@ -232,6 +238,9 @@ desktop-file-install --delete-original \ %{_mandir}/man1/firewall-config*.1* %changelog +* Wed Feb 05 2020 Eric Garver - 0.7.0-5.el8_1_0.1 +- restore zone drifting as a feature + * Tue Aug 13 2019 Eric Garver - 0.7.0-5 - bump nftables version requirements