From cc86483fdf7a6bd988f485c06402fd07368dd26e Mon Sep 17 00:00:00 2001 From: kumvijaya Date: Tue, 21 May 2024 16:41:14 +0530 Subject: T6357: create test repository to validate setup --- data/templates/firewall/nftables-bridge.j2 | 35 +++ data/templates/firewall/nftables-cgnat.j2 | 47 ++++ data/templates/firewall/nftables-defines.j2 | 123 +++++++++ data/templates/firewall/nftables-geoip-update.j2 | 33 +++ data/templates/firewall/nftables-nat.j2 | 46 ++++ data/templates/firewall/nftables-nat66.j2 | 40 +++ data/templates/firewall/nftables-offload.j2 | 9 + data/templates/firewall/nftables-policy.j2 | 71 +++++ data/templates/firewall/nftables-static-nat.j2 | 33 +++ data/templates/firewall/nftables-zone.j2 | 77 ++++++ data/templates/firewall/nftables.j2 | 327 +++++++++++++++++++++++ 11 files changed, 841 insertions(+) create mode 100644 data/templates/firewall/nftables-bridge.j2 create mode 100644 data/templates/firewall/nftables-cgnat.j2 create mode 100644 data/templates/firewall/nftables-defines.j2 create mode 100644 data/templates/firewall/nftables-geoip-update.j2 create mode 100644 data/templates/firewall/nftables-nat.j2 create mode 100644 data/templates/firewall/nftables-nat66.j2 create mode 100644 data/templates/firewall/nftables-offload.j2 create mode 100644 data/templates/firewall/nftables-policy.j2 create mode 100644 data/templates/firewall/nftables-static-nat.j2 create mode 100644 data/templates/firewall/nftables-zone.j2 create mode 100644 data/templates/firewall/nftables.j2 (limited to 'data/templates/firewall') diff --git a/data/templates/firewall/nftables-bridge.j2 b/data/templates/firewall/nftables-bridge.j2 new file mode 100644 index 0000000..dec027b --- /dev/null +++ b/data/templates/firewall/nftables-bridge.j2 @@ -0,0 +1,35 @@ +{% macro bridge(bridge) %} +{% set ns = namespace(sets=[]) %} +{% if bridge.forward is vyos_defined %} +{% for prior, conf in bridge.forward.items() %} + chain VYOS_FORWARD_{{ prior }} { + type filter hook forward priority {{ prior }}; policy accept; +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('FWD', prior, rule_id, 'bri') }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + ['FWD_' + prior + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} + {{ conf | nft_default_rule('FWD-filter', 'bri') }} + } +{% endfor %} +{% endif %} + +{% if bridge.name is vyos_defined %} +{% for name_text, conf in bridge.name.items() %} + chain NAME_{{ name_text }} { +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('NAM', name_text, rule_id, 'bri') }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + ['NAM_' + name_text + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} + {{ conf | nft_default_rule(name_text, 'bri') }} + } +{% endfor %} +{% endif %} +{% endmacro %} diff --git a/data/templates/firewall/nftables-cgnat.j2 b/data/templates/firewall/nftables-cgnat.j2 new file mode 100644 index 0000000..79a8e3d --- /dev/null +++ b/data/templates/firewall/nftables-cgnat.j2 @@ -0,0 +1,47 @@ +#!/usr/sbin/nft -f + +add table ip cgnat +flush table ip cgnat + +add map ip cgnat tcp_nat_map { type ipv4_addr: interval ipv4_addr . inet_service ; flags interval ;} +add map ip cgnat udp_nat_map { type ipv4_addr: interval ipv4_addr . inet_service ; flags interval ;} +add map ip cgnat icmp_nat_map { type ipv4_addr: interval ipv4_addr . inet_service ; flags interval ;} +add map ip cgnat other_nat_map { type ipv4_addr: interval ipv4_addr ; flags interval ;} +flush map ip cgnat tcp_nat_map +flush map ip cgnat udp_nat_map +flush map ip cgnat icmp_nat_map +flush map ip cgnat other_nat_map + +table ip cgnat { + map tcp_nat_map { + type ipv4_addr : interval ipv4_addr . inet_service + flags interval + elements = { {{ proto_map_elements }} } + } + + map udp_nat_map { + type ipv4_addr : interval ipv4_addr . inet_service + flags interval + elements = { {{ proto_map_elements }} } + } + + map icmp_nat_map { + type ipv4_addr : interval ipv4_addr . inet_service + flags interval + elements = { {{ proto_map_elements }} } + } + + map other_nat_map { + type ipv4_addr : interval ipv4_addr + flags interval + elements = { {{ other_map_elements }} } + } + + chain POSTROUTING { + type nat hook postrouting priority srcnat; policy accept; + ip protocol tcp counter snat ip to ip saddr map @tcp_nat_map + ip protocol udp counter snat ip to ip saddr map @udp_nat_map + ip protocol icmp counter snat ip to ip saddr map @icmp_nat_map + counter snat ip to ip saddr map @other_nat_map + } +} diff --git a/data/templates/firewall/nftables-defines.j2 b/data/templates/firewall/nftables-defines.j2 new file mode 100644 index 0000000..8a75ab2 --- /dev/null +++ b/data/templates/firewall/nftables-defines.j2 @@ -0,0 +1,123 @@ +{% macro groups(group, is_ipv6, is_l3) %} +{% if group is vyos_defined %} +{% set ip_type = 'ipv6_addr' if is_ipv6 else 'ipv4_addr' %} +{% if group.address_group is vyos_defined and not is_ipv6 and is_l3 %} +{% for group_name, group_conf in group.address_group.items() %} +{% set includes = group_conf.include if group_conf.include is vyos_defined else [] %} + set A_{{ group_name }} { + type {{ ip_type }} + flags interval + auto-merge +{% if group_conf.address is vyos_defined or includes %} + elements = { {{ group_conf.address | nft_nested_group(includes, group.address_group, 'address') | join(",") }} } +{% endif %} + } +{% endfor %} +{% endif %} +{% if group.ipv6_address_group is vyos_defined and is_ipv6 and is_l3 %} +{% for group_name, group_conf in group.ipv6_address_group.items() %} +{% set includes = group_conf.include if group_conf.include is vyos_defined else [] %} + set A6_{{ group_name }} { + type {{ ip_type }} + flags interval + auto-merge +{% if group_conf.address is vyos_defined or includes %} + elements = { {{ group_conf.address | nft_nested_group(includes, group.ipv6_address_group, 'address') | join(",") }} } +{% endif %} + } +{% endfor %} +{% endif %} +{% if group.domain_group is vyos_defined and is_l3 %} +{% for name, name_config in group.domain_group.items() %} + set D_{{ name }} { + type {{ ip_type }} + flags interval + } +{% endfor %} +{% endif %} +{% if group.mac_group is vyos_defined %} +{% for group_name, group_conf in group.mac_group.items() %} +{% set includes = group_conf.include if group_conf.include is vyos_defined else [] %} + set M_{{ group_name }} { + type ether_addr +{% if group_conf.mac_address is vyos_defined or includes %} + elements = { {{ group_conf.mac_address | nft_nested_group(includes, group.mac_group, 'mac_address') | join(",") }} } +{% endif %} + } +{% endfor %} +{% endif %} +{% if group.network_group is vyos_defined and not is_ipv6 and is_l3 %} +{% for group_name, group_conf in group.network_group.items() %} +{% set includes = group_conf.include if group_conf.include is vyos_defined else [] %} + set N_{{ group_name }} { + type {{ ip_type }} + flags interval + auto-merge +{% if group_conf.network is vyos_defined or includes %} + elements = { {{ group_conf.network | nft_nested_group(includes, group.network_group, 'network') | join(",") }} } +{% endif %} + } +{% endfor %} +{% endif %} +{% if group.ipv6_network_group is vyos_defined and is_ipv6 and is_l3 %} +{% for group_name, group_conf in group.ipv6_network_group.items() %} +{% set includes = group_conf.include if group_conf.include is vyos_defined else [] %} + set N6_{{ group_name }} { + type {{ ip_type }} + flags interval + auto-merge +{% if group_conf.network is vyos_defined or includes %} + elements = { {{ group_conf.network | nft_nested_group(includes, group.ipv6_network_group, 'network') | join(",") }} } +{% endif %} + } +{% endfor %} +{% endif %} +{% if group.port_group is vyos_defined and is_l3 %} +{% for group_name, group_conf in group.port_group.items() %} +{% set includes = group_conf.include if group_conf.include is vyos_defined else [] %} + set P_{{ group_name }} { + type inet_service + flags interval + auto-merge +{% if group_conf.port is vyos_defined or includes %} + elements = { {{ group_conf.port | nft_nested_group(includes, group.port_group, 'port') | join(",") }} } +{% endif %} + } +{% endfor %} +{% endif %} +{% if group.interface_group is vyos_defined %} +{% for group_name, group_conf in group.interface_group.items() %} +{% set includes = group_conf.include if group_conf.include is vyos_defined else [] %} + set I_{{ group_name }} { + type ifname + flags interval + auto-merge +{% if group_conf.interface is vyos_defined or includes %} + elements = { {{ group_conf.interface | nft_nested_group(includes, group.interface_group, 'interface') | join(",") }} } +{% endif %} + } +{% endfor %} +{% endif %} + +{% if group.dynamic_group is vyos_defined %} +{% if group.dynamic_group.address_group is vyos_defined and not is_ipv6 and is_l3 %} +{% for group_name, group_conf in group.dynamic_group.address_group.items() %} + set DA_{{ group_name }} { + type {{ ip_type }} + flags dynamic, timeout + } +{% endfor %} +{% endif %} + +{% if group.dynamic_group.ipv6_address_group is vyos_defined and is_ipv6 and is_l3 %} +{% for group_name, group_conf in group.dynamic_group.ipv6_address_group.items() %} + set DA6_{{ group_name }} { + type {{ ip_type }} + flags dynamic, timeout + } +{% endfor %} +{% endif %} +{% endif %} + +{% endif %} +{% endmacro %} diff --git a/data/templates/firewall/nftables-geoip-update.j2 b/data/templates/firewall/nftables-geoip-update.j2 new file mode 100644 index 0000000..832ccc3 --- /dev/null +++ b/data/templates/firewall/nftables-geoip-update.j2 @@ -0,0 +1,33 @@ +#!/usr/sbin/nft -f + +{% if ipv4_sets is vyos_defined %} +{% for setname, ip_list in ipv4_sets.items() %} +flush set ip vyos_filter {{ setname }} +{% endfor %} + +table ip vyos_filter { +{% for setname, ip_list in ipv4_sets.items() %} + set {{ setname }} { + type ipv4_addr + flags interval + elements = { {{ ','.join(ip_list) }} } + } +{% endfor %} +} +{% endif %} + +{% if ipv6_sets is vyos_defined %} +{% for setname, ip_list in ipv6_sets.items() %} +flush set ip6 vyos_filter {{ setname }} +{% endfor %} + +table ip6 vyos_filter { +{% for setname, ip_list in ipv6_sets.items() %} + set {{ setname }} { + type ipv6_addr + flags interval + elements = { {{ ','.join(ip_list) }} } + } +{% endfor %} +} +{% endif %} diff --git a/data/templates/firewall/nftables-nat.j2 b/data/templates/firewall/nftables-nat.j2 new file mode 100644 index 0000000..4254f6a --- /dev/null +++ b/data/templates/firewall/nftables-nat.j2 @@ -0,0 +1,46 @@ +#!/usr/sbin/nft -f + +{% import 'firewall/nftables-defines.j2' as group_tmpl %} + +{% if first_install is not vyos_defined %} +delete table ip vyos_nat +{% endif %} +{% if deleted is not vyos_defined %} +table ip vyos_nat { + # + # Destination NAT rules build up here + # + chain PREROUTING { + type nat hook prerouting priority -100; policy accept; + counter jump VYOS_PRE_DNAT_HOOK +{% if destination.rule is vyos_defined %} +{% for rule, config in destination.rule.items() if config.disable is not vyos_defined %} + {{ config | nat_rule(rule, 'destination') }} +{% endfor %} +{% endif %} + } + + # + # Source NAT rules build up here + # + chain POSTROUTING { + type nat hook postrouting priority 100; policy accept; + counter jump VYOS_PRE_SNAT_HOOK +{% if source.rule is vyos_defined %} +{% for rule, config in source.rule.items() if config.disable is not vyos_defined %} + {{ config | nat_rule(rule, 'source') }} +{% endfor %} +{% endif %} + } + + chain VYOS_PRE_DNAT_HOOK { + return + } + + chain VYOS_PRE_SNAT_HOOK { + return + } + +{{ group_tmpl.groups(firewall_group, False, True) }} +} +{% endif %} diff --git a/data/templates/firewall/nftables-nat66.j2 b/data/templates/firewall/nftables-nat66.j2 new file mode 100644 index 0000000..67eb2c1 --- /dev/null +++ b/data/templates/firewall/nftables-nat66.j2 @@ -0,0 +1,40 @@ +#!/usr/sbin/nft -f + +{% if first_install is not vyos_defined %} +delete table ip6 vyos_nat +{% endif %} +table ip6 vyos_nat { + # + # Destination NAT66 rules build up here + # + chain PREROUTING { + type nat hook prerouting priority -100; policy accept; + counter jump VYOS_DNPT_HOOK +{% if destination.rule is vyos_defined %} +{% for rule, config in destination.rule.items() if config.disable is not vyos_defined %} + {{ config | nat_rule(rule, 'destination', ipv6=True) }} +{% endfor %} +{% endif %} + } + + # + # Source NAT66 rules build up here + # + chain POSTROUTING { + type nat hook postrouting priority 100; policy accept; + counter jump VYOS_SNPT_HOOK +{% if source.rule is vyos_defined %} +{% for rule, config in source.rule.items() if config.disable is not vyos_defined %} + {{ config | nat_rule(rule, 'source', ipv6=True) }} +{% endfor %} +{% endif %} + } + + chain VYOS_DNPT_HOOK { + return + } + + chain VYOS_SNPT_HOOK { + return + } +} diff --git a/data/templates/firewall/nftables-offload.j2 b/data/templates/firewall/nftables-offload.j2 new file mode 100644 index 0000000..a893e05 --- /dev/null +++ b/data/templates/firewall/nftables-offload.j2 @@ -0,0 +1,9 @@ +{% macro flowtable(name, config) %} + flowtable VYOS_FLOWTABLE_{{ name }} { + hook ingress priority 0; devices = { {{ config.interface | join(', ') }} }; +{% if config.offload is vyos_defined('hardware') %} + flags offload; +{% endif %} + counter + } +{% endmacro %} diff --git a/data/templates/firewall/nftables-policy.j2 b/data/templates/firewall/nftables-policy.j2 new file mode 100644 index 0000000..9e28899 --- /dev/null +++ b/data/templates/firewall/nftables-policy.j2 @@ -0,0 +1,71 @@ +#!/usr/sbin/nft -f + +{% import 'firewall/nftables-defines.j2' as group_tmpl %} + +{% if first_install is not vyos_defined %} +delete table ip vyos_mangle +delete table ip6 vyos_mangle +{% endif %} +table ip vyos_mangle { + chain VYOS_PBR_PREROUTING { + type filter hook prerouting priority -150; policy accept; +{% if route is vyos_defined %} +{% for route_text, conf in route.items() if conf.interface is vyos_defined %} + iifname { {{ conf.interface | join(",") }} } counter jump VYOS_PBR_UD_{{ route_text }} +{% endfor %} +{% endif %} + } + + chain VYOS_PBR_POSTROUTING { + type filter hook postrouting priority -150; policy accept; + } + +{% if route is vyos_defined %} +{% for route_text, conf in route.items() %} + chain VYOS_PBR_UD_{{ route_text }} { +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('route', route_text, rule_id, 'ip') }} +{% endfor %} +{% endif %} +{% if conf.default_log is vyos_defined %} + counter log prefix "[ipv4-{{ (route_text)[:19] }}-default]" +{% endif %} + } +{% endfor %} +{% endif %} + +{{ group_tmpl.groups(firewall_group, False, True) }} +} + +table ip6 vyos_mangle { + chain VYOS_PBR6_PREROUTING { + type filter hook prerouting priority -150; policy accept; +{% if route6 is vyos_defined %} +{% for route_text, conf in route6.items() if conf.interface is vyos_defined %} + iifname { {{ ",".join(conf.interface) }} } counter jump VYOS_PBR6_UD_{{ route_text }} +{% endfor %} +{% endif %} + } + + chain VYOS_PBR6_POSTROUTING { + type filter hook postrouting priority -150; policy accept; + } + +{% if route6 is vyos_defined %} +{% for route_text, conf in route6.items() %} + chain VYOS_PBR6_UD_{{ route_text }} { +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('route6', route_text, rule_id, 'ip6') }} +{% endfor %} +{% endif %} +{% if conf.default_log is vyos_defined %} + counter log prefix "[ipv6-{{ (route_text)[:19] }}-default]" +{% endif %} + } +{% endfor %} +{% endif %} + +{{ group_tmpl.groups(firewall_group, True, True) }} +} diff --git a/data/templates/firewall/nftables-static-nat.j2 b/data/templates/firewall/nftables-static-nat.j2 new file mode 100644 index 0000000..e5e3da8 --- /dev/null +++ b/data/templates/firewall/nftables-static-nat.j2 @@ -0,0 +1,33 @@ +#!/usr/sbin/nft -f + +{% if first_install is not vyos_defined %} +delete table ip vyos_static_nat +{% endif %} +{% if deleted is not vyos_defined %} +table ip vyos_static_nat { + # + # Destination NAT rules build up here + # + + chain PREROUTING { + type nat hook prerouting priority -100; policy accept; +{% if static.rule is vyos_defined %} +{% for rule, config in static.rule.items() if config.disable is not vyos_defined %} + {{ config | nat_static_rule(rule, 'destination') }} +{% endfor %} +{% endif %} + } + + # + # Source NAT rules build up here + # + chain POSTROUTING { + type nat hook postrouting priority 100; policy accept; +{% if static.rule is vyos_defined %} +{% for rule, config in static.rule.items() if config.disable is not vyos_defined %} + {{ config | nat_static_rule(rule, 'source') }} +{% endfor %} +{% endif %} + } +} +{% endif %} diff --git a/data/templates/firewall/nftables-zone.j2 b/data/templates/firewall/nftables-zone.j2 new file mode 100644 index 0000000..e787250 --- /dev/null +++ b/data/templates/firewall/nftables-zone.j2 @@ -0,0 +1,77 @@ +{% macro zone_chains(zone, ipv6=False, state_policy=False) %} +{% set fw_name = 'ipv6_name' if ipv6 else 'name' %} +{% set suffix = '6' if ipv6 else '' %} + chain VYOS_ZONE_FORWARD { + type filter hook forward priority 1; policy accept; +{% if state_policy %} + jump VYOS_STATE_POLICY{{ suffix }} +{% endif %} +{% for zone_name, zone_conf in zone.items() %} +{% if 'local_zone' not in zone_conf %} + oifname { {{ zone_conf.interface | join(',') }} } counter jump VZONE_{{ zone_name }} +{% endif %} +{% endfor %} + } + chain VYOS_ZONE_LOCAL { + type filter hook input priority 1; policy accept; +{% if state_policy %} + jump VYOS_STATE_POLICY{{ suffix }} +{% endif %} +{% for zone_name, zone_conf in zone.items() %} +{% if 'local_zone' in zone_conf %} + counter jump VZONE_{{ zone_name }}_IN +{% endif %} +{% endfor %} + } + chain VYOS_ZONE_OUTPUT { + type filter hook output priority 1; policy accept; +{% if state_policy %} + jump VYOS_STATE_POLICY{{ suffix }} +{% endif %} +{% for zone_name, zone_conf in zone.items() %} +{% if 'local_zone' in zone_conf %} + counter jump VZONE_{{ zone_name }}_OUT +{% endif %} +{% endfor %} + } +{% for zone_name, zone_conf in zone.items() %} +{% if zone_conf.local_zone is vyos_defined %} + chain VZONE_{{ zone_name }}_IN { + iifname lo counter return +{% if zone_conf.from is vyos_defined %} +{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall[fw_name] is vyos_defined %} + iifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }} + iifname { {{ zone[from_zone].interface | join(",") }} } counter return +{% endfor %} +{% endif %} + {{ zone_conf | nft_default_rule('zone_' + zone_name, family) }} + } + chain VZONE_{{ zone_name }}_OUT { + oifname lo counter return +{% if zone_conf.from_local is vyos_defined %} +{% for from_zone, from_conf in zone_conf.from_local.items() if from_conf.firewall[fw_name] is vyos_defined %} + oifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }} + oifname { {{ zone[from_zone].interface | join(",") }} } counter return +{% endfor %} +{% endif %} + {{ zone_conf | nft_default_rule('zone_' + zone_name, family) }} + } +{% else %} + chain VZONE_{{ zone_name }} { + iifname { {{ zone_conf.interface | join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6) }} +{% if zone_conf.intra_zone_filtering is vyos_defined %} + iifname { {{ zone_conf.interface | join(",") }} } counter return +{% endif %} +{% if zone_conf.from is vyos_defined %} +{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall[fw_name] is vyos_defined %} +{% if zone[from_zone].local_zone is not defined %} + iifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }} + iifname { {{ zone[from_zone].interface | join(",") }} } counter return +{% endif %} +{% endfor %} +{% endif %} + {{ zone_conf | nft_default_rule('zone_' + zone_name, family) }} + } +{% endif %} +{% endfor %} +{% endmacro %} \ No newline at end of file diff --git a/data/templates/firewall/nftables.j2 b/data/templates/firewall/nftables.j2 new file mode 100644 index 0000000..833df3a --- /dev/null +++ b/data/templates/firewall/nftables.j2 @@ -0,0 +1,327 @@ +#!/usr/sbin/nft -f + +{% import 'firewall/nftables-defines.j2' as group_tmpl %} +{% import 'firewall/nftables-bridge.j2' as bridge_tmpl %} +{% import 'firewall/nftables-offload.j2' as offload_tmpl %} +{% import 'firewall/nftables-zone.j2' as zone_tmpl %} + +flush chain raw vyos_global_rpfilter +flush chain ip6 raw vyos_global_rpfilter + +table raw { + chain vyos_global_rpfilter { +{% if global_options.source_validation is vyos_defined('loose') %} + fib saddr oif 0 counter drop +{% elif global_options.source_validation is vyos_defined('strict') %} + fib saddr . iif oif 0 counter drop +{% endif %} + return + } +} + +table ip6 raw { + chain vyos_global_rpfilter { +{% if global_options.ipv6_source_validation is vyos_defined('loose') %} + fib saddr oif 0 counter drop +{% elif global_options.ipv6_source_validation is vyos_defined('strict') %} + fib saddr . iif oif 0 counter drop +{% endif %} + return + } +} + +{% if first_install is not vyos_defined %} +delete table ip vyos_filter +{% endif %} +table ip vyos_filter { +{% if ipv4 is vyos_defined %} +{% if flowtable is vyos_defined %} +{% for name, flowtable_conf in flowtable.items() %} +{{ offload_tmpl.flowtable(name, flowtable_conf) }} +{% endfor %} +{% endif %} + +{% set ns = namespace(sets=[]) %} +{% if ipv4.forward is vyos_defined %} +{% for prior, conf in ipv4.forward.items() %} + chain VYOS_FORWARD_{{ prior }} { + type filter hook forward priority {{ prior }}; policy accept; +{% if global_options.state_policy is vyos_defined %} + jump VYOS_STATE_POLICY +{% endif %} +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('FWD', prior, rule_id) }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + ['FWD_' + prior + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} + {{ conf | nft_default_rule('FWD-filter', 'ipv4') }} + } +{% endfor %} +{% endif %} + +{% if ipv4.input is vyos_defined %} +{% for prior, conf in ipv4.input.items() %} + chain VYOS_INPUT_{{ prior }} { + type filter hook input priority {{ prior }}; policy accept; +{% if global_options.state_policy is vyos_defined %} + jump VYOS_STATE_POLICY +{% endif %} +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('INP',prior, rule_id) }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + ['INP_' + prior + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} + {{ conf | nft_default_rule('INP-filter', 'ipv4') }} + } +{% endfor %} +{% endif %} + +{% if ipv4.output is vyos_defined %} +{% for prior, conf in ipv4.output.items() %} + chain VYOS_OUTPUT_{{ prior }} { + type filter hook output priority {{ prior }}; policy accept; +{% if global_options.state_policy is vyos_defined %} + jump VYOS_STATE_POLICY +{% endif %} +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('OUT', prior, rule_id) }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + ['OUT_' + prior + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} + {{ conf | nft_default_rule('OUT-filter', 'ipv4') }} + } +{% endfor %} +{% endif %} + chain VYOS_FRAG_MARK { + type filter hook prerouting priority -450; policy accept; + ip frag-off & 0x3fff != 0 meta mark set 0xffff1 return + } +{% if ipv4.prerouting is vyos_defined %} +{% for prior, conf in ipv4.prerouting.items() %} + chain VYOS_PREROUTING_{{ prior }} { + type filter hook prerouting priority {{ prior }}; policy accept; +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('PRE', prior, rule_id) }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + ['PRE_' + prior + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} + {{ conf | nft_default_rule('PRE-filter', 'ipv4') }} + } +{% endfor %} +{% endif %} + +{% if ipv4.name is vyos_defined %} +{% for name_text, conf in ipv4.name.items() %} + chain NAME_{{ name_text }} { +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('NAM', name_text, rule_id) }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + ['NAM_' + name_text + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} + {{ conf | nft_default_rule(name_text, 'ipv4') }} + } +{% endfor %} +{% endif %} + +{% for set_name in ns.sets %} + set RECENT_{{ set_name }} { + type ipv4_addr + size 65535 + flags dynamic + } +{% endfor %} +{% for set_name in ip_fqdn %} + set FQDN_{{ set_name }} { + type ipv4_addr + flags interval + } +{% endfor %} +{% if geoip_updated.name is vyos_defined %} +{% for setname in geoip_updated.name %} + set {{ setname }} { + type ipv4_addr + flags interval + } +{% endfor %} +{% endif %} +{% endif %} +{{ group_tmpl.groups(group, False, True) }} + +{% if zone is vyos_defined %} +{{ zone_tmpl.zone_chains(zone, False, global_options.state_policy is vyos_defined) }} +{% endif %} +{% if global_options.state_policy is vyos_defined %} + chain VYOS_STATE_POLICY { +{% if global_options.state_policy.established is vyos_defined %} + {{ global_options.state_policy.established | nft_state_policy('established') }} +{% endif %} +{% if global_options.state_policy.invalid is vyos_defined %} + {{ global_options.state_policy.invalid | nft_state_policy('invalid') }} +{% endif %} +{% if global_options.state_policy.related is vyos_defined %} + {{ global_options.state_policy.related | nft_state_policy('related') }} +{% endif %} + return + } +{% endif %} +} + +{% if first_install is not vyos_defined %} +delete table ip6 vyos_filter +{% endif %} +table ip6 vyos_filter { +{% if ipv6 is vyos_defined %} +{% if flowtable is vyos_defined %} +{% for name, flowtable_conf in flowtable.items() %} +{{ offload_tmpl.flowtable(name, flowtable_conf) }} +{% endfor %} +{% endif %} + +{% set ns = namespace(sets=[]) %} +{% if ipv6.forward is vyos_defined %} +{% for prior, conf in ipv6.forward.items() %} + chain VYOS_IPV6_FORWARD_{{ prior }} { + type filter hook forward priority {{ prior }}; policy accept; +{% if global_options.state_policy is vyos_defined %} + jump VYOS_STATE_POLICY6 +{% endif %} +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('FWD', prior, rule_id ,'ip6') }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + ['FWD_' + prior + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} + {{ conf | nft_default_rule('FWD-filter', 'ipv6') }} + } +{% endfor %} +{% endif %} + +{% if ipv6.input is vyos_defined %} +{% for prior, conf in ipv6.input.items() %} + chain VYOS_IPV6_INPUT_{{ prior }} { + type filter hook input priority {{ prior }}; policy accept; +{% if global_options.state_policy is vyos_defined %} + jump VYOS_STATE_POLICY6 +{% endif %} +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('INP', prior, rule_id ,'ip6') }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + ['INP_' + prior + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} + {{ conf | nft_default_rule('INP-filter', 'ipv6') }} + } +{% endfor %} +{% endif %} + +{% if ipv6.output is vyos_defined %} +{% for prior, conf in ipv6.output.items() %} + chain VYOS_IPV6_OUTPUT_{{ prior }} { + type filter hook output priority {{ prior }}; policy accept; +{% if global_options.state_policy is vyos_defined %} + jump VYOS_STATE_POLICY6 +{% endif %} +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('OUT', prior, rule_id ,'ip6') }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + ['OUT_ ' + prior + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} + {{ conf | nft_default_rule('OUT-filter', 'ipv6') }} + } +{% endfor %} +{% endif %} + + chain VYOS_FRAG6_MARK { + type filter hook prerouting priority -450; policy accept; + exthdr frag exists meta mark set 0xffff1 return + } + +{% if ipv6.name is vyos_defined %} +{% for name_text, conf in ipv6.name.items() %} + chain NAME6_{{ name_text }} { +{% if conf.rule is vyos_defined %} +{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} + {{ rule_conf | nft_rule('NAM', name_text, rule_id, 'ip6') }} +{% if rule_conf.recent is vyos_defined %} +{% set ns.sets = ns.sets + ['NAM_' + name_text + '_' + rule_id] %} +{% endif %} +{% endfor %} +{% endif %} + {{ conf | nft_default_rule(name_text, 'ipv6') }} + } +{% endfor %} +{% endif %} + +{% for set_name in ns.sets %} + set RECENT6_{{ set_name }} { + type ipv6_addr + size 65535 + flags dynamic + } +{% endfor %} +{% for set_name in ip6_fqdn %} + set FQDN_{{ set_name }} { + type ipv6_addr + flags interval + } +{% endfor %} +{% if geoip_updated.ipv6_name is vyos_defined %} +{% for setname in geoip_updated.ipv6_name %} + set {{ setname }} { + type ipv6_addr + flags interval + } +{% endfor %} +{% endif %} +{% endif %} +{{ group_tmpl.groups(group, True, True) }} +{% if zone is vyos_defined %} +{{ zone_tmpl.zone_chains(zone, True, global_options.state_policy is vyos_defined) }} +{% endif %} +{% if global_options.state_policy is vyos_defined %} + chain VYOS_STATE_POLICY6 { +{% if global_options.state_policy.established is vyos_defined %} + {{ global_options.state_policy.established | nft_state_policy('established') }} +{% endif %} +{% if global_options.state_policy.invalid is vyos_defined %} + {{ global_options.state_policy.invalid | nft_state_policy('invalid') }} +{% endif %} +{% if global_options.state_policy.related is vyos_defined %} + {{ global_options.state_policy.related | nft_state_policy('related') }} +{% endif %} + return + } +{% endif %} +} + +## Bridge Firewall +{% if first_install is not vyos_defined %} +delete table bridge vyos_filter +{% endif %} +table bridge vyos_filter { +{{ bridge_tmpl.bridge(bridge) }} +{{ group_tmpl.groups(group, False, False) }} + +} -- cgit v1.2.3