From cc5895fe61f938189e229dffb7746fc93aac0f3b Mon Sep 17 00:00:00 2001 From: Adam Schultz Date: Sat, 16 Aug 2025 22:29:11 -0400 Subject: firewall: T7739: Default ruleset for firewall zones In large networks with many zones where simple allow/deny rules are not sufficient, zones become tedious to manage. Many use cases can be simplified by providing an ability to define a default ruleset for traffic from other zones. This change proposes adding the follwing syntax: set firewall zone default_firewall name set firewall zone default_firewall ipv6_name The proposed behavior is the following: local in: The default firewall ruleset for the local zone will be appended after all from configurations. local out: If a non-local zone does not have a from local ruleset but does have a default_firewall ruleset, the default_firewall ruleset will be appended using oifname forward: The default firewall ruleset for the zone will be appended after all from configurations To keep the behavior consistent with from ruleset configurations, a return is appended after the default_firewall ruleset. The proposed behavior differs slightly from the default_policy configuration for the local out chains. The default_policy applied in the out templates comes from the local zone, not the actual outbound zone. The proposed change does not amend this, but does make default_firewall logically consistent with the intent of the out rules. --- data/templates/firewall/nftables-zone.j2 | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'data') diff --git a/data/templates/firewall/nftables-zone.j2 b/data/templates/firewall/nftables-zone.j2 index 5a2b8912e..7b4128082 100644 --- a/data/templates/firewall/nftables-zone.j2 +++ b/data/templates/firewall/nftables-zone.j2 @@ -55,6 +55,10 @@ iifname { {{ zone[from_zone].member.vrf | quoted_join(",") }} } counter return {% endif %} {% endfor %} +{% endif %} +{% if zone_conf.default_firewall is vyos_defined and zone_conf.default_firewall[fw_name] is vyos_defined %} + counter jump NAME{{ suffix }}_{{ zone_conf.default_firewall[fw_name] }} + counter return {% endif %} {{ zone_conf | nft_default_rule('zone_' + zone_name, family) }} } @@ -71,6 +75,20 @@ oifname { {{ zone[from_zone].member.vrf | quoted_join(",") }} } counter return {% endif %} {% endfor %} +{% endif %} +{% if zone_conf.default_local is vyos_defined %} +{% for from_zone, from_conf in zone_conf.default_local.items() if from_conf[fw_name] is vyos_defined %} +{% if 'interface' in zone[from_zone].member %} + oifname { {{ zone[from_zone].member.interface | quoted_join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf[fw_name] }} + oifname { {{ zone[from_zone].member.interface | quoted_join(",") }} } counter return +{% endif %} +{% if 'vrf' in zone[from_zone].member %} +{% for vrf_name in zone[from_zone].member.vrf %} + oifname { "{{ zone[from_zone]['vrf_interfaces'][vrf_name] }}" } counter jump NAME{{ suffix }}_{{ from_conf[fw_name] }} + oifname { "{{ zone[from_zone]['vrf_interfaces'][vrf_name] }}" } counter return +{% endfor %} +{% endif %} +{% endfor %} {% endif %} {{ zone_conf | nft_default_rule('zone_' + zone_name, family) }} } @@ -103,6 +121,10 @@ {% endif %} {% endif %} {% endfor %} +{% endif %} +{% if zone_conf.default_firewall is vyos_defined and zone_conf.default_firewall[fw_name] is vyos_defined %} + counter jump NAME{{ suffix }}_{{ zone_conf.default_firewall[fw_name] }} + counter return {% endif %} {{ zone_conf | nft_default_rule('zone_' + zone_name, family) }} } -- cgit v1.2.3