瀏覽代碼

nftables: Update uRPF interface classification code

  * Move classification wether to apply uRPF or not into separate function
  * Add GRE-tunnels to ignore list
  * Add tag based overide option to active uRPF

Signed-off-by: Maximilian Wilhelm <max@sdn.clinic>
Maximilian Wilhelm 2 年之前
父節點
當前提交
c3e585fafd
共有 1 個文件被更改,包括 46 次插入27 次删除
  1. 46 27
      _modules/ffho_netfilter.py

+ 46 - 27
_modules/ffho_netfilter.py

@@ -7,6 +7,11 @@ import re
 
 import ffho_net
 
+
+# Prepare regex to match VLAN intefaces / extract IDs
+vlan_re = re.compile (r'^vlan(\d+)$')
+
+
 def generate_service_rules (services, acls, af):
 	rules = []
 
@@ -147,42 +152,56 @@ def generate_nat_policy (roles, config_context):
 	return np
 
 
-def generate_urpf_policy (interfaces):
-	urpf = {}
+def _active_urpf (iface, iface_config):
+	# Ignore loopback
+	if iface == "lo":
+		return False
 
-	vlan_re = re.compile (r'^vlan(\d+)$')
+	# Forcefully enable uRPF via tags on Netbox interface?
+	if 'urpf_enable' in iface_config.get ('tags', []):
+		return True
 
-	for iface in sorted (interfaces.keys ()):
-		iface_config = interfaces[iface]
+	# No uRPF on infra VPNs
+	for vpn_prefix in ["gre_", "ovpn-", "wg-"]:
+		if iface.startswith (vpn_prefix):
+			return False
 
-		# Ignore loopback and VPNs
-		if iface == "lo" or iface.startswith ("ovpn-") or iface.startswith ("wg-"):
-			continue
+	# No address, no uRPF
+	if not iface_config.get ('prefixes'):
+		return False
 
-		# No addres, no uRPF
-		if not iface_config.get ('prefixes'):
-			continue
+	# Interface in vrf_external connect to the Internet
+	if iface_config.get ('vrf') in ['vrf_external']:
+		return False
 
-		# Interface in vrf_external connect to the Internet
-		if iface_config.get ('vrf') in ['vrf_external']:
-			continue
+	# Ignore interfaces by VLAN
+	match = vlan_re.search (iface)
+	if match:
+		vid = int (match.group (1))
 
-		# Ignore interfaces by VLAN
-		match = vlan_re.search (iface)
-		if match:
-			vid = int (match.group (1))
+		# Magic
+		if 900 <= vid <= 999:
+			return False
 
-			# Magic
-			if 900 <= vid <= 999:
-				continue
+		# Wired infrastructure stuff
+		if 1000 <= vid <= 1499:
+			return False
 
-			# Wired infrastructure stuff
-			if 1000 <= vid <= 1499:
-				continue
+		# Wireless infrastructure stuff
+		if 2000 <= vid <= 2299:
+			return False
 
-			# Wireless infrastructure stuff
-			if 2000 <= vid <= 2299:
-				continue
+	return True
+
+
+def generate_urpf_policy (interfaces):
+	urpf = {}
+
+	for iface in sorted (interfaces.keys ()):
+		iface_config = interfaces[iface]
+
+		if not _active_urpf (iface, iface_config):
+			continue
 
 		# Ok this seems to be and edge interface
 		urpf[iface] = {