diff options
Diffstat (limited to 'data')
63 files changed, 760 insertions, 531 deletions
diff --git a/data/config-mode-dependencies/vyos-1x.json b/data/config-mode-dependencies/vyos-1x.json index cbd14f7c6..ccfc022f4 100644 --- a/data/config-mode-dependencies/vyos-1x.json +++ b/data/config-mode-dependencies/vyos-1x.json @@ -14,6 +14,9 @@ "vxlan": ["interfaces_vxlan"], "wlan": ["interfaces_wireless"] }, + "interfaces_wireguard": { + "vxlan": ["interfaces_vxlan"] + }, "load_balancing_wan": { "conntrack": ["system_conntrack"] }, @@ -31,6 +34,7 @@ "ipsec": ["vpn_ipsec"], "openconnect": ["vpn_openconnect"], "rpki": ["protocols_rpki"], + "ssh": ["service_ssh"], "sstp": ["vpn_sstp"], "sstpc": ["interfaces_sstpc"], "stunnel": ["service_stunnel"] @@ -70,6 +74,9 @@ "system_ipv6": { "sysctl": ["system_sysctl"] }, + "system_login": { + "ssh": ["service_ssh"] + }, "system_option": { "ip_ipv6": ["system_ip", "system_ipv6"], "sysctl": ["system_sysctl"] diff --git a/data/config.boot.default b/data/config.boot.default index 93369d9b7..02f56da8f 100644 --- a/data/config.boot.default +++ b/data/config.boot.default @@ -40,8 +40,11 @@ system { } } } + option { + reboot-on-upgrade-failure 5 + } syslog { - global { + local { facility all { level "info" } diff --git a/data/op-mode-standardized.json b/data/op-mode-standardized.json index 35587b63c..5d3f4a249 100644 --- a/data/op-mode-standardized.json +++ b/data/op-mode-standardized.json @@ -13,13 +13,13 @@ "evpn.py", "interfaces.py", "ipsec.py", +"load-balancing_wan.py", "lldp.py", "log.py", "memory.py", "multicast.py", "nat.py", "neighbor.py", -"nhrp.py", "openconnect.py", "openvpn.py", "otp.py", @@ -28,6 +28,7 @@ "load-balancing_haproxy.py", "route.py", "storage.py", +"stp.py", "system.py", "uptime.py", "version.py", diff --git a/data/templates/accel-ppp/chap-secrets.ipoe.j2 b/data/templates/accel-ppp/chap-secrets.ipoe.j2 index dd85160c0..59b9dfc8d 100644 --- a/data/templates/accel-ppp/chap-secrets.ipoe.j2 +++ b/data/templates/accel-ppp/chap-secrets.ipoe.j2 @@ -6,7 +6,7 @@ {% if mac_config.vlan is vyos_defined %} {% set iface = iface ~ '.' ~ mac_config.vlan %} {% endif %} -{{ "%-11s" | format(iface) }} * {{ mac | lower }} {{ mac_config.static_ip if mac_config.static_ip is vyos_defined else '*' }} {{ mac_config.rate_limit.download ~ '/' ~ mac_config.rate_limit.upload if mac_config.rate_limit.download is vyos_defined and mac_config.rate_limit.upload is vyos_defined }} +{{ "%-11s" | format(iface) }} * {{ mac | lower }} {{ mac_config.ip_address if mac_config.ip_address is vyos_defined else '*' }} {{ mac_config.rate_limit.download ~ '/' ~ mac_config.rate_limit.upload if mac_config.rate_limit.download is vyos_defined and mac_config.rate_limit.upload is vyos_defined }} {% endfor %} {% endif %} {% endfor %} diff --git a/data/templates/aws/override_aws_gwlbtun.conf.j2 b/data/templates/aws/override_aws_gwlbtun.conf.j2 index 4c566d852..e7e60dc95 100644 --- a/data/templates/aws/override_aws_gwlbtun.conf.j2 +++ b/data/templates/aws/override_aws_gwlbtun.conf.j2 @@ -30,7 +30,7 @@ After=vyos-router.service [Service] EnvironmentFile= -ExecStart=/usr/bin/gwlbtun {{ args | join(' ') }} -CapabilityBoundingSet=CAP_NET_ADMIN +ExecStart=/usr/sbin/gwlbtun {{ args | join(' ') }} +CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW Restart=always RestartSec=10 diff --git a/data/templates/conntrack/sysctl.conf.j2 b/data/templates/conntrack/sysctl.conf.j2 index cd6c34ede..8d934db9c 100644 --- a/data/templates/conntrack/sysctl.conf.j2 +++ b/data/templates/conntrack/sysctl.conf.j2 @@ -1,10 +1,11 @@ # Autogenerated by system_conntrack.py {# all values have defaults - thus no checking required #} +net.netfilter.nf_conntrack_buckets = {{ hash_size }} net.netfilter.nf_conntrack_expect_max = {{ expect_table_size }} net.netfilter.nf_conntrack_max = {{ table_size }} net.ipv4.tcp_max_syn_backlog = {{ tcp.half_open_connections }} net.netfilter.nf_conntrack_tcp_loose = {{ '1' if tcp.loose is vyos_defined('enable') else '0' }} net.netfilter.nf_conntrack_tcp_max_retrans = {{ tcp.max_retrans }} net.netfilter.nf_conntrack_acct = {{ '1' if flow_accounting is vyos_defined else '0' }} -net.netfilter.nf_conntrack_timestamp = {{ '1' if log.timestamp is vyos_defined else '0' }}
\ No newline at end of file +net.netfilter.nf_conntrack_timestamp = {{ '1' if log.timestamp is vyos_defined else '0' }} diff --git a/data/templates/conntrack/vyos_nf_conntrack.conf.j2 b/data/templates/conntrack/vyos_nf_conntrack.conf.j2 deleted file mode 100644 index 1b12fec5f..000000000 --- a/data/templates/conntrack/vyos_nf_conntrack.conf.j2 +++ /dev/null @@ -1,2 +0,0 @@ -# Autogenerated by system_conntrack.py -options nf_conntrack hashsize={{ hash_size }} diff --git a/data/templates/conserver/dropbear@.service.j2 b/data/templates/conserver/dropbear@.service.j2 index e355dab43..c6c31f98f 100644 --- a/data/templates/conserver/dropbear@.service.j2 +++ b/data/templates/conserver/dropbear@.service.j2 @@ -1,4 +1,4 @@ [Service] ExecStart= -ExecStart=/usr/sbin/dropbear -w -j -k -r /etc/dropbear/dropbear_rsa_host_key -b /etc/issue.net -c "/usr/bin/console {{ device }}" -P /run/conserver/dropbear.%I.pid -p %I +ExecStart=/usr/sbin/dropbear -w -j -k -r /etc/dropbear/dropbear_rsa_host_key -r /etc/dropbear/dropbear_ecdsa_host_key -b /etc/issue.net -c "/usr/bin/console {{ device }}" -P /run/conserver/dropbear.%I.pid -p %I PIDFile=/run/conserver/dropbear.%I.pid diff --git a/data/templates/container/containers.conf.j2 b/data/templates/container/containers.conf.j2 index c8b54dfbb..414c3e849 100644 --- a/data/templates/container/containers.conf.j2 +++ b/data/templates/container/containers.conf.j2 @@ -170,10 +170,6 @@ default_sysctls = [ # #label = true -# Logging driver for the container. Available options: k8s-file and journald. -# -#log_driver = "k8s-file" - # Maximum size allowed for the container log file. Negative numbers indicate # that no size limit is imposed. If positive, it must be >= 8192 to match or # exceed conmon's read buffer. The file is truncated and re-opened so the diff --git a/data/templates/container/registries.conf.j2 b/data/templates/container/registries.conf.j2 index eb7ff8775..b5c7eed9b 100644 --- a/data/templates/container/registries.conf.j2 +++ b/data/templates/container/registries.conf.j2 @@ -28,4 +28,14 @@ {% set _ = registry_list.append(r) %} {% endfor %} unqualified-search-registries = {{ registry_list }} +{% for r, r_options in registry.items() if r_options.disable is not vyos_defined %} +[[registry]] +{% if r_options.mirror is vyos_defined %} +location = "{{ r_options.mirror.host_name if r_options.mirror.host_name is vyos_defined else r_options.mirror.address }}{{ ":" + r_options.mirror.port if r_options.mirror.port is vyos_defined }}{{ r_options.mirror.path if r_options.mirror.path is vyos_defined }}" +{% else %} +location = "{{ r }}" +{% endif %} +insecure = {{ 'true' if r_options.insecure is vyos_defined else 'false' }} +prefix = "{{ r }}" +{% endfor %} {% endif %} diff --git a/data/templates/dhcp-client/ipv6.override.conf.j2 b/data/templates/dhcp-client/ipv6.override.conf.j2 index b0c0e0544..d270a55fc 100644 --- a/data/templates/dhcp-client/ipv6.override.conf.j2 +++ b/data/templates/dhcp-client/ipv6.override.conf.j2 @@ -4,6 +4,9 @@ [Unit] ConditionPathExists={{ dhcp6_client_dir }}/dhcp6c.%i.conf +{% if ifname.startswith('pppoe') %} +After=ppp@{{ ifname }}.service +{% endif %} [Service] ExecStart= diff --git a/data/templates/dhcp-server/10-override.conf.j2 b/data/templates/dhcp-server/10-override.conf.j2 deleted file mode 100644 index 6cf9e0a11..000000000 --- a/data/templates/dhcp-server/10-override.conf.j2 +++ /dev/null @@ -1,2 +0,0 @@ -[Unit] -ConditionFileNotEmpty= diff --git a/data/templates/dhcp-server/kea-ctrl-agent.conf.j2 b/data/templates/dhcp-server/kea-ctrl-agent.conf.j2 deleted file mode 100644 index b37cf4798..000000000 --- a/data/templates/dhcp-server/kea-ctrl-agent.conf.j2 +++ /dev/null @@ -1,14 +0,0 @@ -{ - "Control-agent": { -{% if high_availability is vyos_defined %} - "http-host": "{{ high_availability.source_address }}", - "http-port": 647, - "control-sockets": { - "dhcp4": { - "socket-type": "unix", - "socket-name": "/run/kea/dhcp4-ctrl-socket" - } - } -{% endif %} - } -} diff --git a/data/templates/dhcp-server/kea-dhcp-ddns.conf.j2 b/data/templates/dhcp-server/kea-dhcp-ddns.conf.j2 new file mode 100644 index 000000000..7b0394a88 --- /dev/null +++ b/data/templates/dhcp-server/kea-dhcp-ddns.conf.j2 @@ -0,0 +1,30 @@ +{ + "DhcpDdns": { + "ip-address": "127.0.0.1", + "port": 53001, + "control-socket": { + "socket-type": "unix", + "socket-name": "/run/kea/kea-ddns-ctrl-socket" + }, + "tsig-keys": {{ dynamic_dns_update | kea_dynamic_dns_update_tsig_key_json }}, + "forward-ddns" : { + "ddns-domains": {{ dynamic_dns_update | kea_dynamic_dns_update_domains('forward_domain') }} + }, + "reverse-ddns" : { + "ddns-domains": {{ dynamic_dns_update | kea_dynamic_dns_update_domains('reverse_domain') }} + }, + "loggers": [ + { + "name": "kea-dhcp-ddns", + "output_options": [ + { + "output": "stdout", + "pattern": "%-5p %m\n" + } + ], + "severity": "INFO", + "debuglevel": 0 + } + ] + } +} diff --git a/data/templates/dhcp-server/kea-dhcp4.conf.j2 b/data/templates/dhcp-server/kea-dhcp4.conf.j2 index 2e10d58e0..d08ca0eaa 100644 --- a/data/templates/dhcp-server/kea-dhcp4.conf.j2 +++ b/data/templates/dhcp-server/kea-dhcp4.conf.j2 @@ -25,20 +25,6 @@ }, "option-def": [ { - "name": "rfc3442-static-route", - "code": 121, - "type": "record", - "array": true, - "record-types": "uint8,uint8,uint8,uint8,uint8,uint8,uint8" - }, - { - "name": "windows-static-route", - "code": 249, - "type": "record", - "array": true, - "record-types": "uint8,uint8,uint8,uint8,uint8,uint8,uint8" - }, - { "name": "wpad-url", "code": 252, "type": "string" @@ -50,6 +36,19 @@ "space": "ubnt" } ], +{% if dynamic_dns_update is vyos_defined %} + "dhcp-ddns": { + "enable-updates": true, + "server-ip": "127.0.0.1", + "server-port": 53001, + "sender-ip": "", + "sender-port": 0, + "max-queue-size": 1024, + "ncr-protocol": "UDP", + "ncr-format": "JSON" + }, + {{ dynamic_dns_update | kea_dynamic_dns_update_main_json }} +{% endif %} "hooks-libraries": [ {% if high_availability is vyos_defined %} { @@ -69,6 +68,16 @@ }, {% endif %} { + "library": "/usr/lib/{{ machine }}-linux-gnu/kea/hooks/libdhcp_ping_check.so", + "parameters": { + "enable-ping-check" : false, + "min-ping-requests" : 1, + "reply-timeout" : 100, + "ping-cltt-secs" : 60, + "ping-channel-threads" : 0 + } + }, + { "library": "/usr/lib/{{ machine }}-linux-gnu/kea/hooks/libdhcp_lease_cmds.so", "parameters": {} } diff --git a/data/templates/dns-dynamic/ddclient.conf.j2 b/data/templates/dns-dynamic/ddclient.conf.j2 index 5538ea56c..b209c8c81 100644 --- a/data/templates/dns-dynamic/ddclient.conf.j2 +++ b/data/templates/dns-dynamic/ddclient.conf.j2 @@ -21,11 +21,7 @@ if{{ ipv }}={{ address }}, \ {{ host }} {% endmacro %} ### Autogenerated by service_dns_dynamic.py ### -daemon={{ interval }} -syslog=yes ssl=yes -pid={{ config_file | replace('.conf', '.pid') }} -cache={{ config_file | replace('.conf', '.cache') }} {# ddclient default (web=dyndns) doesn't support ssl and results in process lockup #} web=googledomains {# ddclient default (use=ip) results in confusing warning message in log #} diff --git a/data/templates/dns-dynamic/override.conf.j2 b/data/templates/dns-dynamic/override.conf.j2 index 4a6851cef..aaed4ff35 100644 --- a/data/templates/dns-dynamic/override.conf.j2 +++ b/data/templates/dns-dynamic/override.conf.j2 @@ -1,10 +1,12 @@ {% set vrf_command = 'ip vrf exec ' ~ vrf ~ ' ' if vrf is vyos_defined else '' %} +{% set cache_file = config_file.replace('.conf', '.cache') %} [Unit] ConditionPathExists={{ config_file }} +Wants= After=vyos-router.service [Service] -PIDFile={{ config_file | replace('.conf', '.pid') }} EnvironmentFile= ExecStart= -ExecStart={{ vrf_command }}/usr/bin/ddclient -file {{ config_file }} +ExecStart={{ vrf_command }}/usr/bin/ddclient --file {{ config_file }} --cache {{ cache_file }} --foreground --daemon {{ interval }} +Restart=always diff --git a/data/templates/firewall/nftables-defines.j2 b/data/templates/firewall/nftables-defines.j2 index fa6cd74c0..c4b6b7eba 100644 --- a/data/templates/firewall/nftables-defines.j2 +++ b/data/templates/firewall/nftables-defines.j2 @@ -35,6 +35,24 @@ } {% endfor %} {% endif %} +{% if group.remote_group is vyos_defined and is_l3 and not is_ipv6 %} +{% for name, name_config in group.remote_group.items() %} + set R_{{ name }} { + type {{ ip_type }} + flags interval + auto-merge + } +{% endfor %} +{% endif %} +{% if group.remote_group is vyos_defined and is_l3 and is_ipv6 %} +{% for name, name_config in group.remote_group.items() %} + set R6_{{ name }} { + type {{ ip_type }} + flags interval + auto-merge + } +{% 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 [] %} @@ -93,7 +111,7 @@ 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(",") }} } + elements = { {{ group_conf.interface | nft_nested_group(includes, group.interface_group, 'interface') | quoted_join(",") }} } {% endif %} } {% endfor %} diff --git a/data/templates/firewall/nftables-geoip-update.j2 b/data/templates/firewall/nftables-geoip-update.j2 index 832ccc3e9..d8f80d1f5 100644 --- a/data/templates/firewall/nftables-geoip-update.j2 +++ b/data/templates/firewall/nftables-geoip-update.j2 @@ -31,3 +31,36 @@ table ip6 vyos_filter { {% endfor %} } {% endif %} + + +{% if ipv4_sets_policy is vyos_defined %} +{% for setname, ip_list in ipv4_sets_policy.items() %} +flush set ip vyos_mangle {{ setname }} +{% endfor %} + +table ip vyos_mangle { +{% for setname, ip_list in ipv4_sets_policy.items() %} + set {{ setname }} { + type ipv4_addr + flags interval + elements = { {{ ','.join(ip_list) }} } + } +{% endfor %} +} +{% endif %} + +{% if ipv6_sets_policy is vyos_defined %} +{% for setname, ip_list in ipv6_sets_policy.items() %} +flush set ip6 vyos_mangle {{ setname }} +{% endfor %} + +table ip6 vyos_mangle { +{% for setname, ip_list in ipv6_sets_policy.items() %} + set {{ setname }} { + type ipv6_addr + flags interval + elements = { {{ ','.join(ip_list) }} } + } +{% endfor %} +} +{% endif %} diff --git a/data/templates/firewall/nftables-policy.j2 b/data/templates/firewall/nftables-policy.j2 index 9e28899b0..00d0e8a62 100644 --- a/data/templates/firewall/nftables-policy.j2 +++ b/data/templates/firewall/nftables-policy.j2 @@ -33,6 +33,15 @@ table ip vyos_mangle { {% endif %} } {% 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(firewall_group, False, True) }} @@ -65,6 +74,14 @@ table ip6 vyos_mangle { {% endif %} } {% 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(firewall_group, True, True) }} diff --git a/data/templates/firewall/nftables-zone.j2 b/data/templates/firewall/nftables-zone.j2 index e78725079..66f7e0b1c 100644 --- a/data/templates/firewall/nftables-zone.j2 +++ b/data/templates/firewall/nftables-zone.j2 @@ -8,7 +8,14 @@ {% 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 }} +{% if 'interface' in zone_conf.member %} + oifname { {{ zone_conf.member.interface | quoted_join(',') }} } counter jump VZONE_{{ zone_name }} +{% endif %} +{% if 'vrf' in zone_conf.member %} +{% for vrf_name in zone_conf.member.vrf %} + oifname { "{{ zone_conf['vrf_interfaces'][vrf_name] }}" } counter jump VZONE_{{ zone_name }} +{% endfor %} +{% endif %} {% endif %} {% endfor %} } @@ -40,8 +47,15 @@ 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 + +{% if 'interface' in zone[from_zone].member %} + iifname { {{ zone[from_zone].member.interface | quoted_join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }} + iifname { {{ zone[from_zone].member.interface | quoted_join(",") }} } counter return +{% endif %} +{% if 'vrf' in zone[from_zone].member %} + iifname { {{ zone[from_zone].member.vrf | quoted_join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }} + iifname { {{ zone[from_zone].member.vrf | quoted_join(",") }} } counter return +{% endif %} {% endfor %} {% endif %} {{ zone_conf | nft_default_rule('zone_' + zone_name, family) }} @@ -50,23 +64,47 @@ 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 +{% if 'interface' in zone[from_zone].member %} + oifname { {{ zone[from_zone].member.interface | quoted_join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[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.firewall[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) }} } {% else %} chain VZONE_{{ zone_name }} { - iifname { {{ zone_conf.interface | join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6) }} +{% if 'interface' in zone_conf.member %} + iifname { {{ zone_conf.member.interface | quoted_join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6) }} +{% endif %} +{% if 'vrf' in zone_conf.member %} + iifname { {{ zone_conf.member.vrf | quoted_join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6) }} +{% endif %} {% if zone_conf.intra_zone_filtering is vyos_defined %} - iifname { {{ zone_conf.interface | join(",") }} } counter return +{% if 'interface' in zone_conf.member %} + iifname { {{ zone_conf.member.interface | quoted_join(",") }} } counter return +{% endif %} +{% if 'vrf' in zone_conf.member %} + iifname { {{ zone_conf.member.vrf | quoted_join(",") }} } counter return +{% endif %} {% 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 +{% if 'interface' in zone[from_zone].member %} + iifname { {{ zone[from_zone].member.interface | quoted_join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }} + iifname { {{ zone[from_zone].member.interface | quoted_join(",") }} } counter return +{% endif %} +{% if 'vrf' in zone[from_zone].member %} + iifname { {{ zone[from_zone].member.vrf | quoted_join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }} + iifname { {{ zone[from_zone].member.vrf | quoted_join(",") }} } counter return +{% endif %} {% endif %} {% endfor %} {% endif %} diff --git a/data/templates/firewall/nftables.j2 b/data/templates/firewall/nftables.j2 index a35143870..39ef72059 100755 --- a/data/templates/firewall/nftables.j2 +++ b/data/templates/firewall/nftables.j2 @@ -47,7 +47,7 @@ table ip vyos_filter { chain VYOS_FORWARD_{{ prior }} { type filter hook forward priority {{ prior }}; policy accept; {% if global_options.state_policy is vyos_defined %} - jump VYOS_STATE_POLICY + jump VYOS_STATE_POLICY_FORWARD {% endif %} {% if conf.rule is vyos_defined %} {% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} @@ -180,6 +180,22 @@ table ip vyos_filter { {% endif %} return } + + chain VYOS_STATE_POLICY_FORWARD { +{% if global_options.state_policy.offload is vyos_defined %} + counter flow add @VYOS_FLOWTABLE_{{ global_options.state_policy.offload.offload_target }} +{% endif %} +{% 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 %} } @@ -200,7 +216,7 @@ table ip6 vyos_filter { 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 + jump VYOS_STATE_POLICY6_FORWARD {% endif %} {% if conf.rule is vyos_defined %} {% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} @@ -331,6 +347,22 @@ table ip6 vyos_filter { {% endif %} return } + + chain VYOS_STATE_POLICY6_FORWARD { +{% if global_options.state_policy.offload is vyos_defined %} + counter flow add @VYOS_FLOWTABLE_{{ global_options.state_policy.offload.offload_target }} +{% endif %} +{% 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 %} } @@ -378,11 +410,11 @@ table bridge vyos_filter { {% for prior, conf in bridge.output.items() %} chain VYOS_OUTPUT_{{ prior }} { type filter hook output priority {{ prior }}; policy accept; -{% if global_options.apply_to_bridged_traffic is vyos_defined %} -{% if 'invalid_connections' in global_options.apply_to_bridged_traffic %} - ct state invalid udp sport 67 udp dport 68 counter accept - ct state invalid ether type arp counter accept - ct state invalid ether type 0x8864 counter accept +{% if global_options.apply_to_bridged_traffic.accept_invalid is vyos_defined %} +{% if 'ethernet_type' in global_options.apply_to_bridged_traffic.accept_invalid %} +{% for ether_type in global_options.apply_to_bridged_traffic.accept_invalid.ethernet_type %} + {{ ether_type | nft_accept_invalid() }} +{% endfor %} {% endif %} {% endif %} {% if global_options.state_policy is vyos_defined %} @@ -435,13 +467,13 @@ table bridge vyos_filter { {% 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') }} + {{ global_options.state_policy.established | nft_state_policy('established', bridge=True) }} {% endif %} {% if global_options.state_policy.invalid is vyos_defined %} - {{ global_options.state_policy.invalid | nft_state_policy('invalid') }} + {{ global_options.state_policy.invalid | nft_state_policy('invalid', bridge=True) }} {% endif %} {% if global_options.state_policy.related is vyos_defined %} - {{ global_options.state_policy.related | nft_state_policy('related') }} + {{ global_options.state_policy.related | nft_state_policy('related', bridge=True) }} {% endif %} return } diff --git a/data/templates/frr/bgpd.frr.j2 b/data/templates/frr/bgpd.frr.j2 index 51a3f2564..e5a75090f 100644 --- a/data/templates/frr/bgpd.frr.j2 +++ b/data/templates/frr/bgpd.frr.j2 @@ -98,6 +98,8 @@ {% endif %} {% if config.enforce_first_as is vyos_defined %} neighbor {{ neighbor }} enforce-first-as +{% else %} + no neighbor {{ neighbor }} enforce-first-as {% endif %} {% if config.strict_capability_match is vyos_defined %} neighbor {{ neighbor }} strict-capability-match @@ -310,7 +312,9 @@ router bgp {{ system_as }} {{ 'vrf ' ~ vrf if vrf is vyos_defined }} {% if afi_config.redistribute is vyos_defined %} {% for protocol, protocol_config in afi_config.redistribute.items() %} {% if protocol == 'table' %} - redistribute table {{ protocol_config.table }} +{% for table, table_config in protocol_config.items() %} + redistribute table-direct {{ table }} {{ 'metric ' ~ table_config.metric if table_config.metric is vyos_defined }} {{ 'route-map ' ~ table_config.route_map if table_config.route_map is vyos_defined }} +{% endfor %} {% else %} {% set redistribution_protocol = protocol %} {% if protocol == 'ospfv3' %} @@ -355,6 +359,9 @@ router bgp {{ system_as }} {{ 'vrf ' ~ vrf if vrf is vyos_defined }} import vrf {{ vrf }} {% endfor %} {% endif %} +{% if afi_config.route_map.vrf.import is vyos_defined %} + import vrf route-map {{ afi_config.route_map.vrf.import }} +{% endif %} {% if afi_config.label.vpn.export is vyos_defined %} label vpn export {{ afi_config.label.vpn.export }} {% endif %} @@ -631,6 +638,9 @@ bgp route-reflector allow-outbound-policy {% if parameters.no_fast_external_failover is vyos_defined %} no bgp fast-external-failover {% endif %} +{% if parameters.no_ipv6_auto_ra is vyos_defined %} + no bgp ipv6-auto-ra +{% endif %} {% if parameters.no_suppress_duplicates is vyos_defined %} no bgp suppress-duplicates {% endif %} diff --git a/data/templates/frr/daemons.frr.tmpl b/data/templates/frr/daemons.frr.tmpl index 3506528d2..afd888122 100644 --- a/data/templates/frr/daemons.frr.tmpl +++ b/data/templates/frr/daemons.frr.tmpl @@ -4,7 +4,6 @@ # Note: The following FRR-services must be kept disabled because they are replaced by other packages in VyOS: # # pimd Replaced by package igmpproxy. -# nhrpd Replaced by package opennhrp. # pbrd Replaced by PBR in nftables. # vrrpd Replaced by package keepalived. # @@ -30,7 +29,7 @@ isisd=yes pimd=no pim6d=yes ldpd=yes -nhrpd=no +nhrpd=yes eigrpd=no babeld=yes sharpd=no diff --git a/data/templates/frr/ldpd.frr.j2 b/data/templates/frr/ldpd.frr.j2 index 9a893cc55..b8fb0cfc7 100644 --- a/data/templates/frr/ldpd.frr.j2 +++ b/data/templates/frr/ldpd.frr.j2 @@ -82,8 +82,11 @@ mpls ldp {% endfor %} {% endif %} {% if ldp.interface is vyos_defined %} -{% for interface in ldp.interface %} +{% for interface, iface_config in ldp.interface.items() %} interface {{ interface }} +{% if iface_config.disable_establish_hello is vyos_defined %} + disable-establish-hello +{% endif %} exit {% endfor %} {% endif %} @@ -135,8 +138,11 @@ mpls ldp {% endfor %} {% endif %} {% if ldp.interface is vyos_defined %} -{% for interface in ldp.interface %} +{% for interface, iface_config in ldp.interface.items() %} interface {{ interface }} +{% if iface_config.disable_establish_hello is vyos_defined %} + disable-establish-hello +{% endif %} {% endfor %} {% endif %} exit-address-family diff --git a/data/templates/frr/nhrpd.frr.j2 b/data/templates/frr/nhrpd.frr.j2 new file mode 100644 index 000000000..813a9384b --- /dev/null +++ b/data/templates/frr/nhrpd.frr.j2 @@ -0,0 +1,60 @@ +! +{% if redirect is vyos_defined %} +nhrp nflog-group {{ redirect }} +{% endif %} +{% if multicast is vyos_defined %} +nhrp multicast-nflog-group {{ multicast }} +{% endif %} +{% if tunnel is vyos_defined %} +{% for iface, iface_config in tunnel.items() %} +interface {{ iface }} +{% if iface_config.authentication is vyos_defined %} + ip nhrp authentication {{ iface_config.authentication }} +{% endif %} +{% if iface_config.holdtime is vyos_defined %} + ip nhrp holdtime {{ iface_config.holdtime }} +{% endif %} +{% if iface_config.map.tunnel_ip is vyos_defined %} +{% for tunip, tunip_config in iface_config.map.tunnel_ip.items() %} +{% if tunip_config.nbma is vyos_defined %} + ip nhrp map {{ tunip }} {{ tunip_config.nbma }} +{% endif %} +{% endfor %} +{% endif %} +{% if iface_config.mtu is vyos_defined %} + ip nhrp mtu {{ iface_config.mtu }} +{% endif %} +{% if iface_config.multicast is vyos_defined %} +{% for multicast_ip in iface_config.multicast %} + ip nhrp map multicast {{ multicast_ip }} +{% endfor %} +{% endif %} +{% if iface_config.nhs.tunnel_ip is vyos_defined %} +{% for tunip, tunip_config in iface_config.nhs.tunnel_ip.items() %} +{% if tunip_config.nbma is vyos_defined %} +{% for nbmaip in tunip_config.nbma %} + ip nhrp nhs {{ tunip }} nbma {{ nbmaip }} +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} +{% if iface_config.network_id is vyos_defined %} + ip nhrp network-id {{ iface_config.network_id }} +{% endif %} +{% if iface_config.redirect is vyos_defined %} + ip nhrp redirect +{% endif %} +{% if iface_config.registration_no_unique is vyos_defined %} + ip nhrp registration no-unique +{% endif %} +{% if iface_config.shortcut is vyos_defined %} + ip nhrp shortcut +{% endif %} +{% if iface_config.security_profile is vyos_defined %} + tunnel protection vici profile dmvpn-{{ iface_config.security_profile }}-{{ iface }}-child +{% endif %} +exit +! +{% endfor %} +{% endif %} +! diff --git a/data/templates/frr/nhrpd_nftables.conf.j2 b/data/templates/frr/nhrpd_nftables.conf.j2 new file mode 100644 index 000000000..6ae35ef52 --- /dev/null +++ b/data/templates/frr/nhrpd_nftables.conf.j2 @@ -0,0 +1,46 @@ +#!/usr/sbin/nft -f + +table ip vyos_nhrp_multicast +table ip vyos_nhrp_redirect +delete table ip vyos_nhrp_multicast +delete table ip vyos_nhrp_redirect +{% if multicast is vyos_defined %} +table ip vyos_nhrp_multicast { + chain VYOS_NHRP_MULTICAST_OUTPUT { + type filter hook output priority filter+10; policy accept; +{% if tunnel is vyos_defined %} +{% for tun, tunnel_conf in tunnel.items() %} +{% if tunnel_conf.multicast is vyos_defined %} + oifname "{{ tun }}" ip daddr 224.0.0.0/24 counter log group {{ multicast }} + oifname "{{ tun }}" ip daddr 224.0.0.0/24 counter drop +{% endif %} +{% endfor %} +{% endif %} + } + chain VYOS_NHRP_MULTICAST_FORWARD { + type filter hook forward priority filter+10; policy accept; +{% if tunnel is vyos_defined %} +{% for tun, tunnel_conf in tunnel.items() %} +{% if tunnel_conf.multicast is vyos_defined %} + oifname "{{ tun }}" ip daddr 224.0.0.0/4 counter log group {{ multicast }} + oifname "{{ tun }}" ip daddr 224.0.0.0/4 counter drop +{% endif %} +{% endfor %} +{% endif %} + } +} +{% endif %} +{% if redirect is vyos_defined %} +table ip vyos_nhrp_redirect { + chain VYOS_NHRP_REDIRECT_FORWARD { + type filter hook forward priority filter+10; policy accept; +{% if tunnel is vyos_defined %} +{% for tun, tunnel_conf in tunnel.items() %} +{% if tunnel_conf.redirect is vyos_defined %} + iifname "{{ tun }}" oifname "{{ tun }}" meter loglimit-0 size 65535 { ip daddr & 255.255.255.0 . ip saddr & 255.255.255.0 timeout 1m limit rate 4/minute burst 1 packets } counter log group {{ redirect }} +{% endif %} +{% endfor %} +{% endif %} + } +} +{% endif %} diff --git a/data/templates/frr/ospfd.frr.j2 b/data/templates/frr/ospfd.frr.j2 index bc2c74b10..79824fb64 100644 --- a/data/templates/frr/ospfd.frr.j2 +++ b/data/templates/frr/ospfd.frr.j2 @@ -82,7 +82,7 @@ router ospf {{ 'vrf ' ~ vrf if vrf is vyos_defined }} {% for area_id, area_config in area.items() %} {% if area_config.area_type is vyos_defined %} {% for type, type_config in area_config.area_type.items() if type != 'normal' %} - area {{ area_id }} {{ type }} {{ 'no-summary' if type_config.no_summary is vyos_defined }} + area {{ area_id }} {{ type }} {{ 'translate-' + type_config.translate if type_config.translate is vyos_defined }} {{ 'no-summary' if type_config.no_summary is vyos_defined }} {% if type_config.default_cost is vyos_defined %} area {{ area_id }} default-cost {{ type_config.default_cost }} {% endif %} diff --git a/data/templates/frr/policy.frr.j2 b/data/templates/frr/policy.frr.j2 index ed5876ae9..c28633f6f 100644 --- a/data/templates/frr/policy.frr.j2 +++ b/data/templates/frr/policy.frr.j2 @@ -252,6 +252,9 @@ route-map {{ route_map }} {{ rule_config.action }} {{ rule }} {% if rule_config.match.rpki is vyos_defined %} match rpki {{ rule_config.match.rpki }} {% endif %} +{% if rule_config.match.source_vrf is vyos_defined %} + match source-vrf {{ rule_config.match.source_vrf }} +{% endif %} {% if rule_config.match.tag is vyos_defined %} match tag {{ rule_config.match.tag }} {% endif %} diff --git a/data/templates/frr/rpki.frr.j2 b/data/templates/frr/rpki.frr.j2 index 59d5bf0ac..e35f99766 100644 --- a/data/templates/frr/rpki.frr.j2 +++ b/data/templates/frr/rpki.frr.j2 @@ -1,24 +1,34 @@ -! +{% macro rpki_config(rpki) %} {# as FRR does not support deleting the entire rpki section we leave it in place even when it's empty #} rpki -{% if cache is vyos_defined %} -{% for peer, peer_config in cache.items() %} +{% if rpki.cache is vyos_defined %} +{% for peer, peer_config in rpki.cache.items() %} {# port is mandatory and preference uses a default value #} {% if peer_config.ssh.username is vyos_defined %} - rpki cache ssh {{ peer | replace('_', '-') }} {{ peer_config.port }} {{ peer_config.ssh.username }} {{ peer_config.ssh.private_key_file }} {{ peer_config.ssh.public_key_file }} preference {{ peer_config.preference }} + rpki cache ssh {{ peer | replace('_', '-') }} {{ peer_config.port }} {{ peer_config.ssh.username }} {{ peer_config.ssh.private_key_file }} {{ peer_config.ssh.public_key_file }}{{ ' source ' ~ peer_config.source_address if peer_config.source_address is vyos_defined }} preference {{ peer_config.preference }} {% else %} - rpki cache tcp {{ peer | replace('_', '-') }} {{ peer_config.port }} preference {{ peer_config.preference }} + rpki cache tcp {{ peer | replace('_', '-') }} {{ peer_config.port }}{{ ' source ' ~ peer_config.source_address if peer_config.source_address is vyos_defined }} preference {{ peer_config.preference }} {% endif %} {% endfor %} {% endif %} -{% if expire_interval is vyos_defined %} - rpki expire_interval {{ expire_interval }} +{% if rpki.expire_interval is vyos_defined %} + rpki expire_interval {{ rpki.expire_interval }} {% endif %} -{% if polling_period is vyos_defined %} - rpki polling_period {{ polling_period }} +{% if rpki.polling_period is vyos_defined %} + rpki polling_period {{ rpki.polling_period }} {% endif %} -{% if retry_interval is vyos_defined %} - rpki retry_interval {{ retry_interval }} +{% if rpki.retry_interval is vyos_defined %} + rpki retry_interval {{ rpki.retry_interval }} {% endif %} exit +{# j2lint: disable=jinja-statements-delimeter #} +{%- endmacro -%} +! +{% if rpki.vrf is vyos_defined %} +vrf {{ rpki.vrf }} + {{ rpki_config(rpki) | indent(width=1) }} +exit-vrf +{% else %} +{{ rpki_config(rpki) }} +{% endif %} ! diff --git a/data/templates/frr/staticd.frr.j2 b/data/templates/frr/staticd.frr.j2 index 90d17ec14..18d300dae 100644 --- a/data/templates/frr/staticd.frr.j2 +++ b/data/templates/frr/staticd.frr.j2 @@ -94,14 +94,14 @@ vrf {{ vrf }} {% if pppoe is vyos_defined %} {% for interface, interface_config in pppoe.items() if interface_config.no_default_route is not vyos_defined %} {{ ip_prefix }} route 0.0.0.0/0 {{ interface }} tag 210 {{ interface_config.default_route_distance if interface_config.default_route_distance is vyos_defined }} -{%- endfor %} +{% endfor %} {% endif %} {# IPv6 routing #} {% if route6 is vyos_defined %} {% for prefix, prefix_config in route6.items() %} {{ static_routes(ipv6_prefix, prefix, prefix_config) }} {# j2lint: disable=jinja-statements-delimeter #} -{%- endfor %} +{% endfor %} {% endif %} {% if vrf is vyos_defined %} exit-vrf diff --git a/data/templates/frr/zebra.route-map.frr.j2 b/data/templates/frr/zebra.route-map.frr.j2 index 70a810f43..0d6d01930 100644 --- a/data/templates/frr/zebra.route-map.frr.j2 +++ b/data/templates/frr/zebra.route-map.frr.j2 @@ -1,6 +1,12 @@ ! {{ 'no ' if disable_forwarding is vyos_defined }}{{ afi }} forwarding ! +{% if import_table is vyos_defined %} +{% for table_num, table_config in import_table.items() %} +ip import-table {{ table_num }} {{ 'distance ' ~ table_config.distance if table_config.distance is vyos_defined }} {{ 'route-map ' ~ table_config.route_map if table_config.route_map is vyos_defined }} +{% endfor %} +{% endif %} +! {% if nht.no_resolve_via_default is vyos_defined %} no {{ afi }} nht resolve-via-default {% endif %} diff --git a/data/templates/frr/zebra.segment_routing.frr.j2 b/data/templates/frr/zebra.segment_routing.frr.j2 index 7b12fcdd0..718d47d8f 100644 --- a/data/templates/frr/zebra.segment_routing.frr.j2 +++ b/data/templates/frr/zebra.segment_routing.frr.j2 @@ -11,6 +11,9 @@ segment-routing {% if locator_config.behavior_usid is vyos_defined %} behavior usid {% endif %} +{% if locator_config.format is vyos_defined %} + format {{ locator_config.format }} +{% endif %} exit ! {% endfor %} diff --git a/data/templates/https/nginx.default.j2 b/data/templates/https/nginx.default.j2 index 51da46946..47280c9f0 100644 --- a/data/templates/https/nginx.default.j2 +++ b/data/templates/https/nginx.default.j2 @@ -48,7 +48,7 @@ server { ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK'; # proxy settings for HTTP API, if enabled; 503, if not - location ~ ^/(retrieve|configure|config-file|image|import-pki|container-image|generate|show|reboot|reset|poweroff|traceroute|docs|openapi.json|redoc|graphql) { + location ~ ^/(retrieve|configure|config-file|image|import-pki|container-image|generate|show|reboot|reset|poweroff|traceroute|info|docs|openapi.json|redoc|graphql|renew) { {% if api is vyos_defined %} proxy_pass http://unix:/run/api.sock; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; diff --git a/data/templates/ids/fastnetmon.j2 b/data/templates/ids/fastnetmon.j2 deleted file mode 100644 index f6f03d0db..000000000 --- a/data/templates/ids/fastnetmon.j2 +++ /dev/null @@ -1,121 +0,0 @@ -# enable this option if you want to send logs to local syslog facility -logging:logging_level = debug -logging:local_syslog_logging = on - -# list of all your networks in CIDR format -networks_list_path = /run/fastnetmon/networks_list - -# list networks in CIDR format which will be not monitored for attacks -white_list_path = /run/fastnetmon/excluded_networks_list - -# Enable/Disable any actions in case of attack -enable_ban = on -enable_ban_ipv6 = on - -## How many packets will be collected from attack traffic -ban_details_records_count = 500 - -## How long (in seconds) we should keep an IP in blocked state -## If you set 0 here it completely disables unban capability -{% if ban_time is vyos_defined %} -ban_time = {{ ban_time }} -{% endif %} - -# Check if the attack is still active, before triggering an unban callback with this option -# If the attack is still active, check each run of the unban watchdog -unban_only_if_attack_finished = on - -# enable per subnet speed meters -# For each subnet, list track speed in bps and pps for both directions -enable_subnet_counters = off - -{% if mode is vyos_defined('mirror') %} -mirror_afpacket = on -{% elif mode is vyos_defined('sflow') %} -sflow = on -{% if sflow.port is vyos_defined %} -sflow_port = {{ sflow.port }} -{% endif %} -{% if sflow.listen_address is vyos_defined %} -sflow_host = {{ sflow.listen_address }} -{% endif %} -{% endif %} - - -process_incoming_traffic = {{ 'on' if direction is vyos_defined and 'in' in direction else 'off' }} -process_outgoing_traffic = {{ 'on' if direction is vyos_defined and 'out' in direction else 'off' }} - -{% if threshold is vyos_defined %} -{% if threshold.general is vyos_defined %} -# General threshold -{% for thr, thr_value in threshold.general.items() %} -{% if thr is vyos_defined('fps') %} -ban_for_flows = on -threshold_flows = {{ thr_value }} -{% elif thr is vyos_defined('mbps') %} -ban_for_bandwidth = on -threshold_mbps = {{ thr_value }} -{% elif thr is vyos_defined('pps') %} -ban_for_pps = on -threshold_pps = {{ thr_value }} -{% endif %} -{% endfor %} -{% endif %} - -{% if threshold.tcp is vyos_defined %} -# TCP threshold -{% for thr, thr_value in threshold.tcp.items() %} -{% if thr is vyos_defined('fps') %} -ban_for_tcp_flows = on -threshold_tcp_flows = {{ thr_value }} -{% elif thr is vyos_defined('mbps') %} -ban_for_tcp_bandwidth = on -threshold_tcp_mbps = {{ thr_value }} -{% elif thr is vyos_defined('pps') %} -ban_for_tcp_pps = on -threshold_tcp_pps = {{ thr_value }} -{% endif %} -{% endfor %} -{% endif %} - -{% if threshold.udp is vyos_defined %} -# UDP threshold -{% for thr, thr_value in threshold.udp.items() %} -{% if thr is vyos_defined('fps') %} -ban_for_udp_flows = on -threshold_udp_flows = {{ thr_value }} -{% elif thr is vyos_defined('mbps') %} -ban_for_udp_bandwidth = on -threshold_udp_mbps = {{ thr_value }} -{% elif thr is vyos_defined('pps') %} -ban_for_udp_pps = on -threshold_udp_pps = {{ thr_value }} -{% endif %} -{% endfor %} -{% endif %} - -{% if threshold.icmp is vyos_defined %} -# ICMP threshold -{% for thr, thr_value in threshold.icmp.items() %} -{% if thr is vyos_defined('fps') %} -ban_for_icmp_flows = on -threshold_icmp_flows = {{ thr_value }} -{% elif thr is vyos_defined('mbps') %} -ban_for_icmp_bandwidth = on -threshold_icmp_mbps = {{ thr_value }} -{% elif thr is vyos_defined('pps') %} -ban_for_icmp_pps = on -threshold_icmp_pps = {{ thr_value }} -{% endif %} -{% endfor %} -{% endif %} - -{% endif %} - -{% if listen_interface is vyos_defined %} -interfaces = {{ listen_interface | join(',') }} -{% endif %} - -{% if alert_script is vyos_defined %} -notify_script_path = {{ alert_script }} -{% endif %} diff --git a/data/templates/ids/fastnetmon_excluded_networks_list.j2 b/data/templates/ids/fastnetmon_excluded_networks_list.j2 deleted file mode 100644 index c88a1c527..000000000 --- a/data/templates/ids/fastnetmon_excluded_networks_list.j2 +++ /dev/null @@ -1,5 +0,0 @@ -{% if excluded_network is vyos_defined %} -{% for net in excluded_network %} -{{ net }} -{% endfor %} -{% endif %} diff --git a/data/templates/ids/fastnetmon_networks_list.j2 b/data/templates/ids/fastnetmon_networks_list.j2 deleted file mode 100644 index 0a0576d2a..000000000 --- a/data/templates/ids/fastnetmon_networks_list.j2 +++ /dev/null @@ -1,5 +0,0 @@ -{% if network is vyos_defined %} -{% for net in network %} -{{ net }} -{% endfor %} -{% endif %} diff --git a/data/templates/ipsec/charon_systemd.conf.j2 b/data/templates/ipsec/charon_systemd.conf.j2 new file mode 100644 index 000000000..368aa1ae3 --- /dev/null +++ b/data/templates/ipsec/charon_systemd.conf.j2 @@ -0,0 +1,18 @@ +# Generated by ${vyos_conf_scripts_dir}/vpn_ipsec.py + +charon-systemd { + + # Section to configure native systemd journal logger, very similar to the + # syslog logger as described in LOGGER CONFIGURATION in strongswan.conf(5). + journal { + + # Loglevel for a specific subsystem. + # <subsystem> = <default> + +{% if log.level is vyos_defined %} + # Default loglevel. + default = {{ log.level }} +{% endif %} + } + +} diff --git a/data/templates/ipsec/ios_profile.j2 b/data/templates/ipsec/ios_profile.j2 index 966fad433..6993f82bf 100644 --- a/data/templates/ipsec/ios_profile.j2 +++ b/data/templates/ipsec/ios_profile.j2 @@ -55,11 +55,9 @@ <!-- The server is authenticated using a certificate --> <key>AuthenticationMethod</key> <string>Certificate</string> -{% if authentication.client_mode.startswith("eap") %} <!-- The client uses EAP to authenticate --> <key>ExtendedAuthEnabled</key> <integer>1</integer> -{% endif %} <!-- The next two dictionaries are optional (as are the keys in them), but it is recommended to specify them as the default is to use 3DES. IMPORTANT: Because only one proposal is sent (even if nothing is configured here) it must match the server configuration --> <key>IKESecurityAssociationParameters</key> @@ -80,9 +78,9 @@ <string>{{ esp_encryption.encryption }}</string> <key>IntegrityAlgorithm</key> <string>{{ esp_encryption.hash }}</string> -{% if esp_encryption.pfs is vyos_defined %} +{% if ike_encryption.dh_group is vyos_defined %} <key>DiffieHellmanGroup</key> - <integer>{{ esp_encryption.pfs }}</integer> + <integer>{{ ike_encryption.dh_group }}</integer> {% endif %} </dict> <!-- Controls whether the client offers Perfect Forward Secrecy (PFS). This should be set to match the server. --> diff --git a/data/templates/ipsec/swanctl/peer.j2 b/data/templates/ipsec/swanctl/peer.j2 index 3a9af2c94..cf0865c88 100644 --- a/data/templates/ipsec/swanctl/peer.j2 +++ b/data/templates/ipsec/swanctl/peer.j2 @@ -68,8 +68,19 @@ rekey_packets = 0 rekey_time = 0s {% endif %} - local_ts = 0.0.0.0/0,::/0 - remote_ts = 0.0.0.0/0,::/0 +{# set default traffic-selectors #} +{% set local_ts = '0.0.0.0/0,::/0' %} +{% set remote_ts = '0.0.0.0/0,::/0' %} +{% if peer_conf.vti.traffic_selector is vyos_defined %} +{% if peer_conf.vti.traffic_selector.local is vyos_defined and peer_conf.vti.traffic_selector.local.prefix is vyos_defined %} +{% set local_ts = peer_conf.vti.traffic_selector.local.prefix | join(',') %} +{% endif %} +{% if peer_conf.vti.traffic_selector.remote is vyos_defined and peer_conf.vti.traffic_selector.remote.prefix is vyos_defined %} +{% set remote_ts = peer_conf.vti.traffic_selector.remote.prefix | join(',') %} +{% endif %} +{% endif %} + local_ts = {{ local_ts }} + remote_ts = {{ remote_ts }} updown = "/etc/ipsec.d/vti-up-down {{ peer_conf.vti.bind }}" {# The key defaults to 0 and will match any policies which similarly do not have a lookup key configuration. #} {# Thus we simply shift the key by one to also support a vti0 interface #} diff --git a/data/templates/ipsec/swanctl/profile.j2 b/data/templates/ipsec/swanctl/profile.j2 index 8519a84f8..6a04b038a 100644 --- a/data/templates/ipsec/swanctl/profile.j2 +++ b/data/templates/ipsec/swanctl/profile.j2 @@ -22,16 +22,16 @@ } {% endif %} children { - dmvpn { + dmvpn-{{ name }}-{{ interface }}-child { esp_proposals = {{ esp | get_esp_ike_cipher(ike) | join(',') }} rekey_time = {{ esp.lifetime }}s rand_time = 540s local_ts = dynamic[gre] remote_ts = dynamic[gre] mode = {{ esp.mode }} -{% if ike.dead_peer_detection.action is vyos_defined %} - dpd_action = {{ ike.dead_peer_detection.action }} -{% endif %} + dpd_action = clear + close_action = none + start_action = none {% if esp.compression is vyos_defined('enable') %} ipcomp = yes {% endif %} diff --git a/data/templates/lldp/vyos.conf.j2 b/data/templates/lldp/vyos.conf.j2 index 4b4228cea..432a7a8e6 100644 --- a/data/templates/lldp/vyos.conf.j2 +++ b/data/templates/lldp/vyos.conf.j2 @@ -4,7 +4,7 @@ configure system platform VyOS configure system description "VyOS {{ version }}" {% if interface is vyos_defined %} {% set tmp = [] %} -{% for iface, iface_options in interface.items() if iface_options.disable is not vyos_defined %} +{% for iface, iface_options in interface.items() %} {% if iface == 'all' %} {% set iface = '*' %} {% endif %} @@ -17,6 +17,15 @@ configure ports {{ iface }} med location elin "{{ iface_options.location.elin }} configure ports {{ iface }} med location coordinate latitude "{{ iface_options.location.coordinate_based.latitude }}" longitude "{{ iface_options.location.coordinate_based.longitude }}" altitude "{{ iface_options.location.coordinate_based.altitude }}m" datum "{{ iface_options.location.coordinate_based.datum }}" {% endif %} {% endif %} +{% set mode = iface_options.mode %} +{% if mode == 'tx' %} +{% set mode = 'tx-only' %} +{% elif mode == 'rx' %} +{% set mode = 'rx-only' %} +{% elif mode == 'rx-tx' %} +{% set mode = 'rx-and-tx' %} +{% endif %} +configure ports {{ iface }} lldp status {{ mode }} {% endfor %} configure system interface pattern "{{ tmp | join(",") }}" {% endif %} diff --git a/data/templates/load-balancing/haproxy.cfg.j2 b/data/templates/load-balancing/haproxy.cfg.j2 index 786ebfb21..62934c612 100644 --- a/data/templates/load-balancing/haproxy.cfg.j2 +++ b/data/templates/load-balancing/haproxy.cfg.j2 @@ -38,9 +38,10 @@ defaults log global mode http option dontlognull - timeout connect 10s - timeout client 50s - timeout server 50s + timeout check {{ timeout.check }}s + timeout connect {{ timeout.connect }}s + timeout client {{ timeout.client }}s + timeout server {{ timeout.server }}s errorfile 400 /etc/haproxy/errors/400.http errorfile 403 /etc/haproxy/errors/403.http errorfile 408 /etc/haproxy/errors/408.http @@ -49,9 +50,29 @@ defaults errorfile 503 /etc/haproxy/errors/503.http errorfile 504 /etc/haproxy/errors/504.http +# Default ACME backend +backend buildin_acme_certbot + server localhost 127.0.0.1:{{ get_default_port('certbot_haproxy') }} + # Frontend {% if service is vyos_defined %} {% for front, front_config in service.items() %} +{% if front_config.redirect_http_to_https is vyos_defined %} +{% set certbot_backend_name = 'certbot_' ~ front ~ '_backend' %} +frontend {{ front }}-http + mode http +{% if front_config.listen_address is vyos_defined %} +{% for address in front_config.listen_address %} + bind {{ address | bracketize_ipv6 }}:80 +{% endfor %} +{% else %} + bind [::]:80 v4v6 +{% endif %} + acl acme_acl path_beg /.well-known/acme-challenge/ + use_backend buildin_acme_certbot if acme_acl + redirect scheme https code 301 if !acme_acl +{% endif %} + frontend {{ front }} {% set ssl_front = [] %} {% if front_config.ssl.certificate is vyos_defined and front_config.ssl.certificate is iterable %} @@ -67,9 +88,6 @@ frontend {{ front }} {% else %} bind [::]:{{ front_config.port }} v4v6 {{ ssl_directive }} {{ ssl_front | join(' ') }} {% endif %} -{% if front_config.redirect_http_to_https is vyos_defined %} - http-request redirect scheme https unless { ssl_fc } -{% endif %} {% if front_config.logging is vyos_defined %} {% for facility, facility_config in front_config.logging.facility.items() %} log /dev/log {{ facility }} {{ facility_config.level }} @@ -93,6 +111,11 @@ frontend {{ front }} http-response set-header {{ header }} '{{ header_config['value'] }}' {% endfor %} {% endif %} +{% if front_config.http_compression is vyos_defined %} + filter compression + compression algo {{ front_config.http_compression.algorithm }} + compression type {{ front_config.http_compression.mime_type | join(' ') }} +{% endif %} {% if front_config.rule is vyos_defined %} {% for rule, rule_config in front_config.rule.items() %} # rule {{ rule }} @@ -129,6 +152,11 @@ frontend {{ front }} default_backend {{ backend }} {% endfor %} {% endif %} +{% if front_config.timeout is vyos_defined %} +{% if front_config.timeout.client is vyos_defined %} + timeout client {{ front_config.timeout.client }}s +{% endif %} +{% endif %} {% endfor %} {% endif %} @@ -226,6 +254,5 @@ backend {{ back }} {% if back_config.timeout.server is vyos_defined %} timeout server {{ back_config.timeout.server }}s {% endif %} - {% endfor %} {% endif %} diff --git a/data/templates/load-balancing/nftables-wlb.j2 b/data/templates/load-balancing/nftables-wlb.j2 new file mode 100644 index 000000000..8afd0c162 --- /dev/null +++ b/data/templates/load-balancing/nftables-wlb.j2 @@ -0,0 +1,64 @@ +#!/usr/sbin/nft -f + +{% if first_install is not vyos_defined %} +delete table ip vyos_wanloadbalance +{% endif %} +table ip vyos_wanloadbalance { + chain wlb_nat_postrouting { + type nat hook postrouting priority srcnat - 1; policy accept; +{% for ifname, health_conf in interface_health.items() if health_state[ifname].if_addr %} +{% if disable_source_nat is not vyos_defined %} +{% set state = health_state[ifname] %} + ct mark {{ state.mark }} oifname {{ ifname }} counter snat to {{ state.if_addr }} +{% endif %} +{% endfor %} + } + + chain wlb_mangle_prerouting { + type filter hook prerouting priority mangle; policy accept; +{% for ifname, health_conf in interface_health.items() %} +{% set state = health_state[ifname] %} +{% if sticky_connections is vyos_defined %} + iifname "{{ ifname }}" ct state new ct mark set {{ state.mark }} +{% endif %} +{% endfor %} +{% if rule is vyos_defined %} +{% for rule_id, rule_conf in rule.items() %} +{% if rule_conf.exclude is vyos_defined %} + {{ rule_conf | wlb_nft_rule(rule_id, exclude=True, action='return') }} +{% else %} +{% set limit = rule_conf.limit is vyos_defined %} + {{ rule_conf | wlb_nft_rule(rule_id, limit=limit, weight=True, health_state=health_state) }} + {{ rule_conf | wlb_nft_rule(rule_id, restore_mark=True) }} +{% endif %} +{% endfor %} +{% endif %} + } + + chain wlb_mangle_output { + type filter hook output priority -150; policy accept; +{% if enable_local_traffic is vyos_defined %} + meta mark != 0x0 counter return + meta l4proto icmp counter return + ip saddr 127.0.0.0/8 ip daddr 127.0.0.0/8 counter return +{% if rule is vyos_defined %} +{% for rule_id, rule_conf in rule.items() %} +{% if rule_conf.exclude is vyos_defined %} + {{ rule_conf | wlb_nft_rule(rule_id, local=True, exclude=True, action='return') }} +{% else %} +{% set limit = rule_conf.limit is vyos_defined %} + {{ rule_conf | wlb_nft_rule(rule_id, local=True, limit=limit, weight=True, health_state=health_state) }} + {{ rule_conf | wlb_nft_rule(rule_id, local=True, restore_mark=True) }} +{% endif %} +{% endfor %} +{% endif %} +{% endif %} + } + +{% for ifname, health_conf in interface_health.items() %} +{% set state = health_state[ifname] %} + chain wlb_mangle_isp_{{ ifname }} { + meta mark set {{ state.mark }} ct mark set {{ state.mark }} counter accept + } +{% endfor %} +} diff --git a/data/templates/load-balancing/wlb.conf.j2 b/data/templates/load-balancing/wlb.conf.j2 deleted file mode 100644 index 7f04d797e..000000000 --- a/data/templates/load-balancing/wlb.conf.j2 +++ /dev/null @@ -1,134 +0,0 @@ -### Autogenerated by load-balancing_wan.py ### - -{% if disable_source_nat is vyos_defined %} -disable-source-nat -{% endif %} -{% if enable_local_traffic is vyos_defined %} -enable-local-traffic -{% endif %} -{% if sticky_connections is vyos_defined %} -sticky-connections inbound -{% endif %} -{% if flush_connections is vyos_defined %} -flush-conntrack -{% endif %} -{% if hook is vyos_defined %} -hook "{{ hook }}" -{% endif %} -{% if interface_health is vyos_defined %} -health { -{% for interface, interface_config in interface_health.items() %} - interface {{ interface }} { -{% if interface_config.failure_count is vyos_defined %} - failure-ct {{ interface_config.failure_count }} -{% endif %} -{% if interface_config.success_count is vyos_defined %} - success-ct {{ interface_config.success_count }} -{% endif %} -{% if interface_config.nexthop is vyos_defined %} - nexthop {{ interface_config.nexthop }} -{% endif %} -{% if interface_config.test is vyos_defined %} -{% for test_rule, test_config in interface_config.test.items() %} - rule {{ test_rule }} { -{% if test_config.type is vyos_defined %} -{% set type_translate = {'ping': 'ping', 'ttl': 'udp', 'user-defined': 'user-defined'} %} - type {{ type_translate[test_config.type] }} { -{% if test_config.ttl_limit is vyos_defined and test_config.type == 'ttl' %} - ttl {{ test_config.ttl_limit }} -{% endif %} -{% if test_config.test_script is vyos_defined and test_config.type == 'user-defined' %} - test-script {{ test_config.test_script }} -{% endif %} -{% if test_config.target is vyos_defined %} - target {{ test_config.target }} -{% endif %} - resp-time {{ test_config.resp_time | int * 1000 }} - } -{% endif %} - } -{% endfor %} -{% endif %} - } -{% endfor %} -} -{% endif %} - -{% if rule is vyos_defined %} -{% for rule, rule_config in rule.items() %} -rule {{ rule }} { -{% if rule_config.exclude is vyos_defined %} - exclude -{% endif %} -{% if rule_config.failover is vyos_defined %} - failover -{% endif %} -{% if rule_config.limit is vyos_defined %} - limit { -{% if rule_config.limit.burst is vyos_defined %} - burst {{ rule_config.limit.burst }} -{% endif %} -{% if rule_config.limit.rate is vyos_defined %} - rate {{ rule_config.limit.rate }} -{% endif %} -{% if rule_config.limit.period is vyos_defined %} - period {{ rule_config.limit.period }} -{% endif %} -{% if rule_config.limit.threshold is vyos_defined %} - thresh {{ rule_config.limit.threshold }} -{% endif %} - } -{% endif %} -{% if rule_config.per_packet_balancing is vyos_defined %} - per-packet-balancing -{% endif %} -{% if rule_config.protocol is vyos_defined %} - protocol {{ rule_config.protocol }} -{% endif %} -{% if rule_config.destination is vyos_defined %} - destination { -{% if rule_config.destination.address is vyos_defined %} - address "{{ rule_config.destination.address }}" -{% endif %} -{% if rule_config.destination.port is vyos_defined %} -{% if '-' in rule_config.destination.port %} - port-ipt "-m multiport --dports {{ rule_config.destination.port | replace('-', ':') }}" -{% elif ',' in rule_config.destination.port %} - port-ipt "-m multiport --dports {{ rule_config.destination.port }}" -{% else %} - port-ipt " --dport {{ rule_config.destination.port }}" -{% endif %} -{% endif %} - } -{% endif %} -{% if rule_config.source is vyos_defined %} - source { -{% if rule_config.source.address is vyos_defined %} - address "{{ rule_config.source.address }}" -{% endif %} -{% if rule_config.source.port is vyos_defined %} -{% if '-' in rule_config.source.port %} - port-ipt "-m multiport --sports {{ rule_config.source.port | replace('-', ':') }}" -{% elif ',' in rule_config.destination.port %} - port-ipt "-m multiport --sports {{ rule_config.source.port }}" -{% else %} - port.ipt " --sport {{ rule_config.source.port }}" -{% endif %} -{% endif %} - } -{% endif %} -{% if rule_config.inbound_interface is vyos_defined %} - inbound-interface {{ rule_config.inbound_interface }} -{% endif %} -{% if rule_config.interface is vyos_defined %} -{% for interface, interface_config in rule_config.interface.items() %} - interface {{ interface }} { -{% if interface_config.weight is vyos_defined %} - weight {{ interface_config.weight }} -{% endif %} - } -{% endfor %} -{% endif %} -} -{% endfor %} -{% endif %} diff --git a/data/templates/login/authorized_keys.j2 b/data/templates/login/authorized_keys.j2 index 695b66abe..5b15f066a 100644 --- a/data/templates/login/authorized_keys.j2 +++ b/data/templates/login/authorized_keys.j2 @@ -1,5 +1,4 @@ ### Automatically generated by system_login.py ### - {% if authentication.public_keys is vyos_defined %} {% for key, key_options in authentication.public_keys.items() %} {# The whitespace after options is wisely chosen #} diff --git a/data/templates/login/authorized_principals.j2 b/data/templates/login/authorized_principals.j2 new file mode 100644 index 000000000..16525e808 --- /dev/null +++ b/data/templates/login/authorized_principals.j2 @@ -0,0 +1,4 @@ +### Automatically generated by system_login.py ### +{% if authentication.principal is vyos_defined %} +{{ '\n'.join(authentication.principal) }} +{% endif %} diff --git a/data/templates/login/motd_vyos_nonproduction.j2 b/data/templates/login/motd_vyos_nonproduction.j2 index 3f10423ff..4b81acc5b 100644 --- a/data/templates/login/motd_vyos_nonproduction.j2 +++ b/data/templates/login/motd_vyos_nonproduction.j2 @@ -2,3 +2,4 @@ --- WARNING: This VyOS system is not a stable long-term support version and is not intended for production use. + diff --git a/data/templates/login/pam_radius_auth.conf.j2 b/data/templates/login/pam_radius_auth.conf.j2 index 75437ca71..f9b8d5e87 100644 --- a/data/templates/login/pam_radius_auth.conf.j2 +++ b/data/templates/login/pam_radius_auth.conf.j2 @@ -9,7 +9,7 @@ {% if address | is_ipv4 %} {% set source_address.ipv4 = address %} {% elif address | is_ipv6 %} -{% set source_address.ipv6 = "[" + address + "]" %} +{% set source_address.ipv6 = address %} {% endif %} {% endfor %} {% endif %} @@ -21,7 +21,7 @@ {% 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 }} {% else %} -[{{ server }}]:{{ options.port }} {{ "%-25s" | format(options.key) }} {{ "%-10s" | format(options.timeout) }} {{ source_address.ipv6 if source_address.ipv6 is vyos_defined }} +{{ server | bracketize_ipv6 }}:{{ options.port }} {{ "%-25s" | format(options.key) }} {{ "%-10s" | format(options.timeout) }} {{ source_address.ipv6 if source_address.ipv6 is vyos_defined }} {% endif %} {% endfor %} {% endif %} diff --git a/data/templates/nhrp/nftables.conf.j2 b/data/templates/nhrp/nftables.conf.j2 deleted file mode 100644 index a0d1f6d4c..000000000 --- a/data/templates/nhrp/nftables.conf.j2 +++ /dev/null @@ -1,17 +0,0 @@ -#!/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/nhrp/opennhrp.conf.j2 b/data/templates/nhrp/opennhrp.conf.j2 deleted file mode 100644 index c040a8f14..000000000 --- a/data/templates/nhrp/opennhrp.conf.j2 +++ /dev/null @@ -1,42 +0,0 @@ -{# j2lint: disable=jinja-variable-format #} -# Created by VyOS - manual changes will be overwritten - -{% if tunnel is vyos_defined %} -{% for name, tunnel_conf in tunnel.items() %} -{% set type = 'spoke' if tunnel_conf.map is vyos_defined or tunnel_conf.dynamic_map is vyos_defined else 'hub' %} -{% set profile_name = profile_map[name] if profile_map is vyos_defined and name in profile_map else '' %} -interface {{ name }} #{{ type }} {{ profile_name }} -{% if tunnel_conf.map is vyos_defined %} -{% for map, map_conf in tunnel_conf.map.items() %} -{% set cisco = ' cisco' if map_conf.cisco is vyos_defined else '' %} -{% set register = ' register' if map_conf.register is vyos_defined else '' %} - map {{ map }} {{ map_conf.nbma_address }}{{ register }}{{ cisco }} -{% endfor %} -{% endif %} -{% if tunnel_conf.dynamic_map is vyos_defined %} -{% for map, map_conf in tunnel_conf.dynamic_map.items() %} - dynamic-map {{ map }} {{ map_conf.nbma_domain_name }} -{% endfor %} -{% endif %} -{% if tunnel_conf.cisco_authentication is vyos_defined %} - cisco-authentication {{ tunnel_conf.cisco_authentication }} -{% endif %} -{% if tunnel_conf.holding_time is vyos_defined %} - holding-time {{ tunnel_conf.holding_time }} -{% endif %} -{% if tunnel_conf.multicast is vyos_defined %} - multicast {{ tunnel_conf.multicast }} -{% endif %} -{% for key in ['non_caching', 'redirect', 'shortcut', 'shortcut_destination'] %} -{% if key in tunnel_conf %} - {{ key | replace("_", "-") }} -{% endif %} -{% endfor %} -{% if tunnel_conf.shortcut_target is vyos_defined %} -{% for target, shortcut_conf in tunnel_conf.shortcut_target.items() %} - shortcut-target {{ target }}{{ ' holding-time ' + shortcut_conf.holding_time if shortcut_conf.holding_time is vyos_defined }} -{% endfor %} -{% endif %} - -{% endfor %} -{% endif %} diff --git a/data/templates/pmacct/uacctd.conf.j2 b/data/templates/pmacct/uacctd.conf.j2 index aae0a0619..d2de80df4 100644 --- a/data/templates/pmacct/uacctd.conf.j2 +++ b/data/templates/pmacct/uacctd.conf.j2 @@ -25,12 +25,6 @@ imt_mem_pools_number: 169 {% set _ = plugin.append('nfprobe['~ nf_server_key ~ ']') %} {% endfor %} {% endif %} -{% if sflow.server is vyos_defined %} -{% for server in sflow.server %} -{% set sf_server_key = 'sf_' ~ server | dot_colon_to_dash %} -{% set _ = plugin.append('sfprobe[' ~ sf_server_key ~ ']') %} -{% endfor %} -{% endif %} {% if disable_imt is not defined %} {% set _ = plugin.append('memory') %} {% endif %} @@ -61,20 +55,3 @@ nfprobe_timeouts[{{ nf_server_key }}]: expint={{ netflow.timeout.expiry_interval {% endfor %} {% endif %} - -{% if sflow.server is vyos_defined %} -# sFlow servers -{% for server, server_config in sflow.server.items() %} -{# # prevent pmacct syntax error when using IPv6 flow collectors #} -{% set sf_server_key = 'sf_' ~ server | dot_colon_to_dash %} -sfprobe_receiver[{{ sf_server_key }}]: {{ server | bracketize_ipv6 }}:{{ server_config.port }} -sfprobe_agentip[{{ sf_server_key }}]: {{ sflow.agent_address }} -{% if sflow.sampling_rate is vyos_defined %} -sampling_rate[{{ sf_server_key }}]: {{ sflow.sampling_rate }} -{% endif %} -{% if sflow.source_address is vyos_defined %} -sfprobe_source_ip[{{ sf_server_key }}]: {{ sflow.source_address | bracketize_ipv6 }} -{% endif %} - -{% endfor %} -{% endif %} diff --git a/data/templates/prometheus/blackbox_exporter.service.j2 b/data/templates/prometheus/blackbox_exporter.service.j2 new file mode 100644 index 000000000..e93030246 --- /dev/null +++ b/data/templates/prometheus/blackbox_exporter.service.j2 @@ -0,0 +1,21 @@ +{% set vrf_command = 'ip vrf exec ' ~ vrf ~ ' runuser -u node_exporter -- ' if vrf is vyos_defined else '' %} +[Unit] +Description=Blackbox Exporter +Documentation=https://github.com/prometheus/blackbox_exporter +After=network.target + +[Service] +{% if vrf is not vyos_defined %} +User=node_exporter +{% endif %} +ExecStart={{ vrf_command }}/usr/sbin/blackbox_exporter \ +{% if listen_address is vyos_defined %} +{% for address in listen_address %} + --web.listen-address={{ address }}:{{ port }} \ +{% endfor %} +{% else %} + --web.listen-address=:{{ port }} \ +{% endif %} + --config.file=/run/blackbox_exporter/config.yml +[Install] +WantedBy=multi-user.target diff --git a/data/templates/prometheus/blackbox_exporter.yml.j2 b/data/templates/prometheus/blackbox_exporter.yml.j2 new file mode 100644 index 000000000..ba2eecd77 --- /dev/null +++ b/data/templates/prometheus/blackbox_exporter.yml.j2 @@ -0,0 +1,23 @@ +modules: +{% if modules is defined and modules.dns is defined and modules.dns.name is defined %} +{% for module_name, module_config in modules.dns.name.items() %} + {{ module_name }}: + prober: dns + timeout: {{ module_config.timeout }}s + dns: + query_name: "{{ module_config.query_name }}" + query_type: "{{ module_config.query_type }}" + preferred_ip_protocol: "{{ module_config.preferred_ip_protocol | replace('v', '') }}" + ip_protocol_fallback: {{ 'true' if module_config.ip_protocol_fallback is vyos_defined else 'false' }} +{% endfor %} +{% endif %} +{% if modules is defined and modules.icmp is vyos_defined and modules.icmp.name is vyos_defined %} +{% for module_name, module_config in modules.icmp.name.items() %} + {{ module_name }}: + prober: icmp + timeout: {{ module_config.timeout }}s + icmp: + preferred_ip_protocol: "{{ module_config.preferred_ip_protocol | replace('v', '') }}" + ip_protocol_fallback: {{ 'true' if module_config.ip_protocol_fallback is vyos_defined else 'false' }} +{% endfor %} +{% endif %}
\ No newline at end of file diff --git a/data/templates/prometheus/node_exporter.service.j2 b/data/templates/prometheus/node_exporter.service.j2 index 62e7e6774..9a943cd75 100644 --- a/data/templates/prometheus/node_exporter.service.j2 +++ b/data/templates/prometheus/node_exporter.service.j2 @@ -9,6 +9,11 @@ After=network.target User=node_exporter {% endif %} ExecStart={{ vrf_command }}/usr/sbin/node_exporter \ +{% if collectors is vyos_defined %} +{% if collectors.textfile is vyos_defined %} + --collector.textfile.directory=/run/node_exporter/collector \ +{% endif %} +{% endif %} {% if listen_address is vyos_defined %} {% for address in listen_address %} --web.listen-address={{ address }}:{{ port }} @@ -16,5 +21,6 @@ ExecStart={{ vrf_command }}/usr/sbin/node_exporter \ {% else %} --web.listen-address=:{{ port }} {% endif %} + [Install] WantedBy=multi-user.target diff --git a/data/templates/router-advert/radvd.conf.j2 b/data/templates/router-advert/radvd.conf.j2 index a83bd03ac..34f8e1f6d 100644 --- a/data/templates/router-advert/radvd.conf.j2 +++ b/data/templates/router-advert/radvd.conf.j2 @@ -57,6 +57,21 @@ interface {{ iface }} { }; {% endfor %} {% endif %} +{% if iface_config.prefix is vyos_defined and "::/64" in iface_config.prefix %} +{% if iface_config.auto_ignore is vyos_defined or iface_config.prefix | count > 1 %} + autoignoreprefixes { +{% if iface_config.auto_ignore is vyos_defined %} +{% for auto_ignore_prefix in (iface_config.auto_ignore + iface_config.prefix | list) | reject("eq", "::/64") | unique %} + {{ auto_ignore_prefix }}; +{% endfor %} +{% else %} +{% for auto_ignore_prefix in iface_config.prefix | reject("eq", "::/64") %} + {{ auto_ignore_prefix }}; +{% endfor %} +{% endif %} + }; +{% endif %} +{% endif %} {% if iface_config.prefix is vyos_defined %} {% for prefix, prefix_options in iface_config.prefix.items() %} prefix {{ prefix }} { diff --git a/data/templates/rsyslog/override.conf.j2 b/data/templates/rsyslog/override.conf.j2 deleted file mode 100644 index 5f6a87edf..000000000 --- a/data/templates/rsyslog/override.conf.j2 +++ /dev/null @@ -1,11 +0,0 @@ -{% set vrf_command = 'ip vrf exec ' ~ vrf ~ ' ' if vrf is vyos_defined else '' %} -[Unit] -StartLimitIntervalSec=0 - -[Service] -ExecStart= -ExecStart={{ vrf_command }}/usr/sbin/rsyslogd -n -iNONE -Restart=always -RestartPreventExitStatus= -RestartSec=10 -RuntimeDirectoryPreserve=yes diff --git a/data/templates/rsyslog/rsyslog.conf.j2 b/data/templates/rsyslog/rsyslog.conf.j2 index 253a4bee2..6ef2afcaf 100644 --- a/data/templates/rsyslog/rsyslog.conf.j2 +++ b/data/templates/rsyslog/rsyslog.conf.j2 @@ -1,78 +1,121 @@ ### Autogenerated by system_syslog.py ### -{% if global.marker is vyos_defined %} -$ModLoad immark -{% if global.marker.interval is vyos_defined %} -$MarkMessagePeriod {{ global.marker.interval }} -{% endif %} -{% endif %} -{% if global.preserve_fqdn is vyos_defined %} -$PreserveFQDN on -{% endif %} +#### MODULES #### +# Load input modules for local logging and journald -{% if global.local_host_name is vyos_defined %} -$LocalHostName {{ global.local_host_name }} -{% endif %} +# Old-style log file format with low-precision timestamps +# A modern-style logfile format with high-precision timestamps and timezone info +# RSYSLOG_FileFormat +module(load="builtin:omfile" Template="RSYSLOG_TraditionalFileFormat") +module(load="imuxsock") # provides support for local system logging (collection from /dev/log unix socket) -# We always log to /var/log/messages -$outchannel global,/var/log/messages,262144,/usr/sbin/logrotate {{ logrotate }} -{% if global.facility is vyos_defined %} -{% set tmp = [] %} -{% for facility, facility_options in global.facility.items() %} -{% set _ = tmp.append(facility.replace('all', '*') + '.' + facility_options.level.replace('all', '*')) %} -{% endfor %} -{{ tmp | join(';') }} :omfile:$global +# Import logs from journald, which includes kernel log messages +module( + load="imjournal" + StateFile="/var/spool/rsyslog/imjournal.state" # Persistent state file to track the journal cursor + Ratelimit.Interval="0" # Disable rate limiting (set to "0" for no limit) + RateLimit.Burst="0" +) + +########################### +#### GLOBAL DIRECTIVES #### +########################### +# Log specific programs to auth.log, then stop further processing +if ( + $programname == "CRON" or + $programname == "sudo" or + $programname == "su" +) then { + action(type="omfile" file="/var/log/auth.log") + stop +} + +global(workDirectory="/var/spool/rsyslog") + +############### +#### RULES #### +############### + +# Send emergency messages to all logged-in users +*.emerg action(type="omusrmsg" users="*") + +{% if marker is vyos_defined and marker.disable is not vyos_defined %} +# Load the immark module for periodic --MARK-- message capability +module(load="immark" interval="{{ marker.interval }}") +{% endif %} +{% if preserve_fqdn is vyos_defined %} +# Preserve the fully qualified domain name (FQDN) in log messages +global(preserveFQDN="on") +{% if preserve_fqdn.host_name is vyos_defined and preserve_fqdn.domain_name is vyos_defined %} +# Set the local hostname for log messages +global(localHostname="{{ preserve_fqdn.host_name }}.{{ preserve_fqdn.domain_name }}") +{% endif %} {% endif %} -{% if file is vyos_defined %} -# File based configuration section -{% for file_name, file_options in file.items() %} -{% set tmp = [] %} -$outchannel {{ file_name }},/var/log/user/{{ file_name }},{{ file_options.archive.size }},/usr/sbin/logrotate {{ logrotate }} -{% if file_options.facility is vyos_defined %} -{% for facility, facility_options in file_options.facility.items() %} -{% set _ = tmp.append(facility.replace('all', '*') + '.' + facility_options.level.replace('all', '*')) %} -{% endfor %} -{% endif %} -{{ tmp | join(';') }} :omfile:${{ file }} -{% endfor %} +#### GLOBAL LOGGING #### +{% if local.facility is vyos_defined %} +{% set tmp = [] %} +{% if local.facility is vyos_defined %} +{% for facility, facility_options in local.facility.items() %} +{% set _ = tmp.append(facility.replace('all', '*') ~ "." ~ facility_options.level.replace('all', 'debug')) %} +{% endfor %} +if prifilt("{{ tmp | join(',') }}") then { + action( + type="omfile" + file="/var/log/messages" + rotation.sizeLimit="524288" # 512Kib - maximum filesize before rotation + rotation.sizeLimitCommand="/usr/sbin/logrotate {{ logrotate }}" + ) +} +{% endif %} {% endif %} +#### CONSOLE LOGGING #### {% if console.facility is vyos_defined %} -# Console logging {% set tmp = [] %} -{% for facility, facility_options in console.facility.items() %} -{% set _ = tmp.append(facility.replace('all', '*') + '.' + facility_options.level.replace('all', '*')) %} -{% endfor %} -{{ tmp | join(';') }} /dev/console +{% if console.facility is vyos_defined %} +{% for facility, facility_options in console.facility.items() %} +{% set _ = tmp.append(facility.replace('all', '*') ~ "." ~ facility_options.level.replace('all', 'debug')) %} +{% endfor %} +if prifilt("{{ tmp | join(',') }}") then { + action(type="omfile" file="/dev/console") +} +{% endif %} {% endif %} -{% if host is vyos_defined %} -# Remote logging -{% for host_name, host_options in host.items() %} +#### REMOTE LOGGING #### +{% if remote is vyos_defined %} +{% for remote_name, remote_options in remote.items() %} {% set tmp = [] %} -{% if host_options.facility is vyos_defined %} -{% for facility, facility_options in host_options.facility.items() %} -{% set _ = tmp.append(facility.replace('all', '*') + '.' + facility_options.level.replace('all', '*')) %} +{% if remote_options.facility is vyos_defined %} +{% for facility, facility_options in remote_options.facility.items() %} +{% set _ = tmp.append(facility.replace('all', '*') ~ "." ~ facility_options.level.replace('all', 'debug')) %} {% endfor %} -{% endif %} -{% if host_options.protocol is vyos_defined('tcp') %} -{{ tmp | join(';') }} @@{{ '(o)' if host_options.format.octet_counted is vyos_defined }}{{ host_name | bracketize_ipv6 }}:{{ host_options.port }}{{ ';RSYSLOG_SyslogProtocol23Format' if host_options.format.include_timezone is vyos_defined }} -{% else %} -{{ tmp | join(';') }} @{{ host_name | bracketize_ipv6 }}:{{ host_options.port }}{{ ';RSYSLOG_SyslogProtocol23Format' if host_options.format.include_timezone is vyos_defined }} +{% set _ = tmp.sort() %} +# Remote syslog to {{ remote_name }} +if prifilt("{{ tmp | join(',') }}") then { + action( + type="omfwd" + # Remote syslog server where we send our logs to + target="{{ remote_name }}" + # Port on the remote syslog server + port="{{ remote_options.port }}" + protocol="{{ remote_options.protocol }}" +{% if remote_options.format.include_timezone is vyos_defined %} + template="RSYSLOG_SyslogProtocol23Format" +{% endif %} + TCP_Framing="{{ 'octet-counted' if remote_options.format.octet_counted is vyos_defined else 'traditional' }}" +{% if remote_options.source_address is vyos_defined %} + Address="{{ remote_options.source_address }}" +{% endif %} +{% if remote_options.vrf is vyos_defined %} + Device="{{ remote_options.vrf }}" +{% endif %} + ) +} {% endif %} {% endfor %} {% endif %} -{% if user is defined and user is not none %} -# Log to user terminal -{% for username, user_options in user.items() %} -{% set tmp = [] %} -{% if user_options.facility is vyos_defined %} -{% for facility, facility_options in user_options.facility.items() %} -{% set _ = tmp.append(facility.replace('all', '*') + '.' + facility_options.level.replace('all', '*')) %} -{% endfor %} -{% endif %} -{{ tmp | join(';') }} :omusrmsg:{{ username }} -{% endfor %} -{% endif %} +# Include all configuration files in /etc/rsyslog.d/ +include(file="/etc/rsyslog.d/*.conf") diff --git a/data/templates/sflow/hsflowd.conf.j2 b/data/templates/sflow/hsflowd.conf.j2 index 5000956bd..6a1ba2956 100644 --- a/data/templates/sflow/hsflowd.conf.j2 +++ b/data/templates/sflow/hsflowd.conf.j2 @@ -25,6 +25,9 @@ sflow { pcap { dev={{ iface }} } {% endfor %} {% endif %} +{% if enable_egress is vyos_defined %} + psample { group=1 egress=on } +{% endif %} {% if drop_monitor_limit is vyos_defined %} dropmon { limit={{ drop_monitor_limit }} start=on sw=on hw=off } {% endif %} diff --git a/data/templates/squid/squid.conf.j2 b/data/templates/squid/squid.conf.j2 index b953c8b18..4e3d702a8 100644 --- a/data/templates/squid/squid.conf.j2 +++ b/data/templates/squid/squid.conf.j2 @@ -30,6 +30,14 @@ acl BLOCKDOMAIN dstdomain {{ domain }} {% endfor %} http_access deny BLOCKDOMAIN {% endif %} + +{% if domain_noncache is vyos_defined %} +{% for domain in domain_noncache %} +acl NOCACHE dstdomain {{ domain }} +{% endfor %} +no_cache deny NOCACHE +{% endif %} + {% if authentication is vyos_defined %} {% if authentication.children is vyos_defined %} auth_param basic children {{ authentication.children }} diff --git a/data/templates/ssh/sshd_config.j2 b/data/templates/ssh/sshd_config.j2 index 7e44efae8..1315bf2cb 100644 --- a/data/templates/ssh/sshd_config.j2 +++ b/data/templates/ssh/sshd_config.j2 @@ -111,6 +111,18 @@ ClientAliveInterval {{ client_keepalive_interval }} RekeyLimit {{ rekey.data }}M {{ rekey.time + 'M' if rekey.time is vyos_defined }} {% endif %} -{% if trusted_user_ca_key is vyos_defined %} -TrustedUserCAKeys /etc/ssh/trusted_user_ca_key +{% if trusted_user_ca is vyos_defined %} +# Specifies a file containing public keys of certificate authorities that are +# trusted to sign user certificates for authentication +TrustedUserCAKeys {{ get_default_config_file('sshd_user_ca') }} + +# The default is "none", i.e. not to use a principals file - in this case, the +# username of the user must appear in a certificate's principals list for it +# to be accepted. ".ssh/authorized_principals" means a per-user configuration, +# relative to $HOME. +{% set filename = 'none' %} +{% if has_principals is vyos_defined %} +{% set filename = '.ssh/authorized_principals' %} +{% endif %} +AuthorizedPrincipalsFile {{ filename }} {% endif %} diff --git a/data/templates/telegraf/syslog_telegraf.j2 b/data/templates/telegraf/syslog_telegraf.j2 index cdcbd92a4..4fe6382ab 100644 --- a/data/templates/telegraf/syslog_telegraf.j2 +++ b/data/templates/telegraf/syslog_telegraf.j2 @@ -2,4 +2,8 @@ $ModLoad omuxsock $OMUxSockSocket /run/telegraf/telegraf_syslog.sock +{% if telegraf.loki is vyos_defined or telegraf.splunk is vyos_defined %} +*.info;*.notice :omuxsock: +{% else %} *.notice :omuxsock: +{% endif %} diff --git a/data/templates/telegraf/telegraf.j2 b/data/templates/telegraf/telegraf.j2 index 535e3a347..043fc6878 100644 --- a/data/templates/telegraf/telegraf.j2 +++ b/data/templates/telegraf/telegraf.j2 @@ -52,7 +52,7 @@ password = "{{ loki.authentication.password }}" {% endif %} {% if loki.metric_name_label is vyos_defined %} -metric_name_label = "{{ loki.metric_name_label }}" + metric_name_label = "{{ loki.metric_name_label }}" {% endif %} ### End Loki ### {% endif %} |