summaryrefslogtreecommitdiff
path: root/data
diff options
context:
space:
mode:
authorNicolas Vandamme <n.vandamme@firis-system.lu>2025-09-01 17:24:26 +0200
committerGitHub <noreply@github.com>2025-09-01 17:24:26 +0200
commita791cc3b7bb28081a6e79a988964f1fc51a47dae (patch)
treeef5e734bf580f1abfd7d3d4ea30240d8d9fb1278 /data
parentb9f60711392463af1892a30472fba6622a73390a (diff)
parentb1b4545cb7984cd3cdf42554ab2b28acd1ecb6cb (diff)
downloadvyos-1x-a791cc3b7bb28081a6e79a988964f1fc51a47dae.tar.gz
vyos-1x-a791cc3b7bb28081a6e79a988964f1fc51a47dae.zip
Merge branch 'vyos:current' into current
Diffstat (limited to 'data')
-rw-r--r--data/config-mode-dependencies/vyos-1x.json7
-rw-r--r--data/config-mode-dependencies/vyos-vpp.json69
-rw-r--r--data/config.boot.default10
-rw-r--r--data/op-mode-standardized.json2
-rw-r--r--data/templates/accel-ppp/chap-secrets.ipoe.j22
-rw-r--r--data/templates/accel-ppp/pppoe.config.j25
-rw-r--r--data/templates/aws/override_aws_gwlbtun.conf.j24
-rw-r--r--data/templates/conntrack/nftables-ct.j232
-rw-r--r--data/templates/conntrack/sysctl.conf.j23
-rw-r--r--data/templates/conntrack/vyos_nf_conntrack.conf.j22
-rw-r--r--data/templates/conserver/dropbear@.service.j22
-rw-r--r--data/templates/container/containers.conf.j24
-rw-r--r--data/templates/container/registries.conf.j210
-rw-r--r--data/templates/dhcp-client/ipv6.override.conf.j23
-rw-r--r--data/templates/dhcp-server/kea-ctrl-agent.conf.j214
-rw-r--r--data/templates/dhcp-server/kea-dhcp-ddns.conf.j235
-rw-r--r--data/templates/dhcp-server/kea-dhcp4.conf.j242
-rw-r--r--data/templates/dhcp-server/kea-dhcp6.conf.j25
-rw-r--r--data/templates/firewall/nftables-defines.j220
-rw-r--r--data/templates/firewall/nftables-geoip-update.j233
-rw-r--r--data/templates/firewall/nftables-policy.j217
-rw-r--r--data/templates/firewall/nftables-zone.j236
-rwxr-xr-xdata/templates/firewall/nftables.j252
-rw-r--r--data/templates/frr/bgpd.frr.j212
-rw-r--r--data/templates/frr/daemons.frr.tmpl1
-rw-r--r--data/templates/frr/isisd.frr.j25
-rw-r--r--data/templates/frr/ldpd.frr.j210
-rw-r--r--data/templates/frr/nhrpd.frr.j22
-rw-r--r--data/templates/frr/ospfd.frr.j22
-rw-r--r--data/templates/frr/policy.frr.j23
-rw-r--r--data/templates/frr/rpki.frr.j232
-rw-r--r--data/templates/frr/staticd.frr.j24
-rw-r--r--data/templates/frr/zebra.route-map.frr.j26
-rw-r--r--data/templates/https/nginx.default.j22
-rw-r--r--data/templates/ids/fastnetmon.j2121
-rw-r--r--data/templates/ids/fastnetmon_excluded_networks_list.j25
-rw-r--r--data/templates/ids/fastnetmon_networks_list.j25
-rw-r--r--data/templates/ipsec/charon.j219
-rw-r--r--data/templates/ipsec/charon_systemd.conf.j218
-rw-r--r--data/templates/ipsec/ios_profile.j26
-rw-r--r--data/templates/ipsec/swanctl.conf.j28
-rw-r--r--data/templates/ipsec/swanctl/l2tp.j25
-rw-r--r--data/templates/ipsec/swanctl/peer.j226
-rw-r--r--data/templates/ipsec/swanctl/profile.j25
-rw-r--r--data/templates/lldp/vyos.conf.j211
-rw-r--r--data/templates/load-balancing/haproxy.cfg.j257
-rw-r--r--data/templates/load-balancing/nftables-wlb.j264
-rw-r--r--data/templates/load-balancing/wlb.conf.j2134
-rw-r--r--data/templates/login/authorized_keys.j21
-rw-r--r--data/templates/login/authorized_principals.j24
-rw-r--r--data/templates/login/motd_vyos_nonproduction.j21
-rw-r--r--data/templates/prometheus/node_exporter.service.j211
-rw-r--r--data/templates/router-advert/radvd.conf.j215
-rw-r--r--data/templates/rsyslog/override.conf.j211
-rw-r--r--data/templates/rsyslog/rsyslog.conf.j2163
-rw-r--r--data/templates/sflow/hsflowd.conf.j23
-rw-r--r--data/templates/squid/squid.conf.j28
-rw-r--r--data/templates/ssh/sshd_config.j216
-rw-r--r--data/templates/vpp/override.conf.j214
-rw-r--r--data/templates/vpp/startup.conf.j2209
-rw-r--r--data/vyos-firewall-init.conf4
61 files changed, 951 insertions, 481 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-mode-dependencies/vyos-vpp.json b/data/config-mode-dependencies/vyos-vpp.json
new file mode 100644
index 000000000..32b53508e
--- /dev/null
+++ b/data/config-mode-dependencies/vyos-vpp.json
@@ -0,0 +1,69 @@
+{
+ "vpp": {
+ "ethernet": ["interfaces_ethernet"],
+ "vpp_interfaces_bonding": ["vpp_interfaces_bonding"],
+ "vpp_interfaces_bridge": ["vpp_interfaces_bridge"],
+ "vpp_interfaces_ethernet": ["vpp_interfaces_ethernet"],
+ "vpp_interfaces_geneve": ["vpp_interfaces_geneve"],
+ "vpp_interfaces_gre": ["vpp_interfaces_gre"],
+ "vpp_interfaces_ipip": ["vpp_interfaces_ipip"],
+ "vpp_interfaces_loopback": ["vpp_interfaces_loopback"],
+ "vpp_interfaces_vxlan": ["vpp_interfaces_vxlan"],
+ "vpp_interfaces_xconnect": ["vpp_interfaces_xconnect"],
+ "vpp_acl": ["vpp_acl"],
+ "vpp_nat": ["vpp_nat"],
+ "vpp_nat_cgnat": ["vpp_nat_cgnat"],
+ "vpp_kernel_interface": ["vpp_kernel-interfaces"],
+ "vpp_sflow": ["vpp_sflow"]
+ },
+ "vpp_interfaces_bonding": {
+ "vpp_interfaces_xconnect": ["vpp_interfaces_xconnect"],
+ "vpp_acl": ["vpp_acl"],
+ "vpp_nat": ["vpp_nat"],
+ "vpp_nat_cgnat": ["vpp_nat_cgnat"],
+ "vpp_kernel_interface": ["vpp_kernel-interfaces"]
+ },
+ "vpp_interfaces_ethernet": {
+ "vpp_interfaces_xconnect": ["vpp_interfaces_xconnect"],
+ "vpp_acl": ["vpp_acl"],
+ "vpp_nat": ["vpp_nat"],
+ "vpp_nat_cgnat": ["vpp_nat_cgnat"],
+ "vpp_kernel_interface": ["vpp_kernel-interfaces"]
+ },
+ "vpp_interfaces_geneve": {
+ "vpp_interfaces_xconnect": ["vpp_interfaces_xconnect"],
+ "vpp_acl": ["vpp_acl"],
+ "vpp_nat": ["vpp_nat"],
+ "vpp_nat_cgnat": ["vpp_nat_cgnat"],
+ "vpp_kernel_interface": ["vpp_kernel-interfaces"]
+ },
+ "vpp_interfaces_gre": {
+ "vpp_interfaces_xconnect": ["vpp_interfaces_xconnect"],
+ "vpp_acl": ["vpp_acl"],
+ "vpp_nat": ["vpp_nat"],
+ "vpp_nat_cgnat": ["vpp_nat_cgnat"],
+ "vpp_kernel_interface": ["vpp_kernel-interfaces"]
+ },
+ "vpp_interfaces_ipip": {
+ "vpp_interfaces_xconnect": ["vpp_interfaces_xconnect"],
+ "vpp_acl": ["vpp_acl"],
+ "vpp_nat": ["vpp_nat"],
+ "vpp_nat_cgnat": ["vpp_nat_cgnat"],
+ "vpp_kernel_interface": ["vpp_kernel-interfaces"]
+ },
+ "vpp_interfaces_loopback": {
+ "vpp_acl": ["vpp_acl"],
+ "vpp_nat": ["vpp_nat"],
+ "vpp_nat_cgnat": ["vpp_nat_cgnat"],
+ "vpp_kernel_interface": ["vpp_kernel-interfaces"]
+ },
+ "vpp_interfaces_vxlan": {
+ "vpp_interfaces_bridge": ["vpp_interfaces_bridge"],
+ "vpp_interfaces_xconnect": ["vpp_interfaces_xconnect"],
+ "vpp_acl": ["vpp_acl"],
+ "vpp_nat": ["vpp_nat"],
+ "vpp_nat_cgnat": ["vpp_nat_cgnat"],
+ "vpp_kernel_interface": ["vpp_kernel-interfaces"]
+ }
+}
+
diff --git a/data/config.boot.default b/data/config.boot.default
index 93369d9b7..cee350bad 100644
--- a/data/config.boot.default
+++ b/data/config.boot.default
@@ -33,6 +33,11 @@ system {
}
host-name "vyos"
login {
+ operator-group default {
+ command-policy {
+ allow "*"
+ }
+ }
user vyos {
authentication {
encrypted-password "$6$QxPS.uk6mfo$9QBSo8u1FkH16gMyAVhus6fU3LOzvLR9Z9.82m3tiHFAxTtIkhaZSWssSgzt4v4dGAL8rhVQxTg0oAG9/q11h/"
@@ -40,8 +45,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 170f0d259..5d3f4a249 100644
--- a/data/op-mode-standardized.json
+++ b/data/op-mode-standardized.json
@@ -13,6 +13,7 @@
"evpn.py",
"interfaces.py",
"ipsec.py",
+"load-balancing_wan.py",
"lldp.py",
"log.py",
"memory.py",
@@ -27,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/accel-ppp/pppoe.config.j2 b/data/templates/accel-ppp/pppoe.config.j2
index 2c4871a6b..8884fb87f 100644
--- a/data/templates/accel-ppp/pppoe.config.j2
+++ b/data/templates/accel-ppp/pppoe.config.j2
@@ -55,14 +55,15 @@ verbose=1
ac-name={{ access_concentrator }}
{% if interface is vyos_defined %}
{% for iface, iface_config in interface.items() %}
+{% set vpp_cp_opt = ',vpp-cp=true' if iface_config.vpp_cp is vyos_defined else '' %}
{% if iface_config.vlan is not vyos_defined %}
-interface={{ iface }}
+interface={{ iface }}{{ vpp_cp_opt }}
{% else %}
{% for vlan in iface_config.vlan %}
interface=re:^{{ iface }}\.{{ vlan | range_to_regex }}$
{% endfor %}
{% if iface_config.combined is vyos_defined %}
-interface={{ iface }}
+interface={{ iface }}{{ vpp_cp_opt }}
{% endif %}
{% if iface_config.vlan_mon is vyos_defined %}
vlan-mon={{ iface }},{{ iface_config.vlan | join(',') }}
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/nftables-ct.j2 b/data/templates/conntrack/nftables-ct.j2
index c753e6bcb..9169c1f55 100644
--- a/data/templates/conntrack/nftables-ct.j2
+++ b/data/templates/conntrack/nftables-ct.j2
@@ -16,17 +16,15 @@ table ip vyos_conntrack {
{% endif %}
return
}
- chain VYOS_CT_TIMEOUT {
{% if timeout.custom.ipv4.rule is vyos_defined %}
+ chain VYOS_CT_TIMEOUT {
{% for rule, rule_config in timeout.custom.ipv4.rule.items() %}
# rule-{{ rule }} {{ '- ' ~ rule_config.description if rule_config.description is vyos_defined }}
{{ rule_config | conntrack_rule(rule, 'timeout', ipv6=False) }}
{% endfor %}
-{% endif %}
return
}
-{% if timeout.custom.ipv4.rule is vyos_defined %}
{% for rule, rule_config in timeout.custom.ipv4.rule.items() %}
ct timeout ct-timeout-{{ rule }} {
l3proto ip;
@@ -36,12 +34,21 @@ table ip vyos_conntrack {
{% endfor %}
}
{% endfor %}
+
+ chain PREROUTING_CT_TIMEOUT {
+ type filter hook prerouting priority -199; policy accept;
+ counter jump VYOS_CT_TIMEOUT
+ }
+
+ chain OUTPUT_CT_TIMEOUT {
+ type filter hook output priority -199; policy accept;
+ counter jump VYOS_CT_TIMEOUT
+ }
{% endif %}
chain PREROUTING {
type filter hook prerouting priority -300; policy accept;
counter jump VYOS_CT_IGNORE
- counter jump VYOS_CT_TIMEOUT
counter jump FW_CONNTRACK
counter jump NAT_CONNTRACK
counter jump WLB_CONNTRACK
@@ -58,7 +65,6 @@ table ip vyos_conntrack {
chain OUTPUT {
type filter hook output priority -300; policy accept;
counter jump VYOS_CT_IGNORE
- counter jump VYOS_CT_TIMEOUT
counter jump FW_CONNTRACK
counter jump NAT_CONNTRACK
{% if wlb_local_action %}
@@ -106,17 +112,15 @@ table ip6 vyos_conntrack {
{% endif %}
return
}
- chain VYOS_CT_TIMEOUT {
{% if timeout.custom.ipv6.rule is vyos_defined %}
+ chain VYOS_CT_TIMEOUT {
{% for rule, rule_config in timeout.custom.ipv6.rule.items() %}
# rule-{{ rule }} {{ '- ' ~ rule_config.description if rule_config.description is vyos_defined }}
{{ rule_config | conntrack_rule(rule, 'timeout', ipv6=True) }}
{% endfor %}
-{% endif %}
return
}
-{% if timeout.custom.ipv6.rule is vyos_defined %}
{% for rule, rule_config in timeout.custom.ipv6.rule.items() %}
ct timeout ct-timeout-{{ rule }} {
l3proto ip;
@@ -126,12 +130,21 @@ table ip6 vyos_conntrack {
{% endfor %}
}
{% endfor %}
+
+ chain PREROUTING_CT_TIMEOUT {
+ type filter hook prerouting priority -199; policy accept;
+ counter jump VYOS_CT_TIMEOUT
+ }
+
+ chain OUTPUT_CT_TIMEOUT {
+ type filter hook output priority -199; policy accept;
+ counter jump VYOS_CT_TIMEOUT
+ }
{% endif %}
chain PREROUTING {
type filter hook prerouting priority -300; policy accept;
counter jump VYOS_CT_IGNORE
- counter jump VYOS_CT_TIMEOUT
counter jump FW_CONNTRACK
counter jump NAT_CONNTRACK
notrack
@@ -147,7 +160,6 @@ table ip6 vyos_conntrack {
chain OUTPUT {
type filter hook output priority -300; policy accept;
counter jump VYOS_CT_IGNORE
- counter jump VYOS_CT_TIMEOUT
counter jump FW_CONNTRACK
counter jump NAT_CONNTRACK
notrack
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/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..e734a37f3
--- /dev/null
+++ b/data/templates/dhcp-server/kea-dhcp-ddns.conf.j2
@@ -0,0 +1,35 @@
+{
+ "DhcpDdns": {
+ "ip-address": "127.0.0.1",
+ "port": 53001,
+ "control-socket": {
+{% if vrf_context is vyos_defined %}
+ "socket-type": "unix",
+ "socket-name": "/run/kea/kea-ddns-{{ vrf_context }}-ctrl-socket"
+{% else %}
+ "socket-type": "unix",
+ "socket-name": "/run/kea/kea-ddns-ctrl-socket"
+{% endif %}
+ },
+ "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..60c9cf9b2 100644
--- a/data/templates/dhcp-server/kea-dhcp4.conf.j2
+++ b/data/templates/dhcp-server/kea-dhcp4.conf.j2
@@ -15,8 +15,13 @@
"service-sockets-retry-wait-time": 5000
},
"control-socket": {
+{% if vrf_context is vyos_defined %}
+ "socket-type": "unix",
+ "socket-name": "/run/kea/dhcp4-{{ vrf_context }}-ctrl-socket"
+{% else %}
"socket-type": "unix",
"socket-name": "/run/kea/dhcp4-ctrl-socket"
+{% endif %}
},
"lease-database": {
"type": "memfile",
@@ -25,20 +30,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 +41,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 +73,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/dhcp-server/kea-dhcp6.conf.j2 b/data/templates/dhcp-server/kea-dhcp6.conf.j2
index 4745d693c..4352bbae7 100644
--- a/data/templates/dhcp-server/kea-dhcp6.conf.j2
+++ b/data/templates/dhcp-server/kea-dhcp6.conf.j2
@@ -10,8 +10,13 @@
"service-sockets-retry-wait-time": 5000
},
"control-socket": {
+{% if vrf_context is vyos_defined %}
+ "socket-type": "unix",
+ "socket-name": "/run/kea/dhcp6-{{ vrf_context }}-ctrl-socket"
+{% else %}
"socket-type": "unix",
"socket-name": "/run/kea/dhcp6-ctrl-socket"
+{% endif %}
},
"lease-database": {
"type": "memfile",
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 645a38706..66f7e0b1c 100644
--- a/data/templates/firewall/nftables-zone.j2
+++ b/data/templates/firewall/nftables-zone.j2
@@ -9,11 +9,11 @@
{% for zone_name, zone_conf in zone.items() %}
{% if 'local_zone' not in zone_conf %}
{% if 'interface' in zone_conf.member %}
- oifname { {{ zone_conf.member.interface | join(',') }} } counter jump VZONE_{{ zone_name }}
+ 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 }}
+ oifname { "{{ zone_conf['vrf_interfaces'][vrf_name] }}" } counter jump VZONE_{{ zone_name }}
{% endfor %}
{% endif %}
{% endif %}
@@ -49,12 +49,12 @@
{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall[fw_name] is vyos_defined %}
{% if 'interface' in zone[from_zone].member %}
- iifname { {{ zone[from_zone].member.interface | join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
- iifname { {{ zone[from_zone].member.interface | join(",") }} } counter return
+ 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 | join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
- iifname { {{ zone[from_zone].member.vrf | join(",") }} } counter return
+ 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 %}
@@ -65,13 +65,13 @@
{% 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 %}
{% if 'interface' in zone[from_zone].member %}
- oifname { {{ zone[from_zone].member.interface | join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
- oifname { {{ zone[from_zone].member.interface | join(",") }} } counter return
+ 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
+ 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 %}
@@ -81,29 +81,29 @@
{% else %}
chain VZONE_{{ zone_name }} {
{% if 'interface' in zone_conf.member %}
- iifname { {{ zone_conf.member.interface | join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6) }}
+ 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 | join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6) }}
+ 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 %}
{% if 'interface' in zone_conf.member %}
- iifname { {{ zone_conf.member.interface | join(",") }} } counter return
+ iifname { {{ zone_conf.member.interface | quoted_join(",") }} } counter return
{% endif %}
{% if 'vrf' in zone_conf.member %}
- iifname { {{ zone_conf.member.vrf | join(",") }} } counter return
+ 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 %}
{% if 'interface' in zone[from_zone].member %}
- iifname { {{ zone[from_zone].member.interface | join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
- iifname { {{ zone[from_zone].member.interface | join(",") }} } counter return
+ 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 | join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }}
- iifname { {{ zone[from_zone].member.vrf | join(",") }} } counter return
+ 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 %}
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 835dc382b..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.
#
diff --git a/data/templates/frr/isisd.frr.j2 b/data/templates/frr/isisd.frr.j2
index eb14aade6..a4ea28942 100644
--- a/data/templates/frr/isisd.frr.j2
+++ b/data/templates/frr/isisd.frr.j2
@@ -130,6 +130,11 @@ advertise-passive-only
{% if segment_routing.maximum_label_depth is vyos_defined %}
segment-routing node-msd {{ segment_routing.maximum_label_depth }}
{% endif %}
+{% if segment_routing.srv6.locator is vyos_defined %}
+ segment-routing srv6
+ locator {{ segment_routing.srv6.locator }}
+ exit
+{% endif %}
{% if segment_routing.global_block is vyos_defined %}
{% if segment_routing.local_block is vyos_defined %}
segment-routing global-block {{ segment_routing.global_block.low_label_value }} {{ segment_routing.global_block.high_label_value }} local-block {{ segment_routing.local_block.low_label_value }} {{ segment_routing.local_block.high_label_value }}
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
index 2b2aba256..813a9384b 100644
--- a/data/templates/frr/nhrpd.frr.j2
+++ b/data/templates/frr/nhrpd.frr.j2
@@ -58,5 +58,3 @@ exit
{% endfor %}
{% endif %}
!
-exit
-!
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/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.j2 b/data/templates/ipsec/charon.j2
index 388559af8..a9108eeda 100644
--- a/data/templates/ipsec/charon.j2
+++ b/data/templates/ipsec/charon.j2
@@ -202,15 +202,16 @@ charon {
# Size of the AH/ESP replay window, in packets.
# replay_window = 32
- # Base to use for calculating exponential back off, see IKEv2 RETRANSMISSION
- # in strongswan.conf(5).
- # retransmit_base = 1.8
-
- # Timeout in seconds before sending first retransmit.
- # retransmit_timeout = 4.0
-
- # Number of times to retransmit a packet before giving up.
- # retransmit_tries = 5
+ # IKEv2 RETRANSMISSION
+{% if options.retransmission.attempts is vyos_defined %}
+ retransmit_tries = {{ options.retransmission.attempts }}
+{% endif %}
+{% if options.retransmission.base is vyos_defined %}
+ retransmit_base = {{ options.retransmission.base }}
+{% endif %}
+{% if options.retransmission.timeout is vyos_defined %}
+ retransmit_timeout = {{ options.retransmission.timeout }}
+{% endif %}
# Interval in seconds to use when retrying to initiate an IKE_SA (e.g. if
# DNS resolution failed), 0 to disable retries.
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.conf.j2 b/data/templates/ipsec/swanctl.conf.j2
index 64e7ea860..e4e0b373d 100644
--- a/data/templates/ipsec/swanctl.conf.j2
+++ b/data/templates/ipsec/swanctl.conf.j2
@@ -4,15 +4,17 @@
{% import 'ipsec/swanctl/peer.j2' as peer_tmpl %}
{% import 'ipsec/swanctl/remote_access.j2' as remote_access_tmpl %}
+{% set uniqreqids = 'never' if disable_uniqreqids is vyos_defined else None %}
+
connections {
{% if profile is vyos_defined %}
{% for name, profile_conf in profile.items() if profile_conf.disable is not vyos_defined and profile_conf.bind.tunnel is vyos_defined %}
-{{ profile_tmpl.conn(name, profile_conf, ike_group, esp_group) }}
+{{ profile_tmpl.conn(name, profile_conf, ike_group, esp_group, uniqreqids) }}
{% endfor %}
{% endif %}
{% if site_to_site.peer is vyos_defined %}
{% for peer, peer_conf in site_to_site.peer.items() if peer not in dhcp_no_address and peer_conf.disable is not vyos_defined %}
-{{ peer_tmpl.conn(peer, peer_conf, ike_group, esp_group) }}
+{{ peer_tmpl.conn(peer, peer_conf, ike_group, esp_group, uniqreqids) }}
{% endfor %}
{% endif %}
{% if remote_access.connection is vyos_defined %}
@@ -21,7 +23,7 @@ connections {
{% endfor %}
{% endif %}
{% if l2tp %}
-{{ l2tp_tmpl.conn(l2tp, l2tp_outside_address, l2tp_ike_default, l2tp_esp_default, ike_group, esp_group) }}
+{{ l2tp_tmpl.conn(l2tp, l2tp_outside_address, l2tp_ike_default, l2tp_esp_default, ike_group, esp_group, uniqreqids) }}
{% endif %}
}
diff --git a/data/templates/ipsec/swanctl/l2tp.j2 b/data/templates/ipsec/swanctl/l2tp.j2
index 7e63865cc..7eaf9087d 100644
--- a/data/templates/ipsec/swanctl/l2tp.j2
+++ b/data/templates/ipsec/swanctl/l2tp.j2
@@ -1,4 +1,4 @@
-{% macro conn(l2tp, l2tp_outside_address, l2tp_ike_default, l2tp_esp_default, ike_group, esp_group) %}
+{% macro conn(l2tp, l2tp_outside_address, l2tp_ike_default, l2tp_esp_default, ike_group, esp_group, uniqreqids) %}
{% set l2tp_ike = ike_group[l2tp.ike_group] if l2tp.ike_group is vyos_defined else None %}
{% set l2tp_esp = esp_group[l2tp.esp_group] if l2tp.esp_group is vyos_defined else None %}
l2tp_remote_access {
@@ -8,6 +8,9 @@
dpd_timeout = 45s
rekey_time = {{ l2tp_ike.lifetime if l2tp_ike else l2tp.ike_lifetime }}s
reauth_time = 0
+{% if uniqreqids is vyos_defined %}
+ unique = {{ uniqreqids }}
+{% endif %}
local {
auth = {{ 'psk' if l2tp.authentication.mode == 'pre-shared-secret' else 'pubkey' }}
{% if l2tp.authentication.mode == 'x509' %}
diff --git a/data/templates/ipsec/swanctl/peer.j2 b/data/templates/ipsec/swanctl/peer.j2
index 3a9af2c94..518402c53 100644
--- a/data/templates/ipsec/swanctl/peer.j2
+++ b/data/templates/ipsec/swanctl/peer.j2
@@ -1,4 +1,4 @@
-{% macro conn(peer, peer_conf, ike_group, esp_group) %}
+{% macro conn(peer, peer_conf, ike_group, esp_group, uniqreqids) %}
{% set name = peer.replace("@", "") | dot_colon_to_dash %}
{# peer needs to reference the global IKE configuration for certain values #}
{% set ike = ike_group[peer_conf.ike_group] %}
@@ -33,6 +33,9 @@
{% if peer_conf.force_udp_encapsulation is vyos_defined %}
encap = yes
{% endif %}
+{% if uniqreqids is vyos_defined %}
+ unique = {{ uniqreqids }}
+{% endif %}
local {
{% if peer_conf.authentication.local_id is vyos_defined %}
id = "{{ peer_conf.authentication.local_id }}"
@@ -68,8 +71,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 #}
@@ -100,6 +114,12 @@
{% set tunnel_esp_name = tunnel_conf.esp_group if tunnel_conf.esp_group is vyos_defined else peer_conf.default_esp_group %}
{% set tunnel_esp = esp_group[tunnel_esp_name] %}
{% set proto = tunnel_conf.protocol if tunnel_conf.protocol is vyos_defined else '' %}
+{# VyOS 1.3.x (with strongSwan 5.7.x) previously allowed using `all` in traffic selectors, converting it to `%any`. #}
+{# In strongSwan 5.9.x (VyOS >= 1.4.x), the syntax `x.x.x.0/24[all/]` is no longer accepted. #}
+{# We must now explicitly specify a protocol (e.g., `tcp`, `udp`). #}
+{# To achieve "all" protocol behavior, simply use the subnet notation without brackets, #}
+{# such as `x.x.x.0/24` or `x.x.x.0/24[/443]`. #}
+{% set proto = '' if proto == 'all' else proto %}
{% set local_port = tunnel_conf.local.port if tunnel_conf.local.port is vyos_defined else '' %}
{% set local_suffix = '[{0}/{1}]'.format(proto, local_port) if proto or local_port else '' %}
{% set remote_port = tunnel_conf.remote.port if tunnel_conf.remote.port is vyos_defined else '' %}
diff --git a/data/templates/ipsec/swanctl/profile.j2 b/data/templates/ipsec/swanctl/profile.j2
index 6a04b038a..10fe0a8ec 100644
--- a/data/templates/ipsec/swanctl/profile.j2
+++ b/data/templates/ipsec/swanctl/profile.j2
@@ -1,4 +1,4 @@
-{% macro conn(name, profile_conf, ike_group, esp_group) %}
+{% macro conn(name, profile_conf, ike_group, esp_group, uniqreqids) %}
{# peer needs to reference the global IKE configuration for certain values #}
{% set ike = ike_group[profile_conf.ike_group] %}
{% set esp = esp_group[profile_conf.esp_group] %}
@@ -13,6 +13,9 @@
dpd_timeout = {{ ike.dead_peer_detection.timeout }}
dpd_delay = {{ ike.dead_peer_detection.interval }}
{% endif %}
+{% if uniqreqids is vyos_defined %}
+ unique = {{ uniqreqids }}
+{% endif %}
{% if profile_conf.authentication.mode is vyos_defined('pre-shared-secret') %}
local {
auth = psk
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..c73f71722 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, server_config in front_config.listen_address.items() %}
+ bind {{ address | bracketize_ipv6 }}:80 {{ 'accept-proxy' if server_config.accept_proxy is vyos_defined }}
+{% 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 %}
@@ -61,15 +82,12 @@ frontend {{ front }}
{% endif %}
{% set ssl_directive = 'ssl' if ssl_front else '' %}
{% if front_config.listen_address is vyos_defined %}
-{% for address in front_config.listen_address %}
- bind {{ address | bracketize_ipv6 }}:{{ front_config.port }} {{ ssl_directive }} {{ ssl_front | join(' ') }}
+{% for address, server_config in front_config.listen_address.items() %}
+ bind {{ address | bracketize_ipv6 }}:{{ front_config.port }} {{ ssl_directive }} {{ ssl_front | join(' ') }} {{ 'accept-proxy' if server_config.accept_proxy is vyos_defined }}
{% endfor %}
{% 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,17 +111,26 @@ 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 }}
{% if rule_config.domain_name is vyos_defined %}
{% set rule_options = 'hdr(host)' %}
+{% set domain_prefix = '' %}
{% if rule_config.ssl is vyos_defined %}
{% set ssl_rule_translate = {'req-ssl-sni': 'req_ssl_sni', 'ssl-fc-sni': 'ssl_fc_sni', 'ssl-fc-sni-end': 'ssl_fc_sni_end'} %}
{% set rule_options = ssl_rule_translate[rule_config.ssl] %}
{% endif %}
+{% if rule_config.wildcard_domain is vyos_defined %}
+{% set domain_prefix = '-m end .' %}
+{% endif %}
{% for domain in rule_config.domain_name %}
- acl {{ rule }} {{ rule_options }} -i {{ domain }}
+ acl {{ rule }} {{ rule_options }} -i {{ domain_prefix }}{{ domain }}
{% endfor %}
{% endif %}
{# path url #}
@@ -129,6 +156,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 %}
@@ -189,12 +221,16 @@ backend {{ back }}
{% for rule, rule_config in back_config.rule.items() %}
{% if rule_config.domain_name is vyos_defined and rule_config.set.server is vyos_defined %}
{% set rule_options = 'hdr(host)' %}
+{% set domain_prefix = '' %}
{% if rule_config.ssl is vyos_defined %}
{% set ssl_rule_translate = {'req-ssl-sni': 'req_ssl_sni', 'ssl-fc-sni': 'ssl_fc_sni', 'ssl-fc-sni-end': 'ssl_fc_sni_end'} %}
{% set rule_options = ssl_rule_translate[rule_config.ssl] %}
{% endif %}
+{% if rule_config.wildcard_domain is vyos_defined %}
+{% set domain_prefix = '-m end .' %}
+{% endif %}
{% for domain in rule_config.domain_name %}
- acl {{ rule }} {{ rule_options }} -i {{ domain }}
+ acl {{ rule }} {{ rule_options }} -i {{ domain_prefix }}{{ domain }}
{% endfor %}
use-server {{ rule_config.set.server }} if {{ rule }}
{% endif %}
@@ -226,6 +262,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/prometheus/node_exporter.service.j2 b/data/templates/prometheus/node_exporter.service.j2
index 135439bd6..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,10 +21,6 @@ ExecStart={{ vrf_command }}/usr/sbin/node_exporter \
{% else %}
--web.listen-address=:{{ port }}
{% endif %}
-{% if collectors is vyos_defined %}
-{% if collectors.textfile is vyos_defined %}
- --collector.textfile.directory=/run/node_exporter/collector
-{% endif %}
-{% 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 6a1ba2956..fc251e92b 100644
--- a/data/templates/sflow/hsflowd.conf.j2
+++ b/data/templates/sflow/hsflowd.conf.j2
@@ -32,4 +32,7 @@ sflow {
dropmon { limit={{ drop_monitor_limit }} start=on sw=on hw=off }
{% endif %}
dbus { }
+{% if vpp is vyos_defined %}
+ vpp { }
+{% 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/vpp/override.conf.j2 b/data/templates/vpp/override.conf.j2
new file mode 100644
index 000000000..04bb7be15
--- /dev/null
+++ b/data/templates/vpp/override.conf.j2
@@ -0,0 +1,14 @@
+[Unit]
+After=
+After=vyos-router.service
+ConditionPathExists=
+ConditionPathExists=/run/vpp/vpp.conf
+OnFailure=vpp-failure-handler.service
+
+[Service]
+EnvironmentFile=
+ExecStart=
+ExecStart=/usr/bin/vpp -c /run/vpp/vpp.conf
+WorkingDirectory=
+WorkingDirectory=/run/vpp
+Restart=no
diff --git a/data/templates/vpp/startup.conf.j2 b/data/templates/vpp/startup.conf.j2
new file mode 100644
index 000000000..b7515889a
--- /dev/null
+++ b/data/templates/vpp/startup.conf.j2
@@ -0,0 +1,209 @@
+# Generated by ${vyos_conf_scripts_dir}/vpp.py
+
+unix {
+ nodaemon
+ log /var/log/vpp.log
+ full-coredump
+ cli-listen /run/vpp/cli.sock
+ gid vpp
+ # exec /etc/vpp/bootstrap.vpp
+{% if unix is vyos_defined %}
+{% if unix.poll_sleep_usec is vyos_defined %}
+ poll-sleep-usec {{ unix.poll_sleep_usec }}
+{% endif %}
+{% endif %}
+}
+
+{% if cpu is vyos_defined %}
+cpu {
+{% if cpu.main_core is vyos_defined %}
+ main-core {{ cpu.main_core }}
+{% endif %}
+{% if cpu.corelist_workers is vyos_defined %}
+ corelist-workers {{ cpu.corelist_workers | join(',') }}
+{% endif %}
+{% if cpu.skip_cores is vyos_defined %}
+ skip-cores {{ cpu.skip_cores }}
+{% endif %}
+{% if cpu.workers is vyos_defined %}
+ workers {{ cpu.workers }}
+{% endif %}
+}
+{% endif %}
+
+{% if buffers is vyos_defined %}
+buffers {
+{% if buffers.buffers_per_numa is vyos_defined %}
+ buffers-per-numa {{ buffers.buffers_per_numa }}
+{% endif %}
+{% if buffers.data_size is vyos_defined %}
+ default data-size {{ buffers.data_size }}
+{% endif %}
+{% if buffers.page_size is vyos_defined %}
+ page-size {{ buffers.page_size }}
+{% endif %}
+}
+{% endif %}
+
+{% if ipv6 is vyos_defined %}
+ip6 {
+{% if ipv6.hash_buckets is vyos_defined %}
+ hash-buckets {{ ipv6.hash_buckets }}
+{% endif %}
+{% if ipv6.heap_size is vyos_defined %}
+ heap-size {{ ipv6.heap_size }}
+{% endif %}
+}
+{% endif %}
+
+{% if l2learn is vyos_defined %}
+l2learn {
+{% if l2learn.limit is vyos_defined %}
+ limit {{ l2learn.limit }}
+{% endif %}
+}
+{% endif %}
+
+{% if logging is vyos_defined %}
+logging {
+{% if logging.default_log_level is vyos_defined %}
+ default-log-level {{ logging.default_log_level }}
+ default-syslog-log-level {{ logging.default_log_level }}
+{% endif %}
+}
+{% endif %}
+
+{% if physmem is vyos_defined %}
+physmem {
+{% if physmem.max_size is vyos_defined %}
+ max-size {{ physmem.max_size }}
+{% endif %}
+}
+{% endif %}
+
+plugins {
+ path /usr/lib/x86_64-linux-gnu/vpp_plugins/
+ plugin default { disable }
+ plugin af_xdp_plugin.so { enable }
+ plugin avf_plugin.so { enable }
+ plugin dpdk_plugin.so { enable }
+ plugin vmxnet3_plugin.so { enable }
+ plugin lacp_plugin.so { enable }
+ plugin linux_cp_plugin.so { enable }
+ plugin linux_nl_plugin.so { enable }
+ plugin pppoe_plugin.so { enable }
+ plugin sflow_plugin.so { enable }
+ # NAT uncomment if needed
+ # plugin cnat_plugin.so { enable }
+ plugin nat_plugin.so { enable }
+ plugin nat44_ei_plugin.so { enable }
+ plugin det44_plugin.so { enable }
+ # plugin nat44_ei_plugin.so { enable }
+ # plugin nat64_plugin.so { enable }
+ # plugin nat66_plugin.so { enable }
+ # plugin pnat_plugin.so { enable }
+ # Tunnels
+ plugin geneve_plugin.so { enable }
+ plugin gre_plugin.so { enable }
+ plugin vxlan_plugin.so { enable }
+ # Secure
+ # plugin ikev2_plugin.so { enable }
+ # plugin dns_plugin.so { enable } # Probably required for FQDN peers
+{% if ipsec is vyos_defined %}
+ plugin crypto_ipsecmb_plugin.so { enable }
+ plugin crypto_native_plugin.so { enable }
+ plugin crypto_openssl_plugin.so { enable }
+{% endif %}
+ # plugin wireguard_plugin.so { enable }
+ # ACL
+ plugin acl_plugin.so { enable }
+}
+
+linux-cp {
+ lcp-sync
+ lcp-auto-subint
+{% if lcp.ignore_kernel_routes is not vyos_defined %}
+ route-no-paths
+{% endif %}
+}
+
+{% if lcp.netlink is vyos_defined %}
+linux-nl {
+{% if lcp.netlink.rx_buffer_size is vyos_defined %}
+ nl-rx-buffer-size {{ lcp.netlink.rx_buffer_size }}
+{% endif %}
+{% if lcp.netlink.batch_size is vyos_defined %}
+ nl-batch-size {{ lcp.netlink.batch_size }}
+{% endif %}
+{% if lcp.netlink.batch_delay_ms is vyos_defined %}
+ nl-batch-delay-ms {{ lcp.netlink.batch_delay_ms }}
+{% endif %}
+}
+{% endif %}
+
+{% if statseg is vyos_defined %}
+statseg {
+{% if statseg.size is vyos_defined %}
+ size {{ statseg.size }}
+{% endif %}
+{% if statseg.page_size is vyos_defined %}
+ page-size {{ statseg.page_size }}
+{% endif %}
+}
+{% endif %}
+
+{% if memory is vyos_defined %}
+memory {
+{% if memory.main_heap_size is vyos_defined %}
+ main-heap-size {{ memory.main_heap_size }}
+{% endif %}
+{% if memory.main_heap_page_size is vyos_defined %}
+ main-heap-page-size {{ memory.main_heap_page_size }}
+{% endif %}
+{% if memory.default_hugepage_size is vyos_defined %}
+ default-hugepage-size {{ memory.default_hugepage_size }}
+{% endif %}
+}
+{% endif %}
+
+dpdk {
+ # Whitelist the fake PCI address 0000:00:00.0
+ # This prevents all devices from being added to VPP-DPDK by default
+ dev 0000:00:00.0
+{% for iface, iface_config in interface.items() %}
+{% if iface_config.driver == 'dpdk' %}
+ dev {{ iface_config.dpdk_options.dev_id }} {
+ name {{ iface }}
+{% if iface_config.dpdk_options.num_rx_desc is vyos_defined %}
+ num-rx-desc {{ iface_config.dpdk_options.num_rx_desc }}
+{% endif %}
+{% if iface_config.dpdk_options.num_tx_desc is vyos_defined %}
+ num-tx-desc {{ iface_config.dpdk_options.num_tx_desc }}
+{% endif %}
+{% if iface_config.dpdk_options.num_rx_queues is vyos_defined %}
+ num-rx-queues {{ iface_config.dpdk_options.num_rx_queues }}
+{% endif %}
+{% if iface_config.dpdk_options.num_tx_queues is vyos_defined %}
+ num-tx-queues {{ iface_config.dpdk_options.num_tx_queues }}
+{% endif %}
+ }
+{% endif %}
+{% endfor %}
+ uio-bind-force
+}
+
+{% if ipsec is vyos_defined %}
+linux-xfrm-nl {
+ enable-route-mode-ipsec
+ interface {{ ipsec.interface_type }}
+{% if ipsec.netlink.batch_delay_ms is vyos_defined %}
+ nl-batch-delay-ms {{ ipsec.netlink.batch_delay_ms }}
+{% endif %}
+{% if ipsec.netlink.batch_size is vyos_defined %}
+ nl-batch-size {{ ipsec.netlink.batch_size }}
+{% endif %}
+{% if ipsec.netlink.rx_buffer_size is vyos_defined %}
+ nl-rx-buffer-size {{ ipsec.netlink.rx_buffer_size }}
+{% endif %}
+}
+{% endif %}
diff --git a/data/vyos-firewall-init.conf b/data/vyos-firewall-init.conf
index 3929edf0b..220b75652 100644
--- a/data/vyos-firewall-init.conf
+++ b/data/vyos-firewall-init.conf
@@ -17,7 +17,7 @@ table inet mangle {
table raw {
chain VYOS_TCP_MSS {
- type filter hook forward priority -300; policy accept;
+ type filter hook postrouting priority -300; policy accept;
}
chain vyos_global_rpfilter {
@@ -37,7 +37,7 @@ table raw {
table ip6 raw {
chain VYOS_TCP_MSS {
- type filter hook forward priority -300; policy accept;
+ type filter hook postrouting priority -300; policy accept;
}
chain vyos_global_rpfilter {