From 8d480dea4b3fd4ecce20c1569d000cb999dd50f6 Mon Sep 17 00:00:00 2001
From: Eric Garver <eric@garver.life>
Date: Sun, 19 Jan 2020 14:37:31 -0500
Subject: [PATCH 31/37] feat: nftables: support AllowZoneDrifting=yes
(cherry picked from commit 517a061c5886f2ebfb4aa7d73804aa7f3c5a3004)
(cherry picked from commit 92c5926bb9e493545f8d949ba00cbf72e4c7f202)
---
src/firewall/core/nftables.py | 91 ++++++++++++++++++++---------------
1 file changed, 52 insertions(+), 39 deletions(-)
diff --git a/src/firewall/core/nftables.py b/src/firewall/core/nftables.py
index cb8521fb7a5a..c8e893b5dbf6 100644
--- a/src/firewall/core/nftables.py
+++ b/src/firewall/core/nftables.py
@@ -208,8 +208,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])
+
_verb_snippet = rule[verb]
del rule[verb]
if index == 0:
@@ -506,13 +509,14 @@ class nftables(object):
"prio": IPTABLES_TO_NFT_HOOK["raw"][chain][1]}}})
for chain in ["PREROUTING"]:
- default_rules.append({"add": {"chain": {"family": "inet",
- "table": TABLE_NAME,
- "name": "raw_%s_ZONES" % chain}}})
- default_rules.append({"add": {"rule": {"family": "inet",
- "table": TABLE_NAME,
- "chain": "raw_%s" % chain,
- "expr": [{"jump": {"target": "raw_%s_ZONES" % chain}}]}}})
+ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]:
+ default_rules.append({"add": {"chain": {"family": "inet",
+ "table": TABLE_NAME,
+ "name": "raw_%s_%s" % (chain, dispatch_suffix)}}})
+ default_rules.append({"add": {"rule": {"family": "inet",
+ "table": TABLE_NAME,
+ "chain": "raw_%s" % chain,
+ "expr": [{"jump": {"target": "raw_%s_%s" % (chain, dispatch_suffix)}}]}}})
for chain in IPTABLES_TO_NFT_HOOK["mangle"].keys():
default_rules.append({"add": {"chain": {"family": "inet",
@@ -521,13 +525,14 @@ class nftables(object):
"type": "filter",
"hook": "%s" % IPTABLES_TO_NFT_HOOK["mangle"][chain][0],
"prio": IPTABLES_TO_NFT_HOOK["mangle"][chain][1]}}})
- default_rules.append({"add": {"chain": {"family": "inet",
- "table": TABLE_NAME,
- "name": "mangle_%s_ZONES" % chain}}})
- default_rules.append({"add": {"rule": {"family": "inet",
- "table": TABLE_NAME,
- "chain": "mangle_%s" % chain,
- "expr": [{"jump": {"target": "mangle_%s_ZONES" % chain}}]}}})
+ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]:
+ default_rules.append({"add": {"chain": {"family": "inet",
+ "table": TABLE_NAME,
+ "name": "mangle_%s_%s" % (chain, dispatch_suffix)}}})
+ default_rules.append({"add": {"rule": {"family": "inet",
+ "table": TABLE_NAME,
+ "chain": "mangle_%s" % chain,
+ "expr": [{"jump": {"target": "mangle_%s_%s" % (chain, dispatch_suffix)}}]}}})
for family in ["ip", "ip6"]:
for chain in IPTABLES_TO_NFT_HOOK["nat"].keys():
@@ -537,13 +542,15 @@ class nftables(object):
"type": "nat",
"hook": "%s" % IPTABLES_TO_NFT_HOOK["nat"][chain][0],
"prio": IPTABLES_TO_NFT_HOOK["nat"][chain][1]}}})
- default_rules.append({"add": {"chain": {"family": family,
- "table": TABLE_NAME,
- "name": "nat_%s_ZONES" % chain}}})
- default_rules.append({"add": {"rule": {"family": family,
- "table": TABLE_NAME,
- "chain": "nat_%s" % chain,
- "expr": [{"jump": {"target": "nat_%s_ZONES" % chain}}]}}})
+
+ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]:
+ default_rules.append({"add": {"chain": {"family": family,
+ "table": TABLE_NAME,
+ "name": "nat_%s_%s" % (chain, dispatch_suffix)}}})
+ default_rules.append({"add": {"rule": {"family": family,
+ "table": TABLE_NAME,
+ "chain": "nat_%s" % chain,
+ "expr": [{"jump": {"target": "nat_%s_%s" % (chain, dispatch_suffix)}}]}}})
for chain in IPTABLES_TO_NFT_HOOK["filter"].keys():
default_rules.append({"add": {"chain": {"family": "inet",
@@ -554,9 +561,6 @@ class nftables(object):
"prio": IPTABLES_TO_NFT_HOOK["filter"][chain][1]}}})
# filter, INPUT
- default_rules.append({"add": {"chain": {"family": "inet",
- "table": TABLE_NAME,
- "name": "filter_%s_ZONES" % "INPUT"}}})
default_rules.append({"add": {"rule": {"family": "inet",
"table": TABLE_NAME,
"chain": "filter_%s" % "INPUT",
@@ -578,10 +582,14 @@ class nftables(object):
"op": "==",
"right": "lo"}},
{"accept": None}]}}})
- default_rules.append({"add": {"rule": {"family": "inet",
- "table": TABLE_NAME,
- "chain": "filter_%s" % "INPUT",
- "expr": [{"jump": {"target": "filter_%s_ZONES" % "INPUT"}}]}}})
+ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]:
+ default_rules.append({"add": {"chain": {"family": "inet",
+ "table": TABLE_NAME,
+ "name": "filter_%s_%s" % ("INPUT", dispatch_suffix)}}})
+ default_rules.append({"add": {"rule": {"family": "inet",
+ "table": TABLE_NAME,
+ "chain": "filter_%s" % "INPUT",
+ "expr": [{"jump": {"target": "filter_%s_%s" % ("INPUT", dispatch_suffix)}}]}}})
if log_denied != "off":
default_rules.append({"add": {"rule": {"family": "inet",
"table": TABLE_NAME,
@@ -610,10 +618,6 @@ class nftables(object):
"expr": [{"reject": {"type": "icmpx", "expr": "admin-prohibited"}}]}}})
# filter, FORWARD
- for direction in ["IN", "OUT"]:
- default_rules.append({"add": {"chain": {"family": "inet",
- "table": TABLE_NAME,
- "name": "filter_%s_%s_ZONES" % ("FORWARD", direction)}}})
default_rules.append({"add": {"rule": {"family": "inet",
"table": TABLE_NAME,
"chain": "filter_%s" % "FORWARD",
@@ -636,10 +640,14 @@ class nftables(object):
"right": "lo"}},
{"accept": None}]}}})
for direction in ["IN", "OUT"]:
- default_rules.append({"add": {"rule": {"family": "inet",
- "table": TABLE_NAME,
- "chain": "filter_%s" % "FORWARD",
- "expr": [{"jump": {"target": "filter_%s_%s_ZONES" % ("FORWARD", direction)}}]}}})
+ for dispatch_suffix in ["ZONES_SOURCE", "ZONES"] if self._fw._allow_zone_drifting else ["ZONES"]:
+ default_rules.append({"add": {"chain": {"family": "inet",
+ "table": TABLE_NAME,
+ "name": "filter_%s_%s_%s" % ("FORWARD", direction, dispatch_suffix)}}})
+ default_rules.append({"add": {"rule": {"family": "inet",
+ "table": TABLE_NAME,
+ "chain": "filter_%s" % "FORWARD",
+ "expr": [{"jump": {"target": "filter_%s_%s_%s" % ("FORWARD", direction, dispatch_suffix)}}]}}})
if log_denied != "off":
default_rules.append({"add": {"rule": {"family": "inet",
"table": TABLE_NAME,
@@ -778,12 +786,17 @@ 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"
rule = {"family": family,
"table": TABLE_NAME,
- "chain": "%s_%s_ZONES" % (table, chain),
+ "chain": zone_dispatch_chain,
"expr": [self._rule_addr_fragment(opt, address),
{action: {"target": "%s_%s" % (table, target)}}]}
rule.update(self._zone_source_fragment(zone, address))
--
2.23.0