浏览代码

nftables: Clean up generator code + template

  * Move logic from template into Python module
  * Unify API to module functions to trim down Jinja variables

Signed-off-by: Maximilian Wilhelm <max@sdn.clinic>
Maximilian Wilhelm 2 年之前
父节点
当前提交
efda5a5c04
共有 2 个文件被更改,包括 69 次插入35 次删除
  1. 61 15
      _modules/ffho_netfilter.py
  2. 8 20
      nftables/nftables.conf.tmpl

+ 61 - 15
_modules/ffho_netfilter.py

@@ -11,8 +11,22 @@ import ffho_net
 # Prepare regex to match VLAN intefaces / extract IDs
 vlan_re = re.compile (r'^vlan(\d+)$')
 
+################################################################################
+#                          Internal helper functions                           #
+################################################################################
 
-def generate_service_rules (services, acls, af):
+#
+# Check if at least one of the node roles are supposed to run DHCP
+def _allow_dhcp (fw_policy, roles):
+	for dhcp_role in fw_policy.get ('dhcp_roles', []):
+		if dhcp_role in roles:
+			return True
+
+	return False
+
+
+# Generate services rules for the given AF
+def _generate_service_rules (services, acls, af):
 	rules = []
 
 	for srv in services:
@@ -95,7 +109,46 @@ def generate_service_rules (services, acls, af):
 	return rules
 
 
-def generate_forward_policy (policy, roles, config_context):
+################################################################################
+#                               Public functions                               #
+################################################################################
+
+#
+# Generate rules to allow access to services running on this node.
+# Services can either be allow programmatically here or explicitly
+# as Services applied to the device/VM in Netbox
+def generate_service_rules (fw_config, node_config):
+	acls = fw_config.get ('acls', {})
+	fw_policy = fw_config.get ('policy', {})
+
+	services = node_config.get ('services', [])
+	roles = node_config.get ('roles', [])
+
+	rules = {
+		4 : [],
+		6 : [],
+	}
+
+	# Does this node run a DHCP server?
+	if _allow_dhcp (fw_policy, roles):
+		rules[4].append ('udp dport 67 counter accept comment "DHCP"')
+
+	# Allow respondd queries on gateways
+	if 'batman_gw' in roles:
+		rules[6].append ('ip6 saddr fe80::/64 ip6 daddr ff05::2:1001 udp dport 1001 counter accept comment "responnd"')
+
+	# Generate rules for services from Netbox
+	for af in [ 4, 6 ]:
+		rules[af].extend (_generate_service_rules (services, acls, af))
+
+	return rules
+
+
+def generate_forward_policy (fw_config, node_config):
+	policy = fw_config.get ('policy', {})
+	roles = node_config.get ('roles', [])
+	nf_cc = node_config.get ('nftables', {})
+
 	fp = {
 		# Get default policy for packets to be forwarded
 		'policy' : 'drop',
@@ -117,7 +170,7 @@ def generate_forward_policy (policy, roles, config_context):
 		fp['policy_reason'] = "roles: " + ",".join (accept_roles)
 
 	try:
-		cust_rules = config_context['filter']['forward']
+		cust_rules = nf_cc['filter']['forward']
 		for af in [ 4, 6 ]:
 			if af not in cust_rules:
 				continue
@@ -132,14 +185,17 @@ def generate_forward_policy (policy, roles, config_context):
 	return fp
 
 
-def generate_nat_policy (roles, config_context):
+def generate_nat_policy (node_config):
+	roles = node_config.get ('roles', [])
+	nf_cc = node_config.get ('nftables', {})
+
 	np = {
 		4 : {},
 		6 : {},
 	}
 
 	# Any custom rules?
-	cc_nat = config_context.get ('nat')
+	cc_nat = nf_cc.get ('nat')
 	if cc_nat:
 		for chain in ['output', 'prerouting', 'postrouting']:
 			if chain not in cc_nat:
@@ -224,16 +280,6 @@ def generate_urpf_policy (interfaces):
 	return sorted_urpf
 
 
-#
-# Check if at least one of the node roles are supposed to run DHCP
-def allow_dhcp (fw_policy, roles):
-	for dhcp_role in fw_policy.get ('dhcp_roles', []):
-		if dhcp_role in roles:
-			return True
-
-	return False
-
-
 #
 # Get a list of interfaces to allow VXLAN encapsulated traffic on
 def get_vxlan_interfaces (interfaces):

+ 8 - 20
nftables/nftables.conf.tmpl

@@ -3,22 +3,19 @@
 # /etc/nftables.conf - FFHO packet filter configuration
 #
 {%- set node_config = salt['pillar.get']('nodes:' ~ grains['id']) %}
-{%- set nf_cc = node_config.get ('nftables', {}) %}
 {%- set roles = node_config.get ('roles', []) %}
-{%- set services = node_config.get ('services', []) %}
 
-{%- set fw_policy = salt['pillar.get']('firewall:policy', {}) %}
-{%- set acls = salt['pillar.get']('firewall:acls') %}
-{%- set admin_access = salt['pillar.get']('firewall:admin_access') %}
-{%- set ssh = salt['pillar.get']("firewall:ssh") %}
+{%- set fw_config = salt['pillar.get']('firewall', {}) %}
+{%- set admin_access = fw_config.get ('admin_access') %}
+{%- set ssh = fw_config.get ('ssh') %}
 
 {%- set icinga2_queriers = salt['pillar.get']('monitoring:icinga2:queriers', []) %}
 {%- set nms_list = salt['pillar.get']('globals:snmp:nms_list', []) %}
 
-{%- set forward = salt['ffho_netfilter.generate_forward_policy'](fw_policy, roles, nf_cc) %}
-{%- set nat_policy = salt['ffho_netfilter.generate_nat_policy'](roles, nf_cc) %}
+{%- set services = salt['ffho_netfilter.generate_service_rules'](fw_config, node_config) %}
+{%- set forward = salt['ffho_netfilter.generate_forward_policy'](fw_config, node_config) %}
+{%- set nat_policy = salt['ffho_netfilter.generate_nat_policy'](node_config) %}
 {%- set urpf = salt['ffho_netfilter.generate_urpf_policy'](node_config['ifaces']) %}
-{%- set allow_dhcp = salt['ffho_netfilter.allow_dhcp'](fw_policy, roles) %}
 {%- set vxlan_ifaces = salt['ffho_netfilter.get_vxlan_interfaces'](node_config['ifaces']) %}
 
 flush ruleset
@@ -108,11 +105,7 @@ table ip filter {
 	}
 
 	chain services {
-{%- if allow_dhcp %}
-		udp dport 67 counter accept comment "DHCP"
-{%- endif %}
-
-{%- for rule in salt['ffho_netfilter.generate_service_rules'](services, acls, 4) %}
+{%- for rule in services[4] %}
 		{{ rule }}
 {%- endfor %}
 	}
@@ -232,14 +225,9 @@ table ip6 filter {
 	}
 
 	chain services {
-{%- for rule in salt['ffho_netfilter.generate_service_rules'](services, acls, 6) %}
+{%- for rule in services[6] %}
 		{{ rule }}
 {%- endfor %}
-
-{#- Allow respondd queries on gateways #}
-{%- if 'batman_gw' in roles %}
-		ip6 saddr fe80::/64 ip6 daddr ff05::2:1001 udp dport 1001 counter accept comment "responnd"
-{%- endif %}
 	}
 
 	chain urpf {