diff options
Diffstat (limited to 'data/templates')
20 files changed, 400 insertions, 337 deletions
diff --git a/data/templates/firewall/nftables-geoip-update.j2 b/data/templates/firewall/nftables-geoip-update.j2 index f9e61a274..832ccc3e9 100644 --- a/data/templates/firewall/nftables-geoip-update.j2 +++ b/data/templates/firewall/nftables-geoip-update.j2 @@ -2,10 +2,10 @@ {% if ipv4_sets is vyos_defined %} {% for setname, ip_list in ipv4_sets.items() %} -flush set ip filter {{ setname }} +flush set ip vyos_filter {{ setname }} {% endfor %} -table ip filter { +table ip vyos_filter { {% for setname, ip_list in ipv4_sets.items() %} set {{ setname }} { type ipv4_addr @@ -18,10 +18,10 @@ table ip filter { {% if ipv6_sets is vyos_defined %} {% for setname, ip_list in ipv6_sets.items() %} -flush set ip6 filter {{ setname }} +flush set ip6 vyos_filter {{ setname }} {% endfor %} -table ip6 filter { +table ip6 vyos_filter { {% for setname, ip_list in ipv6_sets.items() %} set {{ setname }} { type ipv6_addr diff --git a/data/templates/firewall/nftables-nat66.j2 b/data/templates/firewall/nftables-nat66.j2 index 2fe04b4ff..28714c7a7 100644 --- a/data/templates/firewall/nftables-nat66.j2 +++ b/data/templates/firewall/nftables-nat66.j2 @@ -7,6 +7,17 @@ {% set src_prefix = 'ip6 saddr ' ~ config.source.prefix.replace('!','!= ') if config.source.prefix is vyos_defined %} {% set source_address = 'ip6 saddr ' ~ config.source.address.replace('!','!= ') if config.source.address is vyos_defined %} {% set dest_address = 'ip6 daddr ' ~ config.destination.address.replace('!','!= ') if config.destination.address is vyos_defined %} +{# Port #} +{% if config.source.port is vyos_defined and config.source.port.startswith('!') %} +{% set src_port = 'sport != { ' ~ config.source.port.replace('!','') ~ ' }' %} +{% else %} +{% set src_port = 'sport { ' ~ config.source.port ~ ' }' if config.source.port is vyos_defined %} +{% endif %} +{% if config.destination.port is vyos_defined and config.destination.port.startswith('!') %} +{% set dst_port = 'dport != { ' ~ config.destination.port.replace('!','') ~ ' }' %} +{% else %} +{% set dst_port = 'dport { ' ~ config.destination.port ~ ' }' if config.destination.port is vyos_defined %} +{% endif %} {% if chain is vyos_defined('PREROUTING') %} {% set comment = 'DST-NAT66-' ~ rule %} {% set base_log = '[NAT66-DST-' ~ rule %} @@ -36,6 +47,14 @@ {% endif %} {% set interface = ' oifname "' ~ config.outbound_interface ~ '"' if config.outbound_interface is vyos_defined else '' %} {% endif %} +{% set trns_port = ':' ~ config.translation.port if config.translation.port is vyos_defined %} +{# protocol has a default value thus it is always present #} +{% if config.protocol is vyos_defined('tcp_udp') %} +{% set protocol = 'tcp' %} +{% set comment = comment ~ ' tcp_udp' %} +{% else %} +{% set protocol = config.protocol %} +{% endif %} {% if config.log is vyos_defined %} {% if config.translation.address is vyos_defined('masquerade') %} {% set log = base_log ~ '-MASQ]' %} @@ -43,6 +62,11 @@ {% set log = base_log ~ ']' %} {% endif %} {% endif %} +{% if config.exclude is vyos_defined %} +{# rule has been marked as 'exclude' thus we simply return here #} +{% set trns_addr = 'return' %} +{% set trns_port = '' %} +{% endif %} {% set output = 'add rule ip6 nat ' ~ chain ~ interface %} {# Count packets #} {% set output = output ~ ' counter' %} @@ -54,12 +78,18 @@ {% if src_prefix is vyos_defined %} {% set output = output ~ ' ' ~ src_prefix %} {% endif %} +{% if dst_port is vyos_defined %} +{% set output = output ~ ' ' ~ protocol ~ ' ' ~ dst_port %} +{% endif %} {% if dst_prefix is vyos_defined %} {% set output = output ~ ' ' ~ dst_prefix %} {% endif %} {% if source_address is vyos_defined %} {% set output = output ~ ' ' ~ source_address %} {% endif %} +{% if src_port is vyos_defined %} +{% set output = output ~ ' ' ~ protocol ~ ' ' ~ src_port %} +{% endif %} {% if dest_address is vyos_defined %} {% set output = output ~ ' ' ~ dest_address %} {% endif %} @@ -70,11 +100,22 @@ {% if trns_address is vyos_defined %} {% set output = output ~ ' ' ~ trns_address %} {% endif %} +{% if trns_port is vyos_defined %} +{# Do not add a whitespace here, translation port must be directly added after IP address #} +{# e.g. 2001:db8::1:3389 #} +{% set output = output ~ trns_port %} +{% endif %} {% if comment is vyos_defined %} {% set output = output ~ ' comment "' ~ comment ~ '"' %} {% endif %} {{ log_output if log_output is vyos_defined }} {{ output }} +{# Special handling if protocol is tcp_udp, we must repeat the entire rule with udp as protocol #} +{% if config.protocol is vyos_defined('tcp_udp') %} +{# Beware of trailing whitespace, without it the comment tcp_udp will be changed to udp_udp #} +{{ log_output | replace('tcp ', 'udp ') if log_output is vyos_defined }} +{{ output | replace('tcp ', 'udp ') }} +{% endif %} {% endmacro %} # Start with clean NAT table diff --git a/data/templates/firewall/nftables-policy.j2 b/data/templates/firewall/nftables-policy.j2 index 281525407..40118930b 100644 --- a/data/templates/firewall/nftables-policy.j2 +++ b/data/templates/firewall/nftables-policy.j2 @@ -25,7 +25,6 @@ table ip mangle { {{ rule_conf | nft_rule(route_text, rule_id, 'ip') }} {% endfor %} {% endif %} - {{ conf | nft_default_rule(route_text) }} } {% endfor %} {% endif %} @@ -50,7 +49,6 @@ table ip6 mangle { {{ rule_conf | nft_rule(route_text, rule_id, 'ip6') }} {% endfor %} {% endif %} - {{ conf | nft_default_rule(route_text) }} } {% endfor %} {% endif %} diff --git a/data/templates/firewall/nftables-static-nat.j2 b/data/templates/firewall/nftables-static-nat.j2 new file mode 100644 index 000000000..d3c43858f --- /dev/null +++ b/data/templates/firewall/nftables-static-nat.j2 @@ -0,0 +1,115 @@ +#!/usr/sbin/nft -f + +{% macro nat_rule(rule, config, chain) %} +{% set comment = '' %} +{% set base_log = '' %} + +{% if chain is vyos_defined('PREROUTING') %} +{% set comment = 'STATIC-NAT-' ~ rule %} +{% set base_log = '[NAT-DST-' ~ rule %} +{% set interface = ' iifname "' ~ config.inbound_interface ~ '"' if config.inbound_interface is vyos_defined and config.inbound_interface is not vyos_defined('any') else '' %} +{% if config.translation.address is vyos_defined %} +{# support 1:1 network translation #} +{% if config.translation.address | is_ip_network %} +{% set trns_addr = 'dnat ip prefix to ip daddr map { ' ~ config.destination.address ~ ' : ' ~ config.translation.address ~ ' }' %} +{# we can now clear out the dst_addr part as it's already covered in aboves map #} +{% else %} +{% set dst_addr = 'ip daddr ' ~ config.destination.address if config.destination.address is vyos_defined %} +{% set trns_addr = 'dnat to ' ~ config.translation.address %} +{% endif %} +{% endif %} +{% elif chain is vyos_defined('POSTROUTING') %} +{% set comment = 'STATIC-NAT-' ~ rule %} +{% set base_log = '[NAT-SRC-' ~ rule %} +{% set interface = ' oifname "' ~ config.inbound_interface ~ '"' if config.inbound_interface is vyos_defined and config.inbound_interface is not vyos_defined('any') else '' %} +{% if config.translation.address is vyos_defined %} +{# support 1:1 network translation #} +{% if config.translation.address | is_ip_network %} +{% set trns_addr = 'snat ip prefix to ip saddr map { ' ~ config.translation.address ~ ' : ' ~ config.destination.address ~ ' }' %} +{# we can now clear out the src_addr part as it's already covered in aboves map #} +{% else %} +{% set src_addr = 'ip saddr ' ~ config.translation.address if config.translation.address is vyos_defined %} +{% set trns_addr = 'snat to ' ~ config.destination.address %} +{% endif %} +{% endif %} +{% endif %} + +{% if config.exclude is vyos_defined %} +{# rule has been marked as 'exclude' thus we simply return here #} +{% set trns_addr = 'return' %} +{% set trns_port = '' %} +{% endif %} + +{% if config.translation.options is vyos_defined %} +{% if config.translation.options.address_mapping is vyos_defined('persistent') %} +{% set trns_opts_addr = 'persistent' %} +{% endif %} +{% if config.translation.options.port_mapping is vyos_defined('random') %} +{% set trns_opts_port = 'random' %} +{% elif config.translation.options.port_mapping is vyos_defined('fully-random') %} +{% set trns_opts_port = 'fully-random' %} +{% endif %} +{% endif %} + +{% if trns_opts_addr is vyos_defined and trns_opts_port is vyos_defined %} +{% set trns_opts = trns_opts_addr ~ ',' ~ trns_opts_port %} +{% elif trns_opts_addr is vyos_defined %} +{% set trns_opts = trns_opts_addr %} +{% elif trns_opts_port is vyos_defined %} +{% set trns_opts = trns_opts_port %} +{% endif %} + +{% set output = 'add rule ip vyos_static_nat ' ~ chain ~ interface %} + +{% if dst_addr is vyos_defined %} +{% set output = output ~ ' ' ~ dst_addr %} +{% endif %} +{% if src_addr is vyos_defined %} +{% set output = output ~ ' ' ~ src_addr %} +{% endif %} + +{# Count packets #} +{% set output = output ~ ' counter' %} +{# Special handling of log option, we must repeat the entire rule before the #} +{# NAT translation options are added, this is essential #} +{% if log is vyos_defined %} +{% set log_output = output ~ ' log prefix "' ~ log ~ '" comment "' ~ comment ~ '"' %} +{% endif %} +{% if trns_addr is vyos_defined %} +{% set output = output ~ ' ' ~ trns_addr %} +{% endif %} + +{% if trns_opts is vyos_defined %} +{% set output = output ~ ' ' ~ trns_opts %} +{% endif %} +{% if comment is vyos_defined %} +{% set output = output ~ ' comment "' ~ comment ~ '"' %} +{% endif %} +{{ log_output if log_output is vyos_defined }} +{{ output }} +{% endmacro %} + +# Start with clean STATIC NAT chains +flush chain ip vyos_static_nat PREROUTING +flush chain ip vyos_static_nat POSTROUTING + +{# NAT if enabled - add targets to nftables #} + +# +# Destination NAT rules build up here +# +add rule ip vyos_static_nat PREROUTING counter jump VYOS_PRE_DNAT_HOOK +{% if static.rule is vyos_defined %} +{% for rule, config in static.rule.items() if config.disable is not vyos_defined %} +{{ nat_rule(rule, config, 'PREROUTING') }} +{% endfor %} +{% endif %} +# +# Source NAT rules build up here +# +add rule ip vyos_static_nat POSTROUTING counter jump VYOS_PRE_SNAT_HOOK +{% if static.rule is vyos_defined %} +{% for rule, config in static.rule.items() if config.disable is not vyos_defined %} +{{ nat_rule(rule, config, 'POSTROUTING') }} +{% endfor %} +{% endif %} diff --git a/data/templates/firewall/nftables-zone.j2 b/data/templates/firewall/nftables-zone.j2 new file mode 100644 index 000000000..919881e19 --- /dev/null +++ b/data/templates/firewall/nftables-zone.j2 @@ -0,0 +1,72 @@ + +{% macro zone_chains(zone, state_policy=False, ipv6=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 +{% 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 %} + {{ zone_conf | nft_default_rule('zone_' + zone_name) }} + } + chain VZONE_{{ zone_name }}_OUT { + oifname lo counter return +{% 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 %} + {{ zone_conf | nft_default_rule('zone_' + zone_name) }} + } +{% 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 %} +{% 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 %} + {{ zone_conf | nft_default_rule('zone_' + zone_name) }} + } +{% endif %} +{% endfor %} +{% endmacro %} diff --git a/data/templates/firewall/nftables.j2 b/data/templates/firewall/nftables.j2 index b91fed615..c0780dad5 100644 --- a/data/templates/firewall/nftables.j2 +++ b/data/templates/firewall/nftables.j2 @@ -1,25 +1,48 @@ #!/usr/sbin/nft -f {% import 'firewall/nftables-defines.j2' as group_tmpl %} +{% import 'firewall/nftables-zone.j2' as zone_tmpl %} -{% if cleanup_commands is vyos_defined %} -{% for command in cleanup_commands %} -{{ command }} -{% endfor %} +{% if first_install is not vyos_defined %} +delete table ip vyos_filter {% endif %} - -table ip filter { -{% if first_install is vyos_defined %} +table ip vyos_filter { chain VYOS_FW_FORWARD { type filter hook forward priority 0; policy accept; +{% if state_policy is vyos_defined %} + jump VYOS_STATE_POLICY +{% endif %} +{% if interface is vyos_defined %} +{% for ifname, ifconf in interface.items() %} +{% if ifconf.in is vyos_defined and ifconf.in.name is vyos_defined %} + iifname {{ ifname }} counter jump NAME_{{ ifconf.in.name }} +{% endif %} +{% if ifconf.out is vyos_defined and ifconf.out.name is vyos_defined %} + oifname {{ ifname }} counter jump NAME_{{ ifconf.out.name }} +{% endif %} +{% endfor %} +{% endif %} jump VYOS_POST_FW } chain VYOS_FW_LOCAL { type filter hook input priority 0; policy accept; +{% if state_policy is vyos_defined %} + jump VYOS_STATE_POLICY +{% endif %} +{% if interface is vyos_defined %} +{% for ifname, ifconf in interface.items() %} +{% if ifconf.local is vyos_defined and ifconf.local.name is vyos_defined %} + iifname {{ ifname }} counter jump NAME_{{ ifconf.local.name }} +{% endif %} +{% endfor %} +{% endif %} jump VYOS_POST_FW } chain VYOS_FW_OUTPUT { type filter hook output priority 0; policy accept; +{% if state_policy is vyos_defined %} + jump VYOS_STATE_POLICY +{% endif %} jump VYOS_POST_FW } chain VYOS_POST_FW { @@ -29,7 +52,6 @@ table ip filter { type filter hook prerouting priority -450; policy accept; ip frag-off & 0x3fff != 0 meta mark set 0xffff1 return } -{% endif %} {% if name is vyos_defined %} {% set ns = namespace(sets=[]) %} {% for name_text, conf in name.items() %} @@ -72,6 +94,10 @@ table ip filter { {{ group_tmpl.groups(group, False) }} +{% if zone is vyos_defined %} +{{ zone_tmpl.zone_chains(zone, state_policy is vyos_defined, False) }} +{% endif %} + {% if state_policy is vyos_defined %} chain VYOS_STATE_POLICY { {% if state_policy.established is vyos_defined %} @@ -88,18 +114,46 @@ table ip filter { {% endif %} } -table ip6 filter { -{% if first_install is vyos_defined %} +{% if first_install is not vyos_defined %} +delete table ip6 vyos_filter +{% endif %} +table ip6 vyos_filter { chain VYOS_FW6_FORWARD { type filter hook forward priority 0; policy accept; +{% if state_policy is vyos_defined %} + jump VYOS_STATE_POLICY6 +{% endif %} +{% if interface is vyos_defined %} +{% for ifname, ifconf in interface.items() %} +{% if ifconf.in is vyos_defined and ifconf.in.ipv6_name is vyos_defined %} + iifname {{ ifname }} counter jump NAME6_{{ ifconf.in.ipv6_name }} +{% endif %} +{% if ifconf.out is vyos_defined and ifconf.out.ipv6_name is vyos_defined %} + oifname {{ ifname }} counter jump NAME6_{{ ifconf.out.ipv6_name }} +{% endif %} +{% endfor %} +{% endif %} jump VYOS_POST_FW6 } chain VYOS_FW6_LOCAL { type filter hook input priority 0; policy accept; +{% if state_policy is vyos_defined %} + jump VYOS_STATE_POLICY6 +{% endif %} +{% if interface is vyos_defined %} +{% for ifname, ifconf in interface.items() %} +{% if ifconf.local is vyos_defined and ifconf.local.ipv6_name is vyos_defined %} + iifname {{ ifname }} counter jump NAME6_{{ ifconf.local.ipv6_name }} +{% endif %} +{% endfor %} +{% endif %} jump VYOS_POST_FW6 } chain VYOS_FW6_OUTPUT { type filter hook output priority 0; policy accept; +{% if state_policy is vyos_defined %} + jump VYOS_STATE_POLICY6 +{% endif %} jump VYOS_POST_FW6 } chain VYOS_POST_FW6 { @@ -109,7 +163,6 @@ table ip6 filter { type filter hook prerouting priority -450; policy accept; exthdr frag exists meta mark set 0xffff1 return } -{% endif %} {% if ipv6_name is vyos_defined %} {% set ns = namespace(sets=[]) %} {% for name_text, conf in ipv6_name.items() %} @@ -144,6 +197,10 @@ table ip6 filter { {{ group_tmpl.groups(group, True) }} +{% if zone is vyos_defined %} +{{ zone_tmpl.zone_chains(zone, state_policy is vyos_defined, True) }} +{% endif %} + {% if state_policy is vyos_defined %} chain VYOS_STATE_POLICY6 { {% if state_policy.established is vyos_defined %} @@ -159,146 +216,3 @@ table ip6 filter { } {% endif %} } - -{% if first_install is vyos_defined %} -table ip nat { - chain PREROUTING { - type nat hook prerouting priority -100; policy accept; - counter jump VYOS_PRE_DNAT_HOOK - } - - chain POSTROUTING { - type nat hook postrouting priority 100; policy accept; - counter jump VYOS_PRE_SNAT_HOOK - } - - chain VYOS_PRE_DNAT_HOOK { - return - } - - chain VYOS_PRE_SNAT_HOOK { - return - } -} - -table ip6 nat { - chain PREROUTING { - type nat hook prerouting priority -100; policy accept; - counter jump VYOS_DNPT_HOOK - } - - chain POSTROUTING { - type nat hook postrouting priority 100; policy accept; - counter jump VYOS_SNPT_HOOK - } - - chain VYOS_DNPT_HOOK { - return - } - - chain VYOS_SNPT_HOOK { - return - } -} - -table inet mangle { - chain FORWARD { - type filter hook forward priority -150; policy accept; - } -} - -table raw { - chain VYOS_TCP_MSS { - type filter hook forward priority -300; policy accept; - } - - chain PREROUTING { - type filter hook prerouting priority -200; policy accept; - counter jump VYOS_CT_IGNORE - counter jump VYOS_CT_TIMEOUT - counter jump VYOS_CT_PREROUTING_HOOK - counter jump FW_CONNTRACK - notrack - } - - chain OUTPUT { - type filter hook output priority -200; policy accept; - counter jump VYOS_CT_IGNORE - counter jump VYOS_CT_TIMEOUT - counter jump VYOS_CT_OUTPUT_HOOK - counter jump FW_CONNTRACK - notrack - } - - ct helper rpc_tcp { - type "rpc" protocol tcp; - } - - ct helper rpc_udp { - type "rpc" protocol udp; - } - - ct helper tns_tcp { - type "tns" protocol tcp; - } - - chain VYOS_CT_HELPER { - ct helper set "rpc_tcp" tcp dport {111} return - ct helper set "rpc_udp" udp dport {111} return - ct helper set "tns_tcp" tcp dport {1521,1525,1536} return - return - } - - chain VYOS_CT_IGNORE { - return - } - - chain VYOS_CT_TIMEOUT { - return - } - - chain VYOS_CT_PREROUTING_HOOK { - return - } - - chain VYOS_CT_OUTPUT_HOOK { - return - } - - chain FW_CONNTRACK { - accept - } -} - -table ip6 raw { - chain VYOS_TCP_MSS { - type filter hook forward priority -300; policy accept; - } - - chain PREROUTING { - type filter hook prerouting priority -300; policy accept; - counter jump VYOS_CT_PREROUTING_HOOK - counter jump FW_CONNTRACK - notrack - } - - chain OUTPUT { - type filter hook output priority -300; policy accept; - counter jump VYOS_CT_OUTPUT_HOOK - counter jump FW_CONNTRACK - notrack - } - - chain VYOS_CT_PREROUTING_HOOK { - return - } - - chain VYOS_CT_OUTPUT_HOOK { - return - } - - chain FW_CONNTRACK { - accept - } -} -{% endif %} diff --git a/data/templates/firewall/upnpd.conf.j2 b/data/templates/firewall/upnpd.conf.j2 index 27573cbf9..e964fc696 100644 --- a/data/templates/firewall/upnpd.conf.j2 +++ b/data/templates/firewall/upnpd.conf.j2 @@ -71,7 +71,7 @@ min_lifetime={{ pcp_lifetime.min }} {% if friendly_name is vyos_defined %} # Name of this service, default is "`uname -s` router" -friendly_name= {{ friendly_name }} +friendly_name={{ friendly_name }} {% endif %} # Manufacturer name, default is "`uname -s`" @@ -117,7 +117,10 @@ clean_ruleset_threshold=10 clean_ruleset_interval=600 # Anchor name in pf (default is miniupnpd) -anchor=VyOS +# Something wrong with this option "anchor", comment it out +# vyos@r14# miniupnpd -vv -f /run/upnp/miniupnp.conf +# invalid option in file /run/upnp/miniupnp.conf line 74 : anchor=VyOS +#anchor=VyOS uuid={{ uuid }} @@ -129,7 +132,7 @@ lease_file=/config/upnp.leases #serial=12345678 #model_number=1 -{% if rules is vyos_defined %} +{% if rule is vyos_defined %} # UPnP permission rules # (allow|deny) (external port range) IP/mask (internal port range) # A port range is <min port>-<max port> or <port> if there is only @@ -142,9 +145,9 @@ lease_file=/config/upnp.leases # modify the IP ranges to match their own internal networks, and # also consider implementing network-specific restrictions # CAUTION: failure to enforce any rules may permit insecure requests to be made! -{% for rule, config in rules.items() %} -{% if config.disable is vyos_defined %} -{{ config.action }} {{ config.external_port_range }} {{ config.ip }} {{ config.internal_port_range }} +{% for rule, config in rule.items() %} +{% if config.disable is not vyos_defined %} +{{ config.action }} {{ config.external_port_range }} {{ config.ip }}{{ '/32' if '/' not in config.ip else '' }} {{ config.internal_port_range }} {% endif %} {% endfor %} {% endif %} diff --git a/data/templates/frr/bgpd.frr.j2 b/data/templates/frr/bgpd.frr.j2 index 2ab7c8596..bf4be23ff 100644 --- a/data/templates/frr/bgpd.frr.j2 +++ b/data/templates/frr/bgpd.frr.j2 @@ -38,6 +38,9 @@ {% if config.disable_capability_negotiation is vyos_defined %} neighbor {{ neighbor }} dont-capability-negotiate {% endif %} +{% if config.disable_connected_check is vyos_defined %} + neighbor {{ neighbor }} disable-connected-check +{% endif %} {% if config.ebgp_multihop is vyos_defined %} neighbor {{ neighbor }} ebgp-multihop {{ config.ebgp_multihop }} {% endif %} @@ -458,6 +461,9 @@ router bgp {{ system_as }} {{ 'vrf ' ~ vrf if vrf is vyos_defined }} {% if parameters.bestpath.med is vyos_defined %} bgp bestpath med {{ 'confed' if parameters.bestpath.med.confed is vyos_defined }} {{ 'missing-as-worst' if parameters.bestpath.med.missing_as_worst is vyos_defined }} {% endif %} +{% if parameters.bestpath.peer_type is vyos_defined %} + bgp bestpath peer-type {{ 'multipath-relax' if parameters.bestpath.peer_type.multipath_relax is vyos_defined }} +{% endif %} {% if parameters.cluster_id is vyos_defined %} bgp cluster-id {{ parameters.cluster_id }} {% endif %} diff --git a/data/templates/frr/isisd.frr.j2 b/data/templates/frr/isisd.frr.j2 index 8e95348bc..709484c98 100644 --- a/data/templates/frr/isisd.frr.j2 +++ b/data/templates/frr/isisd.frr.j2 @@ -124,23 +124,23 @@ router isis VyOS {{ 'vrf ' + vrf if vrf is vyos_defined }} {% for prefix, prefix_config in segment_routing.prefix.items() %} {% if prefix_config.absolute is vyos_defined %} {% if prefix_config.absolute.value is vyos_defined %} - segment-routing prefix {{ prefixes }} absolute {{ prefix_config.absolute.value }} + segment-routing prefix {{ prefix }} absolute {{ prefix_config.absolute.value }} {% if prefix_config.absolute.explicit_null is vyos_defined %} - segment-routing prefix {{ prefixes }} absolute {{ prefix_config.absolute.value }} explicit-null + segment-routing prefix {{ prefix }} absolute {{ prefix_config.absolute.value }} explicit-null {% endif %} {% if prefix_config.absolute.no_php_flag is vyos_defined %} - segment-routing prefix {{ prefixes }} absolute {{ prefix_config.absolute.value }} no-php-flag + segment-routing prefix {{ prefix }} absolute {{ prefix_config.absolute.value }} no-php-flag {% endif %} {% endif %} -{% if prefix_config.index is vyos_defined %} -{% if prefix_config.index.value is vyos_defined %} - segment-routing prefix {{ prefixes }} index {{ prefix_config.index.value }} -{% if prefix_config.index.explicit_null is vyos_defined %} - segment-routing prefix {{ prefixes }} index {{ prefix_config.index.value }} explicit-null -{% endif %} -{% if prefix_config.index.no_php_flag is vyos_defined %} - segment-routing prefix {{ prefixes }} index {{ prefix_config.index.value }} no-php-flag -{% endif %} +{% endif %} +{% if prefix_config.index is vyos_defined %} +{% if prefix_config.index.value is vyos_defined %} + segment-routing prefix {{ prefix }} index {{ prefix_config.index.value }} +{% if prefix_config.index.explicit_null is vyos_defined %} + segment-routing prefix {{ prefix }} index {{ prefix_config.index.value }} explicit-null +{% endif %} +{% if prefix_config.index.no_php_flag is vyos_defined %} + segment-routing prefix {{ prefix }} index {{ prefix_config.index.value }} no-php-flag {% endif %} {% endif %} {% endif %} diff --git a/data/templates/high-availability/keepalived.conf.j2 b/data/templates/high-availability/keepalived.conf.j2 index 6684dbc2c..706e1c5ae 100644 --- a/data/templates/high-availability/keepalived.conf.j2 +++ b/data/templates/high-availability/keepalived.conf.j2 @@ -47,10 +47,10 @@ vrrp_instance {{ name }} { {% endif %} {% endif %} {% if group_config.rfc3768_compatibility is vyos_defined and group_config.peer_address is vyos_defined %} - use_vmac {{ group_config.interface }}v{{ group_config.vrid }} + use_vmac {{ group_config.interface }}v{{ group_config.vrid }}v{{ '4' if group_config['address'] | first | is_ipv4 else '6' }} vmac_xmit_base {% elif group_config.rfc3768_compatibility is vyos_defined %} - use_vmac {{ group_config.interface }}v{{ group_config.vrid }} + use_vmac {{ group_config.interface }}v{{ group_config.vrid }}v{{ '4' if group_config['address'] | first | is_ipv4 else '6' }} {% endif %} {% if group_config.authentication is vyos_defined %} authentication { diff --git a/data/templates/ipsec/swanctl/profile.j2 b/data/templates/ipsec/swanctl/profile.j2 index d4f417378..8519a84f8 100644 --- a/data/templates/ipsec/swanctl/profile.j2 +++ b/data/templates/ipsec/swanctl/profile.j2 @@ -9,6 +9,10 @@ version = {{ ike.key_exchange[4:] if ike.key_exchange is vyos_defined else "0" }} rekey_time = {{ ike.lifetime }}s keyingtries = 0 +{% if ike.dead_peer_detection is vyos_defined %} + dpd_timeout = {{ ike.dead_peer_detection.timeout }} + dpd_delay = {{ ike.dead_peer_detection.interval }} +{% endif %} {% if profile_conf.authentication.mode is vyos_defined('pre-shared-secret') %} local { auth = psk diff --git a/data/templates/login/pam_radius_auth.conf.j2 b/data/templates/login/pam_radius_auth.conf.j2 index 1105b60e5..c61154753 100644 --- a/data/templates/login/pam_radius_auth.conf.j2 +++ b/data/templates/login/pam_radius_auth.conf.j2 @@ -16,7 +16,7 @@ {% if radius.server is vyos_defined %} # server[:port] shared_secret timeout source_ip {# .items() returns a tuple of two elements: key and value. 1 relates to the 2nd element i.e. the value and .priority relates to the key from the internal dict #} -{% for server, options in radius.server.items() | sort(attribute='1.priority') if not options.disabled %} +{% for server, options in radius.server.items() | sort(attribute='1.priority') if not 'disable' in options %} {# RADIUS IPv6 servers must be specified in [] notation #} {% if server | is_ipv4 %} {{ server }}:{{ options.port }} {{ "%-25s" | format(options.key) }} {{ "%-10s" | format(options.timeout) }} {{ source_address.ipv4 if source_address.ipv4 is vyos_defined }} @@ -33,4 +33,3 @@ mapped_priv_user radius_priv_user vrf-name {{ radius.vrf }} {% endif %} {% endif %} - diff --git a/data/templates/monitoring/override.conf.j2 b/data/templates/monitoring/override.conf.j2 deleted file mode 100644 index 9f1b4ebec..000000000 --- a/data/templates/monitoring/override.conf.j2 +++ /dev/null @@ -1,7 +0,0 @@ -[Unit] -After=vyos-router.service -ConditionPathExists=/run/telegraf/vyos-telegraf.conf -[Service] -Environment=INFLUX_TOKEN={{ influxdb.authentication.token }} -CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN CAP_SYS_ADMIN -AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN diff --git a/data/templates/monitoring/systemd_vyos_telegraf_service.j2 b/data/templates/monitoring/systemd_vyos_telegraf_service.j2 deleted file mode 100644 index 234ef5586..000000000 --- a/data/templates/monitoring/systemd_vyos_telegraf_service.j2 +++ /dev/null @@ -1,16 +0,0 @@ -[Unit] -Description=The plugin-driven server agent for reporting metrics into InfluxDB -Documentation=https://github.com/influxdata/telegraf -After=network.target - -[Service] -EnvironmentFile=-/etc/default/telegraf -User=telegraf -ExecStart=/usr/bin/telegraf -config /run/telegraf/vyos-telegraf.conf -config-directory /etc/telegraf/telegraf.d $TELEGRAF_OPTS -ExecReload=/bin/kill -HUP $MAINPID -Restart=on-failure -RestartForceExitStatus=SIGPIPE -KillMode=control-group - -[Install] -WantedBy=multi-user.target diff --git a/data/templates/nhrp/nftables.conf.j2 b/data/templates/nhrp/nftables.conf.j2 new file mode 100644 index 000000000..a0d1f6d4c --- /dev/null +++ b/data/templates/nhrp/nftables.conf.j2 @@ -0,0 +1,17 @@ +#!/usr/sbin/nft -f + +{% if first_install is not vyos_defined %} +delete table ip vyos_nhrp_filter +{% endif %} +table ip vyos_nhrp_filter { + chain VYOS_NHRP_OUTPUT { + type filter hook output priority 10; policy accept; +{% if tunnel is vyos_defined %} +{% for tun, tunnel_conf in tunnel.items() %} +{% if if_tunnel[tun].source_address is vyos_defined %} + ip protocol gre ip saddr {{ if_tunnel[tun].source_address }} ip daddr 224.0.0.0/4 counter drop comment "VYOS_NHRP_{{ tun }}" +{% endif %} +{% endfor %} +{% endif %} + } +} diff --git a/data/templates/ocserv/ocserv_config.j2 b/data/templates/ocserv/ocserv_config.j2 index 8418a2185..3194354e6 100644 --- a/data/templates/ocserv/ocserv_config.j2 +++ b/data/templates/ocserv/ocserv_config.j2 @@ -1,5 +1,9 @@ ### generated by vpn_openconnect.py ### +{% if listen_address is vyos_defined %} +listen-host = {{ listen_address }} +{% endif %} + tcp-port = {{ listen_ports.tcp }} udp-port = {{ listen_ports.udp }} @@ -7,7 +11,7 @@ run-as-user = nobody run-as-group = daemon {% if "radius" in authentication.mode %} -auth = "radius [config=/run/ocserv/radiusclient.conf]" +auth = "radius [config=/run/ocserv/radiusclient.conf{{ ',groupconfig=true' if authentication.radius.groupconfig is vyos_defined else '' }}]" {% elif "local" in authentication.mode %} {% if authentication.mode.local == "password-otp" %} auth = "plain[passwd=/run/ocserv/ocpasswd,otp=/run/ocserv/users.oath]" @@ -56,36 +60,46 @@ ban-reset-time = 300 # The name to use for the tun device device = sslvpn -# An alternative way of specifying the network: -{% if network_settings %} # DNS settings -{% if network_settings.name_server is string %} -dns = {{ network_settings.name_server }} -{% else %} -{% for dns in network_settings.name_server %} +{% if network_settings.name_server is vyos_defined %} +{% for dns in network_settings.name_server %} dns = {{ dns }} -{% endfor %} +{% endfor %} +{% endif %} +{% if network_settings.tunnel_all_dns is vyos_defined %} +{% if "yes" in network_settings.tunnel_all_dns %} +tunnel-all-dns = true +{% else %} +tunnel-all-dns = false {% endif %} +{% endif %} + # IPv4 network pool -{% if network_settings.client_ip_settings %} -{% if network_settings.client_ip_settings.subnet %} +{% if network_settings.client_ip_settings.subnet is vyos_defined %} ipv4-network = {{ network_settings.client_ip_settings.subnet }} -{% endif %} -{% endif %} +{% endif %} + # IPv6 network pool -{% if network_settings.client_ipv6_pool %} -{% if network_settings.client_ipv6_pool.prefix %} +{% if network_settings.client_ipv6_pool.prefix is vyos_defined %} ipv6-network = {{ network_settings.client_ipv6_pool.prefix }} ipv6-subnet-prefix = {{ network_settings.client_ipv6_pool.mask }} -{% endif %} -{% endif %} {% endif %} -{% if network_settings.push_route is string %} -route = {{ network_settings.push_route }} -{% else %} +{% if network_settings.push_route is vyos_defined %} {% for route in network_settings.push_route %} route = {{ route }} {% endfor %} {% endif %} +{% if network_settings.split_dns is vyos_defined %} +{% for tmp in network_settings.split_dns %} +split-dns = {{ tmp }} +{% endfor %} +{% endif %} + +{% if authentication.group is vyos_defined %} +# Group settings +{% for grp in authentication.group %} +select-group = {{ grp }} +{% endfor %} +{% endif %}
\ No newline at end of file diff --git a/data/templates/telegraf/override.conf.j2 b/data/templates/telegraf/override.conf.j2 new file mode 100644 index 000000000..7e3e4aaf5 --- /dev/null +++ b/data/templates/telegraf/override.conf.j2 @@ -0,0 +1,16 @@ +{% set vrf_command = 'ip vrf exec ' ~ vrf ~ ' ' if vrf is vyos_defined else '' %} +[Unit] +After= +After=vyos-router.service +ConditionPathExists=/run/telegraf/telegraf.conf + +[Service] +ExecStart= +ExecStart={{ vrf_command }}/usr/bin/telegraf --config /run/telegraf/telegraf.conf --config-directory /etc/telegraf/telegraf.d --pidfile /run/telegraf/telegraf.pid +PIDFile=/run/telegraf/telegraf.pid +EnvironmentFile= +Environment=INFLUX_TOKEN={{ influxdb.authentication.token }} +CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN CAP_SYS_ADMIN CAP_BPF CAP_DAC_OVERRIDE +AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN +Restart=always +RestartSec=10 diff --git a/data/templates/monitoring/syslog_telegraf.j2 b/data/templates/telegraf/syslog_telegraf.j2 index cdcbd92a4..cdcbd92a4 100644 --- a/data/templates/monitoring/syslog_telegraf.j2 +++ b/data/templates/telegraf/syslog_telegraf.j2 diff --git a/data/templates/monitoring/telegraf.j2 b/data/templates/telegraf/telegraf.j2 index 6b395692b..6b395692b 100644 --- a/data/templates/monitoring/telegraf.j2 +++ b/data/templates/telegraf/telegraf.j2 diff --git a/data/templates/zone_policy/nftables.j2 b/data/templates/zone_policy/nftables.j2 deleted file mode 100644 index fe941f9f8..000000000 --- a/data/templates/zone_policy/nftables.j2 +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/sbin/nft -f - -{% if cleanup_commands is vyos_defined %} -{% for command in cleanup_commands %} -{{ command }} -{% endfor %} -{% endif %} - -{% if zone is vyos_defined %} -table ip filter { -{% for zone_name, zone_conf in zone.items() if zone_conf.ipv4 %} -{% if zone_conf.local_zone is vyos_defined %} - chain VZONE_{{ zone_name }}_IN { - iifname lo counter return -{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall.name is vyos_defined %} - iifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME_{{ from_conf.firewall.name }} - iifname { {{ zone[from_zone].interface | join(",") }} } counter return -{% endfor %} - {{ zone_conf | nft_default_rule('zone_' + zone_name) }} - } - chain VZONE_{{ zone_name }}_OUT { - oifname lo counter return -{% for from_zone, from_conf in zone_conf.from_local.items() if from_conf.firewall.name is vyos_defined %} - oifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME_{{ from_conf.firewall.name }} - oifname { {{ zone[from_zone].interface | join(",") }} } counter return -{% endfor %} - {{ zone_conf | nft_default_rule('zone_' + zone_name) }} - } -{% else %} - chain VZONE_{{ zone_name }} { - iifname { {{ zone_conf.interface | join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6=False) }} -{% if zone_conf.intra_zone_filtering is vyos_defined %} - iifname { {{ zone_conf.interface | join(",") }} } counter return -{% endif %} -{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall.name is vyos_defined %} -{% if zone[from_zone].local_zone is not defined %} - iifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME_{{ from_conf.firewall.name }} - iifname { {{ zone[from_zone].interface | join(",") }} } counter return -{% endif %} -{% endfor %} - {{ zone_conf | nft_default_rule('zone_' + zone_name) }} - } -{% endif %} -{% endfor %} -} - -table ip6 filter { -{% for zone_name, zone_conf in zone.items() if zone_conf.ipv6 %} -{% if zone_conf.local_zone is vyos_defined %} - chain VZONE6_{{ zone_name }}_IN { - iifname lo counter return -{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall.ipv6_name is vyos_defined %} - iifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME6_{{ from_conf.firewall.ipv6_name }} - iifname { {{ zone[from_zone].interface | join(",") }} } counter return -{% endfor %} - {{ zone_conf | nft_default_rule('zone6_' + zone_name) }} - } - chain VZONE6_{{ zone_name }}_OUT { - oifname lo counter return -{% for from_zone, from_conf in zone_conf.from_local.items() if from_conf.firewall.ipv6_name is vyos_defined %} - oifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME6_{{ from_conf.firewall.ipv6_name }} - oifname { {{ zone[from_zone].interface | join(",") }} } counter return -{% endfor %} - {{ zone_conf | nft_default_rule('zone6_' + zone_name) }} - } -{% else %} - chain VZONE6_{{ zone_name }} { - iifname { {{ zone_conf.interface | join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6=True) }} -{% if zone_conf.intra_zone_filtering is vyos_defined %} - iifname { {{ zone_conf.interface | join(",") }} } counter return -{% endif %} -{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall.ipv6_name is vyos_defined %} -{% if zone[from_zone].local_zone is not defined %} - iifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME6_{{ from_conf.firewall.ipv6_name }} - iifname { {{ zone[from_zone].interface | join(",") }} } counter return -{% endif %} -{% endfor %} - {{ zone_conf | nft_default_rule('zone6_' + zone_name) }} - } -{% endif %} -{% endfor %} -} - -{% for zone_name, zone_conf in zone.items() %} -{% if zone_conf.ipv4 %} -{% if 'local_zone' in zone_conf %} -insert rule ip filter VYOS_FW_LOCAL counter jump VZONE_{{ zone_name }}_IN -insert rule ip filter VYOS_FW_OUTPUT counter jump VZONE_{{ zone_name }}_OUT -{% else %} -insert rule ip filter VYOS_FW_FORWARD oifname { {{ zone_conf.interface | join(',') }} } counter jump VZONE_{{ zone_name }} -{% endif %} -{% endif %} -{% if zone_conf.ipv6 %} -{% if 'local_zone' in zone_conf %} -insert rule ip6 filter VYOS_FW6_LOCAL counter jump VZONE6_{{ zone_name }}_IN -insert rule ip6 filter VYOS_FW6_OUTPUT counter jump VZONE6_{{ zone_name }}_OUT -{% else %} -insert rule ip6 filter VYOS_FW6_FORWARD oifname { {{ zone_conf.interface | join(',') }} } counter jump VZONE6_{{ zone_name }} -{% endif %} -{% endif %} -{% endfor %} - -{# Ensure that state-policy rule is first in the chain #} -{% if firewall.state_policy is vyos_defined %} -{% for chain in ['VYOS_FW_FORWARD', 'VYOS_FW_OUTPUT', 'VYOS_FW_LOCAL'] %} -insert rule ip filter {{ chain }} jump VYOS_STATE_POLICY -{% endfor %} -{% for chain in ['VYOS_FW6_FORWARD', 'VYOS_FW6_OUTPUT', 'VYOS_FW6_LOCAL'] %} -insert rule ip6 filter {{ chain }} jump VYOS_STATE_POLICY6 -{% endfor %} -{% endif %} - -{% endif %} |