summaryrefslogtreecommitdiff
path: root/data
diff options
context:
space:
mode:
Diffstat (limited to 'data')
-rw-r--r--data/configd-include.json10
-rw-r--r--data/templates/accel-ppp/pppoe.config.tmpl23
-rw-r--r--data/templates/accel-ppp/sstp.config.tmpl6
-rw-r--r--data/templates/conntrack/sysctl.conf.tmpl26
-rw-r--r--data/templates/conntrack/vyos_nf_conntrack.conf.tmpl3
-rw-r--r--data/templates/conntrackd/conntrackd.conf.tmpl25
-rw-r--r--data/templates/dhcp-server/dhcpdv6.conf.tmpl3
-rw-r--r--data/templates/ethernet/wpa_supplicant.conf.tmpl8
-rw-r--r--data/templates/firewall/nftables-nat.tmpl23
-rw-r--r--data/templates/firewall/nftables-vrf-zones.tmpl17
-rw-r--r--data/templates/frr/bgpd.frr.tmpl17
-rw-r--r--data/templates/frr/isisd.frr.tmpl (renamed from data/templates/frr/isis.frr.tmpl)66
-rw-r--r--data/templates/frr/ospfv3.frr.tmpl5
-rw-r--r--data/templates/frr/policy.frr.tmpl14
-rw-r--r--data/templates/https/nginx.default.tmpl5
-rw-r--r--data/templates/ipsec/charon/dhcp.conf.tmpl22
-rw-r--r--data/templates/ipsec/charon/eap-radius.conf.tmpl115
-rw-r--r--data/templates/ipsec/interfaces_use.conf.tmpl5
-rw-r--r--data/templates/ipsec/ios_profile.tmpl104
-rw-r--r--data/templates/ipsec/ipsec.conf.tmpl21
-rw-r--r--data/templates/ipsec/ipsec.secrets.tmpl12
-rw-r--r--data/templates/ipsec/remote-access.tmpl28
-rw-r--r--data/templates/ipsec/swanctl.conf.tmpl131
-rw-r--r--data/templates/ipsec/swanctl/l2tp.tmpl30
-rw-r--r--data/templates/ipsec/swanctl/peer.tmpl134
-rw-r--r--data/templates/ipsec/swanctl/profile.tmpl39
-rw-r--r--data/templates/ipsec/swanctl/remote_access.tmpl47
-rw-r--r--data/templates/ipsec/windows_profile.tmpl4
-rw-r--r--data/templates/nhrp/opennhrp.conf.tmpl41
-rw-r--r--data/templates/ocserv/ocserv_config.tmpl14
-rw-r--r--data/templates/openvpn/server.conf.tmpl100
-rw-r--r--data/templates/proxy-ndp/ndppd.conf.tmpl4
-rw-r--r--data/templates/router-advert/radvd.conf.tmpl79
-rw-r--r--data/templates/snmp/override.conf.tmpl5
-rw-r--r--data/templates/system/sysctl.conf.tmpl7
-rw-r--r--data/templates/wwan/chat.tmpl10
-rw-r--r--data/templates/wwan/ip-down.script.tmpl27
-rw-r--r--data/templates/wwan/ip-pre-up.script.tmpl23
-rw-r--r--data/templates/wwan/ip-up.script.tmpl25
-rw-r--r--data/templates/wwan/peer.tmpl31
40 files changed, 978 insertions, 331 deletions
diff --git a/data/configd-include.json b/data/configd-include.json
index f241d0cb6..3b4e2925b 100644
--- a/data/configd-include.json
+++ b/data/configd-include.json
@@ -1,5 +1,7 @@
[
"bcast_relay.py",
+"conntrack.py",
+"conntrack_sync.py",
"dhcp_relay.py",
"dhcpv6_relay.py",
"dns_forwarding.py",
@@ -24,12 +26,12 @@
"interfaces-vxlan.py",
"interfaces-wireguard.py",
"interfaces-wireless.py",
-"interfaces-wirelessmodem.py",
-"ipsec-settings.py",
+"interfaces-wwan.py",
"lldp.py",
"nat.py",
"nat66.py",
"ntp.py",
+"pki.py",
"policy.py",
"policy-local-route.py",
"protocols_bfd.py",
@@ -37,6 +39,7 @@
"protocols_igmp.py",
"protocols_isis.py",
"protocols_mpls.py",
+"protocols_nhrp.py",
"protocols_ospf.py",
"protocols_ospfv3.py",
"protocols_pim.py",
@@ -66,6 +69,5 @@
"vpn_pptp.py",
"vpn_sstp.py",
"vrf.py",
-"vrrp.py",
-"vyos_cert.py"
+"vrrp.py"
]
diff --git a/data/templates/accel-ppp/pppoe.config.tmpl b/data/templates/accel-ppp/pppoe.config.tmpl
index f444af85c..238e7ee15 100644
--- a/data/templates/accel-ppp/pppoe.config.tmpl
+++ b/data/templates/accel-ppp/pppoe.config.tmpl
@@ -17,6 +17,10 @@ net-snmp
{% if limits is defined %}
connlimit
{% endif %}
+{% if extended_scripts is defined %}
+sigchld
+pppd_compat
+{% endif %}
[core]
thread-count={{ thread_count }}
@@ -91,6 +95,9 @@ ipv6-accept-peer-intf-id={{ "1" if ppp_options.ipv6_accept_peer_intf_id is defin
{% endif %}
{# MTU #}
mtu={{ mtu }}
+{% if ppp_options.interface_cache is defined and ppp_options.interface_cache is not none %}
+unit-cache={{ ppp_options.interface_cache }}
+{% endif %}
[pppoe]
verbose=1
@@ -133,6 +140,9 @@ service-name={{ service_name | join(',') }}
{% endfor %}
pado-delay={{ pado_delay_param.value }}
{% endif %}
+{% if authentication.radius.called_sid_format is defined and authentication.radius.called_sid_format is not none %}
+called-sid={{ authentication.radius.called_sid_format }}
+{% endif %}
{% if limits is defined %}
[connlimit]
@@ -146,12 +156,19 @@ burst={{ limits.burst }}
timeout={{ limits.timeout }}
{% endif %}
{% endif %}
-{% if authentication.radius.called_sid_format is defined and authentication.radius.called_sid_format is not none %}
-called-sid={{ authentication.radius.called_sid_format }}
-{% endif %}
{# Common RADIUS shaper configuration #}
{% include 'accel-ppp/config_shaper_radius.j2' %}
+{% if extended_scripts is defined %}
+[pppd-compat]
+verbose=1
+radattr-prefix=/run/accel-pppd/radattr
+{% set script_name = {'on_up': 'ip-up', 'on_down': 'ip-down', 'on_change':'ip-change', 'on_pre_up':'ip-pre-up'} %}
+{% for script in extended_scripts %}
+{{ script_name[script] }}={{ extended_scripts[script] }}
+{% endfor %}
+{% endif %}
+
[cli]
tcp=127.0.0.1:2001
diff --git a/data/templates/accel-ppp/sstp.config.tmpl b/data/templates/accel-ppp/sstp.config.tmpl
index 7ca7b1c1e..fad91d118 100644
--- a/data/templates/accel-ppp/sstp.config.tmpl
+++ b/data/templates/accel-ppp/sstp.config.tmpl
@@ -29,9 +29,9 @@ disable
verbose=1
ifname=sstp%d
accept=ssl
-ssl-ca-file={{ ssl.ca_cert_file }}
-ssl-pemfile={{ ssl.cert_file }}
-ssl-keyfile={{ ssl.key_file }}
+ssl-ca-file=/run/accel-pppd/sstp-ca.pem
+ssl-pemfile=/run/accel-pppd/sstp-cert.pem
+ssl-keyfile=/run/accel-pppd/sstp-cert.key
{# Common IP pool definitions #}
{% include 'accel-ppp/config_ip_pool.j2' %}
diff --git a/data/templates/conntrack/sysctl.conf.tmpl b/data/templates/conntrack/sysctl.conf.tmpl
new file mode 100644
index 000000000..9e97c3286
--- /dev/null
+++ b/data/templates/conntrack/sysctl.conf.tmpl
@@ -0,0 +1,26 @@
+# Autogenerated by conntrack.py
+{# all values have defaults - thus no checking required #}
+
+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 == 'enable' else '0' }}
+net.netfilter.nf_conntrack_tcp_max_retrans = {{ tcp.max_retrans }}
+
+net.netfilter.nf_conntrack_icmp_timeout = {{ timeout.icmp }}
+net.netfilter.nf_conntrack_generic_timeout = {{ timeout.other }}
+
+net.netfilter.nf_conntrack_tcp_timeout_close_wait = {{ timeout.tcp.close_wait }}
+net.netfilter.nf_conntrack_tcp_timeout_close = {{ timeout.tcp.close }}
+net.netfilter.nf_conntrack_tcp_timeout_established = {{ timeout.tcp.established }}
+net.netfilter.nf_conntrack_tcp_timeout_fin_wait = {{ timeout.tcp.fin_wait }}
+net.netfilter.nf_conntrack_tcp_timeout_last_ack = {{ timeout.tcp.last_ack }}
+net.netfilter.nf_conntrack_tcp_timeout_syn_recv = {{ timeout.tcp.syn_recv }}
+net.netfilter.nf_conntrack_tcp_timeout_syn_sent = {{ timeout.tcp.syn_sent }}
+net.netfilter.nf_conntrack_tcp_timeout_time_wait = {{ timeout.tcp.time_wait }}
+
+net.netfilter.nf_conntrack_udp_timeout = {{ timeout.udp.other }}
+net.netfilter.nf_conntrack_udp_timeout_stream = {{ timeout.udp.stream }}
+
diff --git a/data/templates/conntrack/vyos_nf_conntrack.conf.tmpl b/data/templates/conntrack/vyos_nf_conntrack.conf.tmpl
new file mode 100644
index 000000000..111459485
--- /dev/null
+++ b/data/templates/conntrack/vyos_nf_conntrack.conf.tmpl
@@ -0,0 +1,3 @@
+# Autogenerated by conntrack.py
+options nf_conntrack hashsize={{ hash_size }} nf_conntrack_helper=1
+
diff --git a/data/templates/conntrackd/conntrackd.conf.tmpl b/data/templates/conntrackd/conntrackd.conf.tmpl
index 17ee529bf..45b7bff09 100644
--- a/data/templates/conntrackd/conntrackd.conf.tmpl
+++ b/data/templates/conntrackd/conntrackd.conf.tmpl
@@ -6,28 +6,31 @@ Sync {
DisableExternalCache {{ 'on' if disable_external_cache is defined else 'off' }}
}
{% for iface, iface_config in interface.items() %}
-{% if loop.first %}
-{% if iface_config.peer is defined and iface_config.peer is not none %}
+{% if iface_config.peer is defined and iface_config.peer is not none %}
UDP {
-{% if listen_address is defined and listen_address is not none %}
+{% if listen_address is defined and listen_address is not none %}
IPv4_address {{ listen_address }}
-{% endif %}
+{% endif %}
IPv4_Destination_Address {{ iface_config.peer }}
- Port 3780
-{% else %}
-{% set ip_address = iface | get_ipv4 %}
+ Port {{ iface_config.port if iface_config.port is defined else '3780' }}
+ Interface {{ iface }}
+ SndSocketBuffer {{ sync_queue_size | int *1024 *1024 }}
+ RcvSocketBuffer {{ sync_queue_size | int *1024 *1024 }}
+ Checksum on
+ }
+{% else %}
Multicast {
+{% set ip_address = iface | get_ipv4 %}
IPv4_address {{ mcast_group }}
- Group 3780
+ Group {{ iface_config.port if iface_config.port is defined else '3780' }}
IPv4_interface {{ ip_address[0] | ip_from_cidr }}
-{% endif %}
Interface {{ iface }}
-{% endif %}
-{% endfor %}
SndSocketBuffer {{ sync_queue_size | int *1024 *1024 }}
RcvSocketBuffer {{ sync_queue_size | int *1024 *1024 }}
Checksum on
}
+{% endif %}
+{% endfor %}
{% if expect_sync is defined and expect_sync is not none %}
Options {
{% if 'all' in expect_sync %}
diff --git a/data/templates/dhcp-server/dhcpdv6.conf.tmpl b/data/templates/dhcp-server/dhcpdv6.conf.tmpl
index 8d653ff72..45d629928 100644
--- a/data/templates/dhcp-server/dhcpdv6.conf.tmpl
+++ b/data/templates/dhcp-server/dhcpdv6.conf.tmpl
@@ -107,6 +107,9 @@ shared-network {{ network | replace('_','-') }} {
{% if host_config.ipv6_address is defined and host_config.ipv6_address is not none %}
fixed-address6 {{ host_config.ipv6_address }};
{% endif %}
+{% if host_config.ipv6_prefix is defined and host_config.ipv6_prefix is not none %}
+ fixed-prefix6 {{ host_config.ipv6_prefix }};
+{% endif %}
}
{% endfor %}
{% endif %}
diff --git a/data/templates/ethernet/wpa_supplicant.conf.tmpl b/data/templates/ethernet/wpa_supplicant.conf.tmpl
index fe518ad45..308d777f1 100644
--- a/data/templates/ethernet/wpa_supplicant.conf.tmpl
+++ b/data/templates/ethernet/wpa_supplicant.conf.tmpl
@@ -32,11 +32,11 @@ fast_reauth=1
network={
{% if eapol is defined and eapol is not none %}
-{% if eapol.ca_cert_file is defined and eapol.ca_cert_file is not none %}
- ca_cert="{{ eapol.ca_cert_file }}"
+{% if eapol.ca_certificate is defined and eapol.ca_certificate is not none %}
+ ca_cert="/run/wpa_supplicant/{{ ifname }}_ca.pem"
{% endif %}
- client_cert="{{ eapol.cert_file }}"
- private_key="{{ eapol.key_file }}"
+ client_cert="/run/wpa_supplicant/{{ ifname }}_cert.pem"
+ private_key="/run/wpa_supplicant/{{ ifname }}_cert.key"
{% endif %}
# list of accepted authenticated key management protocols
diff --git a/data/templates/firewall/nftables-nat.tmpl b/data/templates/firewall/nftables-nat.tmpl
index b80fc1968..40ed1b916 100644
--- a/data/templates/firewall/nftables-nat.tmpl
+++ b/data/templates/firewall/nftables-nat.tmpl
@@ -73,6 +73,26 @@
{% set trns_addr = 'return' %}
{% set trns_port = '' %}
{% endif %}
+{# T1083: NAT address and port translation options #}
+{% if config.translation is defined and config.translation.options is defined and config.translation.options is not none %}
+{% if config.translation.options.address_mapping is defined and config.translation.options.address_mapping == "persistent" %}
+{% set trns_opts_addr = 'persistent' %}
+{% endif %}
+{% if config.translation.options.port_mapping is defined %}
+{% if config.translation.options.port_mapping == "random" %}
+{% set trns_opts_port = 'random' %}
+{% elif config.translation.options.port_mapping == "fully-random" %}
+{% set trns_opts_port = 'fully-random' %}
+{% endif %}
+{% endif %}
+{% endif %}
+{% if trns_opts_addr and trns_opts_port %}
+{% set trns_opts = trns_opts_addr + ',' + trns_opts_port %}
+{% elif trns_opts_addr %}
+{% set trns_opts = trns_opts_addr %}
+{% elif trns_opts_port %}
+{% set trns_opts = trns_opts_port %}
+{% endif %}
{% set output = 'add rule ip nat ' + chain + interface %}
{% if protocol != 'all' %}
{% set output = output + ' ip protocol ' + protocol %}
@@ -104,6 +124,9 @@
{# e.g. 192.0.2.10:3389 #}
{% set output = output + trns_port %}
{% endif %}
+{% if trns_opts %}
+{% set output = output + ' ' + trns_opts %}
+{% endif %}
{% if comment %}
{% set output = output + ' comment "' + comment + '"' %}
{% endif %}
diff --git a/data/templates/firewall/nftables-vrf-zones.tmpl b/data/templates/firewall/nftables-vrf-zones.tmpl
new file mode 100644
index 000000000..eecf47b78
--- /dev/null
+++ b/data/templates/firewall/nftables-vrf-zones.tmpl
@@ -0,0 +1,17 @@
+table inet vrf_zones {
+ # Map of interfaces and connections tracking zones
+ map ct_iface_map {
+ typeof iifname : ct zone
+ }
+ # Assign unique zones for each VRF
+ # Chain for inbound traffic
+ chain vrf_zones_ct_in {
+ type filter hook prerouting priority raw; policy accept;
+ counter ct zone set iifname map @ct_iface_map
+ }
+ # Chain for locally-generated traffic
+ chain vrf_zones_ct_out {
+ type filter hook output priority raw; policy accept;
+ counter ct zone set oifname map @ct_iface_map
+ }
+}
diff --git a/data/templates/frr/bgpd.frr.tmpl b/data/templates/frr/bgpd.frr.tmpl
index 5edd3f97d..aa297876b 100644
--- a/data/templates/frr/bgpd.frr.tmpl
+++ b/data/templates/frr/bgpd.frr.tmpl
@@ -65,6 +65,9 @@
{% if config.shutdown is defined %}
neighbor {{ neighbor }} shutdown
{% endif %}
+{% if config.solo is defined %}
+ neighbor {{ neighbor }} solo
+{% endif %}
{% if config.strict_capability_match is defined %}
neighbor {{ neighbor }} strict-capability-match
{% endif %}
@@ -173,6 +176,9 @@
{% if afi_config.maximum_prefix is defined and afi_config.maximum_prefix is not none %}
neighbor {{ neighbor }} maximum-prefix {{ afi_config.maximum_prefix }}
{% endif %}
+{% if afi_config.maximum_prefix_out is defined and afi_config.maximum_prefix_out is not none %}
+ neighbor {{ neighbor }} maximum-prefix-out {{ afi_config.maximum_prefix_out }}
+{% endif %}
{% if afi_config.nexthop_self is defined %}
neighbor {{ neighbor }} next-hop-self {{ 'force' if afi_config.nexthop_self.force is defined }}
{% endif %}
@@ -399,15 +405,18 @@ router bgp {{ local_as }} {{ 'vrf ' ~ vrf if vrf is defined and vrf is not none
bgp always-compare-med
{% endif %}
{% if parameters.bestpath is defined and parameters.bestpath is not none %}
-{% if parameters.bestpath.compare_routerid is defined %}
- bgp bestpath compare-routerid
-{% endif %}
{% if parameters.bestpath.as_path is defined and parameters.bestpath.as_path is not none %}
{% for option in parameters.bestpath.as_path %}
{# replace is required for multipath-relax option #}
bgp bestpath as-path {{ option|replace('_', '-') }}
{% endfor %}
{% endif %}
+{% if parameters.bestpath.bandwidth is defined and parameters.bestpath.bandwidth is not none %}
+ bgp bestpath bandwidth {{ parameters.bestpath.bandwidth }}
+{% endif %}
+{% if parameters.bestpath.compare_routerid is defined %}
+ bgp bestpath compare-routerid
+{% endif %}
{% if parameters.bestpath.med is defined and parameters.bestpath.med is not none %}
bgp bestpath med {{ 'confed' if parameters.bestpath.med.confed is defined }} {{ 'missing-as-worst' if parameters.bestpath.med.missing_as_worst is defined }}
{% endif %}
@@ -420,7 +429,7 @@ router bgp {{ local_as }} {{ 'vrf ' ~ vrf if vrf is defined and vrf is not none
bgp confederation identifier {{ parameters.confederation.identifier }}
{% endif %}
{% if parameters.confederation.peers is defined and parameters.confederation.peers is not none %}
- bgp confederation peers {{ parameters.confederation.peers }}
+ bgp confederation peers {{ parameters.confederation.peers | join(' ') }}
{% endif %}
{% endif %}
{% if parameters.dampening is defined and parameters.dampening is defined and parameters.dampening.half_life is defined and parameters.dampening.half_life is not none %}
diff --git a/data/templates/frr/isis.frr.tmpl b/data/templates/frr/isisd.frr.tmpl
index 433f10892..6cfa076d0 100644
--- a/data/templates/frr/isis.frr.tmpl
+++ b/data/templates/frr/isisd.frr.tmpl
@@ -13,8 +13,15 @@ router isis VyOS {{ 'vrf ' + vrf if vrf is defined and vrf is not none }}
{% if set_overload_bit is defined %}
set-overload-bit
{% endif %}
-{% if domain_password is defined and domain_password.plaintext_password is defined and domain_password.plaintext_password is not none %}
+{% if domain_password is defined and domain_password is not none %}
+{% if domain_password.md5 is defined and domain_password.md5 is not none %}
+ domain-password md5 {{ domain_password.plaintext_password }}
+{% elif domain_password.plaintext_password is defined and domain_password.plaintext_password is not none %}
domain-password clear {{ domain_password.plaintext_password }}
+{% endif %}
+{% endif %}
+{% if log_adjacency_changes is defined %}
+ log-adjacency-changes
{% endif %}
{% if lsp_gen_interval is defined and lsp_gen_interval is not none %}
lsp-gen-interval {{ lsp_gen_interval }}
@@ -95,39 +102,53 @@ router isis VyOS {{ 'vrf ' + vrf if vrf is defined and vrf is not none }}
{% if spf_delay_ietf is defined and spf_delay_ietf.init_delay is defined and spf_delay_ietf.init_delay is not none %}
spf-delay-ietf init-delay {{ spf_delay_ietf.init_delay }}
{% endif %}
-{% if area_password is defined and area_password.md5 is defined and area_password.md5 is not none %}
+{% if area_password is defined and area_password is not none %}
+{% if area_password.md5 is defined and area_password.md5 is not none %}
area-password md5 {{ area_password.md5 }}
-{% elif area_password is defined and area_password.plaintext_password is defined and area_password.plaintext_password is not none %}
+{% elif area_password.plaintext_password is defined and area_password.plaintext_password is not none %}
area-password clear {{ area_password.plaintext_password }}
+{% endif %}
{% endif %}
{% if default_information is defined and default_information.originate is defined and default_information.originate is not none %}
-{% for level in default_information.originate.ipv4 if default_information.originate.ipv4 is defined %}
- default-information originate ipv4 {{ level | replace('_', '-') }}
-{% endfor %}
-{% for level in default_information.originate.ipv6 if default_information.originate.ipv6 is defined %}
- default-information originate ipv6 {{ level | replace('_', '-') }} always
+{% for afi, afi_config in default_information.originate.items() %}
+{% for level, level_config in afi_config.items() %}
+ default-information originate {{ afi }} {{ level | replace('_', '-') }} {{ 'always' if level_config.always is defined }} {{ 'route-map ' ~ level_config.route_map if level_config.route_map is defined }} {{ 'metric ' ~ level_config.metric if level_config.metric is defined }}
+{% endfor %}
{% endfor %}
{% endif %}
-{% if redistribute is defined and redistribute.ipv4 is defined and redistribute.ipv4 is not none %}
-{% for protocol in redistribute.ipv4 %}
-{% for level, level_config in redistribute.ipv4[protocol].items() %}
-{% if level_config.metric is defined and level_config.metric is not none %}
+{% if redistribute is defined %}
+{% if redistribute.ipv4 is defined and redistribute.ipv4 is not none %}
+{% for protocol, protocol_options in redistribute.ipv4.items() %}
+{% for level, level_config in protocol_options.items() %}
+{% if level_config.metric is defined and level_config.metric is not none %}
redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }} metric {{ level_config.metric }}
-{% elif level_config.route_map is defined and level_config.route_map is not none %}
+{% elif level_config.route_map is defined and level_config.route_map is not none %}
redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }} route-map {{ level_config.route_map }}
-{% else %}
+{% else %}
redistribute ipv4 {{ protocol }} {{ level | replace('_', '-') }}
-{% endif %}
+{% endif %}
+{% endfor %}
{% endfor %}
-{% endfor %}
+{% endif %}
+{% if redistribute.ipv6 is defined and redistribute.ipv6 is not none %}
+{% for protocol, protocol_options in redistribute.ipv6.items() %}
+{% for level, level_config in protocol_options.items() %}
+{% if level_config.metric is defined and level_config.metric is not none %}
+ redistribute ipv6 {{ protocol }} {{ level | replace('_', '-') }} metric {{ level_config.metric }}
+{% elif level_config.route_map is defined and level_config.route_map is not none %}
+ redistribute ipv6 {{ protocol }} {{ level | replace('_', '-') }} route-map {{ level_config.route_map }}
+{% else %}
+ redistribute ipv6 {{ protocol }} {{ level | replace('_', '-') }}
+{% endif %}
+{% endfor %}
+{% endfor %}
+{% endif %}
{% endif %}
{% if level is defined and level is not none %}
-{% if level == 'level-1' %}
- is-type level-1
-{% elif level == 'level-2' %}
+{% if level == 'level-2' %}
is-type level-2-only
-{% elif level == 'level-1-2' %}
- is-type level-1-2
+{% else %}
+ is-type {{ level }}
{% endif %}
{% endif %}
!
@@ -135,6 +156,7 @@ router isis VyOS {{ 'vrf ' + vrf if vrf is defined and vrf is not none }}
{% for iface, iface_config in interface.items() %}
interface {{ iface }} {{ 'vrf ' + vrf if vrf is defined and vrf is not none }}
ip router isis VyOS
+ ipv6 router isis VyOS
{% if iface_config.bfd is defined %}
isis bfd
{% endif %}
@@ -173,4 +195,4 @@ interface {{ iface }} {{ 'vrf ' + vrf if vrf is defined and vrf is not none }}
{% endif %}
{% endfor %}
{% endif %}
-!
+! \ No newline at end of file
diff --git a/data/templates/frr/ospfv3.frr.tmpl b/data/templates/frr/ospfv3.frr.tmpl
index d08972a80..0026c0d2c 100644
--- a/data/templates/frr/ospfv3.frr.tmpl
+++ b/data/templates/frr/ospfv3.frr.tmpl
@@ -50,6 +50,11 @@ router ospf6
interface {{ interface }} area {{ area_id }}
{% endfor %}
{% endif %}
+{% if area_config.area_type is defined and area_config.area_type is not none %}
+{% for type, type_config in area_config.area_type.items() %}
+ area {{ area_id }} {{ type }} {{ 'no-summary' if type_config.no_summary is defined }}
+{% endfor %}
+{% endif %}
{% if area_config.range is defined and area_config.range is not none %}
{% for prefix, prefix_config in area_config.range.items() %}
area {{ area_id }} range {{ prefix }} {{ 'advertise' if prefix_config.advertise is defined }} {{ 'not-advertise' if prefix_config.not_advertise is defined }}
diff --git a/data/templates/frr/policy.frr.tmpl b/data/templates/frr/policy.frr.tmpl
index 881afa21f..b5649b44e 100644
--- a/data/templates/frr/policy.frr.tmpl
+++ b/data/templates/frr/policy.frr.tmpl
@@ -247,11 +247,14 @@ route-map {{ route_map }} {{ rule_config.action }} {{ rule }}
{% if rule_config.set.distance is defined and rule_config.set.distance is not none %}
set distance {{ rule_config.set.distance }}
{% endif %}
-{% if rule_config.set.extcommunity_rt is defined and rule_config.set.extcommunity_rt is not none %}
- set extcommunity rt {{ rule_config.set.extcommunity_rt }}
+{% if rule_config.set.extcommunity is defined and rule_config.set.extcommunity.bandwidth is defined and rule_config.set.extcommunity.bandwidth is not none %}
+ set extcommunity bandwidth {{ rule_config.set.extcommunity.bandwidth }}
{% endif %}
-{% if rule_config.set.extcommunity_soo is defined and rule_config.set.extcommunity_soo is not none %}
- set extcommunity soo {{ rule_config.set.extcommunity_soo }}
+{% if rule_config.set.extcommunity is defined and rule_config.set.extcommunity.rt is defined and rule_config.set.extcommunity.rt is not none %}
+ set extcommunity rt {{ rule_config.set.extcommunity.rt }}
+{% endif %}
+{% if rule_config.set.extcommunity is defined and rule_config.set.extcommunity.soo is defined and rule_config.set.extcommunity.soo is not none %}
+ set extcommunity soo {{ rule_config.set.extcommunity.soo }}
{% endif %}
{% if rule_config.set.ip_next_hop is defined and rule_config.set.ip_next_hop is not none %}
set ip next-hop {{ rule_config.set.ip_next_hop }}
@@ -262,6 +265,9 @@ route-map {{ route_map }} {{ rule_config.action }} {{ rule }}
{% if rule_config.set.ipv6_next_hop is defined and rule_config.set.ipv6_next_hop.local is defined and rule_config.set.ipv6_next_hop.local is not none %}
set ipv6 next-hop local {{ rule_config.set.ipv6_next_hop.local }}
{% endif %}
+{% if rule_config.set.ipv6_next_hop is defined and rule_config.set.ipv6_next_hop.prefer_global is defined %}
+ set ipv6 next-hop prefer-global
+{% endif %}
{% if rule_config.set.large_community is defined and rule_config.set.large_community is not none %}
set large-community {{ rule_config.set.large_community }}
{% endif %}
diff --git a/data/templates/https/nginx.default.tmpl b/data/templates/https/nginx.default.tmpl
index 916764410..b40ddcc74 100644
--- a/data/templates/https/nginx.default.tmpl
+++ b/data/templates/https/nginx.default.tmpl
@@ -30,7 +30,8 @@ server {
include {{ server.certbot_dir }}/options-ssl-nginx.conf;
ssl_dhparam {{ server.certbot_dir }}/ssl-dhparams.pem;
{% elif server.vyos_cert %}
- include {{ server.vyos_cert.conf }};
+ ssl_certificate {{ server.vyos_cert.crt }};
+ ssl_certificate_key {{ server.vyos_cert.key }};
{% else %}
#
# Self signed certs generated by the ssl-cert package
@@ -40,7 +41,7 @@ server {
{% endif %}
# proxy settings for HTTP API, if enabled; 503, if not
- location ~ /(retrieve|configure|config-file|image|generate|show|docs|openapi.json|redoc) {
+ location ~ /(retrieve|configure|config-file|image|generate|show|docs|openapi.json|redoc|graphql) {
{% if server.api %}
proxy_pass http://localhost:{{ server.api.port }};
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
diff --git a/data/templates/ipsec/charon/dhcp.conf.tmpl b/data/templates/ipsec/charon/dhcp.conf.tmpl
new file mode 100644
index 000000000..92774b275
--- /dev/null
+++ b/data/templates/ipsec/charon/dhcp.conf.tmpl
@@ -0,0 +1,22 @@
+dhcp {
+ load = yes
+{% if remote_access is defined and remote_access.dhcp is defined %}
+{% if remote_access.dhcp.interface is defined %}
+ interface = {{ remote_access.dhcp.interface }}
+{% endif %}
+{% if remote_access.dhcp.server is defined %}
+ server = {{ remote_access.dhcp.server }}
+{% endif %}
+{% endif %}
+
+ # Always use the configured server address.
+ # force_server_address = no
+
+ # Derive user-defined MAC address from hash of IKE identity and send client
+ # identity DHCP option.
+ # identity_lease = no
+
+ # Use the DHCP server port (67) as source port when a unicast server address
+ # is configured.
+ # use_server_port = no
+}
diff --git a/data/templates/ipsec/charon/eap-radius.conf.tmpl b/data/templates/ipsec/charon/eap-radius.conf.tmpl
new file mode 100644
index 000000000..5ec35c988
--- /dev/null
+++ b/data/templates/ipsec/charon/eap-radius.conf.tmpl
@@ -0,0 +1,115 @@
+eap-radius {
+ # Send RADIUS accounting information to RADIUS servers.
+ # accounting = no
+
+ # Close the IKE_SA if there is a timeout during interim RADIUS accounting
+ # updates.
+ # accounting_close_on_timeout = yes
+
+ # Interval in seconds for interim RADIUS accounting updates, if not
+ # specified by the RADIUS server in the Access-Accept message.
+ # accounting_interval = 0
+
+ # If enabled, accounting is disabled unless an IKE_SA has at least one
+ # virtual IP. Only for IKEv2, for IKEv1 a virtual IP is strictly necessary.
+ # accounting_requires_vip = no
+
+ # If enabled, adds the Class attributes received in Access-Accept message to
+ # the RADIUS accounting messages.
+ # accounting_send_class = no
+
+ # Use class attributes in Access-Accept messages as group membership
+ # information.
+ # class_group = no
+
+ # Closes all IKE_SAs if communication with the RADIUS server times out. If
+ # it is not set only the current IKE_SA is closed.
+ # close_all_on_timeout = no
+
+ # Send EAP-Start instead of EAP-Identity to start RADIUS conversation.
+ # eap_start = no
+
+ # Use filter_id attribute as group membership information.
+ # filter_id = no
+
+ # Prefix to EAP-Identity, some AAA servers use a IMSI prefix to select the
+ # EAP method.
+ # id_prefix =
+
+ # Whether to load the plugin. Can also be an integer to increase the
+ # priority of this plugin.
+ load = yes
+
+ # NAS-Identifier to include in RADIUS messages.
+ nas_identifier = {{ remote_access.radius.nas_identifier if remote_access is defined and remote_access.radius is defined and remote_access.radius.nas_identifier is defined else 'strongSwan' }}
+
+ # Port of RADIUS server (authentication).
+ # port = 1812
+
+ # Base to use for calculating exponential back off.
+ # retransmit_base = 1.4
+
+ # Timeout in seconds before sending first retransmit.
+ # retransmit_timeout = 2.0
+
+ # Number of times to retransmit a packet before giving up.
+ # retransmit_tries = 4
+
+ # Shared secret between RADIUS and NAS. If set, make sure to adjust the
+ # permissions of the config file accordingly.
+ # secret =
+
+ # IP/Hostname of RADIUS server.
+ # server =
+
+ # Number of sockets (ports) to use, increase for high load.
+ # sockets = 1
+
+ # Whether to include the UDP port in the Called- and Calling-Station-Id
+ # RADIUS attributes.
+ # station_id_with_port = yes
+
+ dae {
+ # Enables support for the Dynamic Authorization Extension (RFC 5176).
+ # enable = no
+
+ # Address to listen for DAE messages from the RADIUS server.
+ # listen = 0.0.0.0
+
+ # Port to listen for DAE requests.
+ # port = 3799
+
+ # Shared secret used to verify/sign DAE messages. If set, make sure to
+ # adjust the permissions of the config file accordingly.
+ # secret =
+ }
+
+ forward {
+ # RADIUS attributes to be forwarded from IKEv2 to RADIUS.
+ # ike_to_radius =
+
+ # Same as ike_to_radius but from RADIUS to IKEv2.
+ # radius_to_ike =
+ }
+
+ # Section to specify multiple RADIUS servers.
+ servers {
+{% if remote_access is defined and remote_access.radius is defined and remote_access.radius.server is defined %}
+{% for server, server_options in remote_access.radius.server.items() if server_options.disable is not defined %}
+ {{ server | replace('.', '-') }} {
+ address = {{ server }}
+ secret = {{ server_options.key }}
+ auth_port = {{ server_options.port }}
+{% if server_options.disable_accounting is not defined %}
+ acct_port = {{ server_options.port | int +1 }}
+{% endif %}
+ sockets = 20
+ }
+{% endfor %}
+{% endif %}
+ }
+
+ # Section to configure multiple XAuth authentication rounds via RADIUS.
+ xauth {
+ }
+}
diff --git a/data/templates/ipsec/interfaces_use.conf.tmpl b/data/templates/ipsec/interfaces_use.conf.tmpl
new file mode 100644
index 000000000..a77102396
--- /dev/null
+++ b/data/templates/ipsec/interfaces_use.conf.tmpl
@@ -0,0 +1,5 @@
+{% if interface is defined %}
+charon {
+ interfaces_use = {{ ', '.join(interface) }}
+}
+{% endif %} \ No newline at end of file
diff --git a/data/templates/ipsec/ios_profile.tmpl b/data/templates/ipsec/ios_profile.tmpl
new file mode 100644
index 000000000..af6c79d6e
--- /dev/null
+++ b/data/templates/ipsec/ios_profile.tmpl
@@ -0,0 +1,104 @@
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <!-- Set the name to whatever you like, it is used in the profile list on the device -->
+ <key>PayloadDisplayName</key>
+ <string>{{ profile_name }}</string>
+ <!-- This is a reverse-DNS style unique identifier used to detect duplicate profiles -->
+ <key>PayloadIdentifier</key>
+ <string>{{ rfqdn }}</string>
+ <!-- A globally unique identifier, use uuidgen on Linux/Mac OS X to generate it -->
+ <key>PayloadUUID</key>
+ <string>{{ '' | get_uuid }}</string>
+ <key>PayloadType</key>
+ <string>Configuration</string>
+ <key>PayloadVersion</key>
+ <integer>1</integer>
+ <key>PayloadContent</key>
+ <array>
+ <!-- It is possible to add multiple VPN payloads with different identifiers/UUIDs and names -->
+ <dict>
+ <!-- This is an extension of the identifier given above -->
+ <key>PayloadIdentifier</key>
+ <string>{{ rfqdn }}.conf1</string>
+ <!-- A globally unique identifier for this payload -->
+ <key>PayloadUUID</key>
+ <string>{{ '' | get_uuid }}</string>
+ <key>PayloadType</key>
+ <string>com.apple.vpn.managed</string>
+ <key>PayloadVersion</key>
+ <integer>1</integer>
+ <!-- This is the name of the VPN connection as seen in the VPN application later -->
+ <key>UserDefinedName</key>
+ <string>{{ vpn_name }}</string>
+ <key>VPNType</key>
+ <string>IKEv2</string>
+ <key>IKEv2</key>
+ <dict>
+ <!-- Hostname or IP address of the VPN server -->
+ <key>RemoteAddress</key>
+ <string>{{ remote }}</string>
+ <!-- Remote identity, can be a FQDN, a userFQDN, an IP or (theoretically) a certificate's subject DN. Can't be empty.
+ IMPORTANT: DNs are currently not handled correctly, they are always sent as identities of type FQDN -->
+ <key>RemoteIdentifier</key>
+ <string>{{ authentication.id if authentication.id is defined else 'fooo' }}</string>
+ <!-- Local IKE identity, same restrictions as above. If it is empty the client's IP address will be used -->
+ <key>LocalIdentifier</key>
+ <string></string>
+ <!-- Optional, if it matches the CN of the root CA certificate (not the full subject DN) a certificate request will be sent
+ NOTE: If this is not configured make sure to configure leftsendcert=always on the server, otherwise it won't send its certificate -->
+ <key>ServerCertificateIssuerCommonName</key>
+ <string>{{ ca_cn }}</string>
+ <!-- Optional, the CN or one of the subjectAltNames of the server certificate to verify it, if not set RemoteIdentifier will be used -->
+ <key>ServerCertificateCommonName</key>
+ <string>{{ cert_cn }}</string>
+ <!-- The server is authenticated using a certificate -->
+ <key>AuthenticationMethod</key>
+ <string>Certificate</string>
+ <!-- The client uses EAP to authenticate -->
+ <key>ExtendedAuthEnabled</key>
+ <integer>1</integer>
+ <!-- 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>
+ <dict>
+ <!-- @see https://developer.apple.com/documentation/networkextension/nevpnikev2encryptionalgorithm -->
+ <key>EncryptionAlgorithm</key>
+ <string>{{ ike_encryption.encryption }}</string>
+ <!-- @see https://developer.apple.com/documentation/networkextension/nevpnikev2integrityalgorithm -->
+ <key>IntegrityAlgorithm</key>
+ <string>{{ ike_encryption.hash }}</string>
+ <!-- @see https://developer.apple.com/documentation/networkextension/nevpnikev2diffiehellmangroup -->
+ <key>DiffieHellmanGroup</key>
+ <integer>{{ ike_encryption.dh_group }}</integer>
+ </dict>
+ <key>ChildSecurityAssociationParameters</key>
+ <dict>
+ <key>EncryptionAlgorithm</key>
+ <string>{{ esp_encryption.encryption }}</string>
+ <key>IntegrityAlgorithm</key>
+ <string>{{ esp_encryption.hash }}</string>
+ <key>DiffieHellmanGroup</key>
+ <integer>{{ ike_encryption.dh_group }}</integer>
+ </dict>
+ </dict>
+ </dict>
+ <!-- This payload is optional but it provides an easy way to install the CA certificate together with the configuration -->
+ <dict>
+ <key>PayloadIdentifier</key>
+ <string>org.example.ca</string>
+ <key>PayloadUUID</key>
+ <string>{{ '' | get_uuid }}</string>
+ <key>PayloadType</key>
+ <string>com.apple.security.root</string>
+ <key>PayloadVersion</key>
+ <integer>1</integer>
+ <!-- This is the Base64 (PEM) encoded CA certificate -->
+ <key>PayloadContent</key>
+ <data>
+ {{ ca_cert }}
+ </data>
+ </dict>
+ </array>
+</dict>
+</plist>
diff --git a/data/templates/ipsec/ipsec.conf.tmpl b/data/templates/ipsec/ipsec.conf.tmpl
index d0b60765b..1cb531e76 100644
--- a/data/templates/ipsec/ipsec.conf.tmpl
+++ b/data/templates/ipsec/ipsec.conf.tmpl
@@ -1,3 +1,18 @@
-{{delim_ipsec_l2tp_begin}}
-include {{ipsec_ra_conn_file}}
-{{delim_ipsec_l2tp_end}}
+# Created by VyOS - manual changes will be overwritten
+
+config setup
+{% set charondebug = '' %}
+{% if log is defined and log.subsystem is defined and log.subsystem is not none %}
+{% set subsystem = log.subsystem %}
+{% if 'any' in log.subsystem %}
+{% set subsystem = ['dmn', 'mgr', 'ike', 'chd','job', 'cfg', 'knl', 'net', 'asn',
+ 'enc', 'lib', 'esp', 'tls', 'tnc', 'imc', 'imv', 'pts'] %}
+{% endif %}
+{% set charondebug = subsystem | join (' ' ~ log.level ~ ', ') ~ ' ' ~ log.level %}
+{% endif %}
+ charondebug = "{{ charondebug }}"
+ uniqueids = {{ "no" if disable_uniqreqids is defined else "yes" }}
+
+{% if include_ipsec_conf is defined %}
+include {{ include_ipsec_conf }}
+{% endif %}
diff --git a/data/templates/ipsec/ipsec.secrets.tmpl b/data/templates/ipsec/ipsec.secrets.tmpl
index 55c010a3b..057e291ed 100644
--- a/data/templates/ipsec/ipsec.secrets.tmpl
+++ b/data/templates/ipsec/ipsec.secrets.tmpl
@@ -1,7 +1,5 @@
-{{delim_ipsec_l2tp_begin}}
-{% if ipsec_l2tp_auth_mode == 'pre-shared-secret' %}
-{{outside_addr}} %any : PSK "{{ipsec_l2tp_secret}}"
-{% elif ipsec_l2tp_auth_mode == 'x509' %}
-: RSA {{server_key_file_copied}}
-{% endif%}
-{{delim_ipsec_l2tp_end}}
+# Created by VyOS - manual changes will be overwritten
+
+{% if include_ipsec_secrets is defined %}
+include {{ include_ipsec_secrets }}
+{% endif %}
diff --git a/data/templates/ipsec/remote-access.tmpl b/data/templates/ipsec/remote-access.tmpl
deleted file mode 100644
index fae48232f..000000000
--- a/data/templates/ipsec/remote-access.tmpl
+++ /dev/null
@@ -1,28 +0,0 @@
-{{delim_ipsec_l2tp_begin}}
-conn {{ra_conn_name}}
- type=transport
- left={{outside_addr}}
- leftsubnet=%dynamic[/1701]
- rightsubnet=%dynamic
- mark_in=%unique
- auto=add
- ike=aes256-sha1-modp1024,3des-sha1-modp1024,3des-sha1-modp1024!
- dpddelay=15
- dpdtimeout=45
- dpdaction=clear
- esp=aes256-sha1,3des-sha1!
- rekey=no
-{% if ipsec_l2tp_auth_mode == 'pre-shared-secret' %}
- authby=secret
- leftauth=psk
- rightauth=psk
-{% elif ipsec_l2tp_auth_mode == 'x509' %}
- authby=rsasig
- leftrsasigkey=%cert
- rightrsasigkey=%cert
- rightca=%same
- leftcert={{server_cert_file_copied}}
-{% endif %}
- ikelifetime={{ipsec_l2tp_ike_lifetime}}
- keylife={{ipsec_l2tp_lifetime}}
-{{delim_ipsec_l2tp_end}}
diff --git a/data/templates/ipsec/swanctl.conf.tmpl b/data/templates/ipsec/swanctl.conf.tmpl
new file mode 100644
index 000000000..161f19f95
--- /dev/null
+++ b/data/templates/ipsec/swanctl.conf.tmpl
@@ -0,0 +1,131 @@
+### Autogenerated by vpn_ipsec.py ###
+{% import 'ipsec/swanctl/l2tp.tmpl' as l2tp_tmpl %}
+{% import 'ipsec/swanctl/profile.tmpl' as profile_tmpl %}
+{% import 'ipsec/swanctl/peer.tmpl' as peer_tmpl %}
+{% import 'ipsec/swanctl/remote_access.tmpl' as remote_access_tmpl %}
+
+connections {
+{% if profile is defined %}
+{% for name, profile_conf in profile.items() if profile_conf.disable is not defined and profile_conf.bind is defined and profile_conf.bind.tunnel is defined %}
+{{ profile_tmpl.conn(name, profile_conf, ike_group, esp_group) }}
+{% endfor %}
+{% endif %}
+{% if site_to_site is defined and site_to_site.peer is defined %}
+{% for peer, peer_conf in site_to_site.peer.items() if peer not in dhcp_no_address and peer_conf.disable is not defined %}
+{{ peer_tmpl.conn(peer, peer_conf, ike_group, esp_group) }}
+{% endfor %}
+{% endif %}
+{% if remote_access is defined and remote_access.connection is defined and remote_access.connection is not none %}
+{% for rw, rw_conf in remote_access.connection.items() if rw_conf.disable is not defined %}
+{{ remote_access_tmpl.conn(rw, rw_conf, ike_group, esp_group) }}
+{% endfor %}
+{% endif %}
+{% if l2tp %}
+{{ l2tp_tmpl.conn(l2tp, l2tp_outside_address, l2tp_ike_default, l2tp_esp_default, ike_group, esp_group) }}
+{% endif %}
+}
+
+pools {
+{% if remote_access is defined and remote_access.pool is defined and remote_access.pool is not none %}
+{% for pool, pool_config in remote_access.pool.items() %}
+ {{ pool }} {
+{% if pool_config.prefix is defined and pool_config.prefix is not none %}
+ addrs = {{ pool_config.prefix }}
+{% endif %}
+{% if pool_config.name_server is defined and pool_config.name_server is not none %}
+ dns = {{ pool_config.name_server | join(',') }}
+{% endif %}
+{% if pool_config.exclude is defined and pool_config.exclude is not none %}
+ split_exclude = {{ pool_config.exclude | join(',') }}
+{% endif %}
+ }
+{% endfor %}
+{% endif %}
+}
+
+secrets {
+{% if profile is defined %}
+{% for name, profile_conf in profile.items() if profile_conf.disable is not defined and profile_conf.bind is defined and profile_conf.bind.tunnel is defined %}
+{% if profile_conf.authentication.mode == 'pre-shared-secret' %}
+{% for interface in profile_conf.bind.tunnel %}
+ ike-dmvpn-{{ interface }} {
+ secret = {{ profile_conf.authentication.pre_shared_secret }}
+ }
+{% endfor %}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if site_to_site is defined and site_to_site.peer is defined %}
+{% for peer, peer_conf in site_to_site.peer.items() if peer not in dhcp_no_address and peer_conf.disable is not defined %}
+{% set peer_name = peer.replace(".", "-").replace("@", "") %}
+{% if peer_conf.authentication.mode == 'pre-shared-secret' %}
+ ike_{{ peer_name }} {
+{% if peer_conf.local_address is defined %}
+ id-local = {{ peer_conf.local_address }} # dhcp:{{ peer_conf.dhcp_interface if 'dhcp_interface' in peer_conf else 'no' }}
+{% endif %}
+ id-remote = {{ peer }}
+{% if peer_conf.authentication.id is defined %}
+ id-localid = {{ peer_conf.authentication.id }}
+{% endif %}
+{% if peer_conf.authentication.remote_id is defined %}
+ id-remoteid = {{ peer_conf.authentication.remote_id }}
+{% endif %}
+ secret = "{{ peer_conf.authentication.pre_shared_secret }}"
+ }
+{% elif peer_conf.authentication.mode == 'x509' %}
+ private_{{ peer_name }} {
+ file = {{ peer_conf.authentication.x509.certificate }}.pem
+{% if peer_conf.authentication.x509.passphrase is defined %}
+ secret = "{{ peer_conf.authentication.x509.passphrase }}"
+{% endif %}
+ }
+{% elif peer_conf.authentication.mode == 'rsa' %}
+ rsa_{{ peer_name }}_local {
+ file = {{ peer_conf.authentication.rsa.local_key }}.pem
+{% if peer_conf.authentication.rsa.passphrase is defined %}
+ secret = "{{ peer_conf.authentication.rsa.passphrase }}"
+{% endif %}
+ }
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if remote_access is defined and remote_access.connection is defined and remote_access.connection is not none %}
+{% for ra, ra_conf in remote_access.connection.items() if ra_conf.disable is not defined %}
+{% if ra_conf.authentication.server_mode == 'pre-shared-secret' %}
+ ike_{{ ra }} {
+{% if ra_conf.authentication.id is defined %}
+ id = "{{ ra_conf.authentication.id }}"
+{% elif ra_conf.local_address is defined %}
+ id = "{{ ra_conf.local_address }}"
+{% endif %}
+ secret = "{{ ra_conf.authentication.pre_shared_secret }}"
+ }
+{% endif %}
+{% if ra_conf.authentication.client_mode == 'eap-mschapv2' and ra_conf.authentication.local_users is defined and ra_conf.authentication.local_users.username is defined %}
+{% for user, user_conf in ra_conf.authentication.local_users.username.items() if user_conf.disable is not defined %}
+ eap-{{ ra }}-{{ user }} {
+ secret = "{{ user_conf.password }}"
+ id-{{ ra }}-{{ user }} = "{{ user }}"
+ }
+{% endfor %}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if l2tp %}
+{% if l2tp.authentication.mode == 'pre-shared-secret' %}
+ ike_l2tp_remote_access {
+ id = "{{ l2tp_outside_address }}"
+ secret = "{{ l2tp.authentication.pre_shared_secret }}"
+ }
+{% elif l2tp.authentication.mode == 'x509' %}
+ private_l2tp_remote_access {
+ id = "{{ l2tp_outside_address }}"
+ file = {{ l2tp.authentication.x509.certificate }}.pem
+{% if l2tp.authentication.x509.passphrase is defined %}
+ secret = "{{ l2tp.authentication.x509.passphrase }}"
+{% endif %}
+ }
+{% endif %}
+{% endif %}
+}
+
diff --git a/data/templates/ipsec/swanctl/l2tp.tmpl b/data/templates/ipsec/swanctl/l2tp.tmpl
new file mode 100644
index 000000000..2df5c2a4d
--- /dev/null
+++ b/data/templates/ipsec/swanctl/l2tp.tmpl
@@ -0,0 +1,30 @@
+{% macro conn(l2tp, l2tp_outside_address, l2tp_ike_default, l2tp_esp_default, ike_group, esp_group) %}
+{% set l2tp_ike = ike_group[l2tp.ike_group] if l2tp.ike_group is defined else None %}
+{% set l2tp_esp = esp_group[l2tp.esp_group] if l2tp.esp_group is defined else None %}
+ l2tp_remote_access {
+ proposals = {{ l2tp_ike | get_esp_ike_cipher | join(',') if l2tp_ike else l2tp_ike_default }}
+ local_addrs = {{ l2tp_outside_address }}
+ dpd_delay = 15s
+ dpd_timeout = 45s
+ rekey_time = {{ l2tp_ike.lifetime if l2tp_ike else l2tp.ike_lifetime }}s
+ reauth_time = 0
+ local {
+ auth = {{ 'psk' if l2tp.authentication.mode == 'pre-shared-secret' else 'pubkey' }}
+{% if l2tp.authentication.mode == 'x509' %}
+ certs = {{ l2tp.authentication.x509.certificate }}.pem
+{% endif %}
+ }
+ remote {
+ auth = {{ 'psk' if l2tp.authentication.mode == 'pre-shared-secret' else 'pubkey' }}
+ }
+ children {
+ l2tp_remote_access_esp {
+ mode = transport
+ esp_proposals = {{ l2tp_esp | get_esp_ike_cipher | join(',') if l2tp_esp else l2tp_esp_default }}
+ life_time = {{ l2tp_esp.lifetime if l2tp_esp else l2tp.lifetime }}s
+ local_ts = dynamic[/1701]
+ remote_ts = dynamic
+ }
+ }
+ }
+{% endmacro %}
diff --git a/data/templates/ipsec/swanctl/peer.tmpl b/data/templates/ipsec/swanctl/peer.tmpl
new file mode 100644
index 000000000..dd29ea7d4
--- /dev/null
+++ b/data/templates/ipsec/swanctl/peer.tmpl
@@ -0,0 +1,134 @@
+{% macro conn(peer, peer_conf, ike_group, esp_group) %}
+{% set name = peer.replace(".", "-").replace("@", "") %}
+{# peer needs to reference the global IKE configuration for certain values #}
+{% set ike = ike_group[peer_conf.ike_group] %}
+ peer_{{ name }} {
+ proposals = {{ ike | get_esp_ike_cipher | join(',') }}
+ version = {{ ike.key_exchange[4:] if ike is defined and ike.key_exchange is defined else "0" }}
+ local_addrs = {{ peer_conf.local_address if peer_conf.local_address != 'any' else '0.0.0.0/0' }} # dhcp:{{ peer_conf.dhcp_interface if 'dhcp_interface' in peer_conf else 'no' }}
+ remote_addrs = {{ peer if peer not in ['any', '0.0.0.0'] and peer[0:1] != '@' else '0.0.0.0/0' }}
+{% if peer_conf.authentication is defined and peer_conf.authentication.mode is defined and peer_conf.authentication.mode == 'x509' %}
+ send_cert = always
+{% endif %}
+{% if ike.dead_peer_detection is defined %}
+ dpd_timeout = {{ ike.dead_peer_detection.timeout }}
+ dpd_delay = {{ ike.dead_peer_detection.interval }}
+{% endif %}
+{% if ike.key_exchange is defined and ike.key_exchange == "ikev1" and ike.mode is defined and ike.mode == "aggressive" %}
+ aggressive = yes
+{% endif %}
+ mobike = {{ "yes" if ike.mobike is not defined or ike.mobike == "enable" else "no" }}
+{% if peer[0:1] == '@' %}
+ keyingtries = 0
+ rekey_time = 0
+ reauth_time = 0
+{% elif peer_conf.connection_type is not defined or peer_conf.connection_type == 'initiate' %}
+ keyingtries = 0
+{% elif peer_conf.connection_type is defined and peer_conf.connection_type == 'respond' %}
+ keyingtries = 1
+{% endif %}
+{% if peer_conf.force_encapsulation is defined and peer_conf.force_encapsulation == 'enable' %}
+ encap = yes
+{% endif %}
+ local {
+{% if peer_conf.authentication is defined and peer_conf.authentication.id is defined and peer_conf.authentication.use_x509_id is not defined %}
+ id = "{{ peer_conf.authentication.id }}"
+{% endif %}
+ auth = {{ 'psk' if peer_conf.authentication.mode == 'pre-shared-secret' else 'pubkey' }}
+{% if peer_conf.authentication.mode == 'x509' %}
+ certs = {{ peer_conf.authentication.x509.certificate }}.pem
+{% elif peer_conf.authentication.mode == 'rsa' %}
+ pubkeys = {{ peer_conf.authentication.rsa.local_key }}.pem
+{% endif %}
+ }
+ remote {
+{% if peer_conf.authentication.remote_id is defined %}
+ id = "{{ peer_conf.authentication.remote_id }}"
+{% elif peer[0:1] == '@' %}
+ id = "{{ peer }}"
+{% endif %}
+ auth = {{ 'psk' if peer_conf.authentication.mode == 'pre-shared-secret' else 'pubkey' }}
+{% if peer_conf.authentication.mode == 'rsa' %}
+ pubkeys = {{ peer_conf.authentication.rsa.remote_key }}.pem
+{% endif %}
+ }
+ children {
+{% if peer_conf.vti is defined and peer_conf.vti.bind is defined and peer_conf.tunnel is not defined %}
+{% set vti_esp = esp_group[ peer_conf.vti.esp_group ] if peer_conf.vti.esp_group is defined else esp_group[ peer_conf.default_esp_group ] %}
+ peer_{{ name }}_vti {
+ esp_proposals = {{ vti_esp | get_esp_ike_cipher | join(',') }}
+ local_ts = 0.0.0.0/0,::/0
+ remote_ts = 0.0.0.0/0,::/0
+ updown = "/etc/ipsec.d/vti-up-down {{ peer_conf.vti.bind }} {{ peer_conf.dhcp_interface if peer_conf.dhcp_interface is defined else 'no' }}"
+ if_id_in = {{ peer_conf.vti.bind | replace('vti', '') }}
+ if_id_out = {{ peer_conf.vti.bind | replace('vti', '') }}
+ ipcomp = {{ 'yes' if vti_esp.compression is defined and vti_esp.compression == 'enable' else 'no' }}
+ mode = {{ vti_esp.mode }}
+{% if peer[0:1] == '@' %}
+ start_action = none
+{% elif peer_conf.connection_type is not defined or peer_conf.connection_type == 'initiate' %}
+ start_action = start
+{% elif peer_conf.connection_type == 'respond' %}
+ start_action = trap
+{% endif %}
+{% if ike.dead_peer_detection is defined %}
+{% set dpd_translate = {'clear': 'clear', 'hold': 'trap', 'restart': 'start'} %}
+ dpd_action = {{ dpd_translate[ike.dead_peer_detection.action] }}
+{% endif %}
+ }
+{% elif peer_conf.tunnel is defined %}
+{% for tunnel_id, tunnel_conf in peer_conf.tunnel.items() if tunnel_conf.disable is not defined %}
+{% set tunnel_esp_name = tunnel_conf.esp_group if tunnel_conf.esp_group is 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 defined else '' %}
+{% set local_port = tunnel_conf.local.port if tunnel_conf.local is defined and tunnel_conf.local.port is 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 is defined and tunnel_conf.remote.port is defined else '' %}
+{% set remote_suffix = '[{0}/{1}]'.format(proto, remote_port) if proto or remote_port else '' %}
+ peer_{{ name }}_tunnel_{{ tunnel_id }} {
+ esp_proposals = {{ tunnel_esp | get_esp_ike_cipher | join(',') }}
+{% if tunnel_esp.mode is not defined or tunnel_esp.mode == 'tunnel' %}
+{% if tunnel_conf.local is defined and tunnel_conf.local.prefix is defined %}
+{% set local_prefix = tunnel_conf.local.prefix if 'any' not in tunnel_conf.local.prefix else ['0.0.0.0/0', '::/0'] %}
+ local_ts = {{ local_prefix | join(local_suffix + ",") }}{{ local_suffix }}
+{% endif %}
+{% if tunnel_conf.remote is defined and tunnel_conf.remote.prefix is defined %}
+{% set remote_prefix = tunnel_conf.remote.prefix if 'any' not in tunnel_conf.remote.prefix else ['0.0.0.0/0', '::/0'] %}
+ remote_ts = {{ remote_prefix | join(remote_suffix + ",") }}{{ remote_suffix }}
+{% endif %}
+{% elif tunnel_esp.mode == 'transport' %}
+ local_ts = {{ peer_conf.local_address }}{{ local_suffix }}
+ remote_ts = {{ peer }}{{ remote_suffix }}
+{% endif %}
+ ipcomp = {{ 'yes' if tunnel_esp.compression is defined and tunnel_esp.compression == 'enable' else 'no' }}
+ mode = {{ tunnel_esp.mode }}
+{% if peer[0:1] == '@' %}
+ start_action = none
+{% elif peer_conf.connection_type is not defined or peer_conf.connection_type == 'initiate' %}
+ start_action = start
+{% elif peer_conf.connection_type == 'respond' %}
+ start_action = trap
+{% endif %}
+{% if ike.dead_peer_detection is defined %}
+{% set dpd_translate = {'clear': 'clear', 'hold': 'trap', 'restart': 'start'} %}
+ dpd_action = {{ dpd_translate[ike.dead_peer_detection.action] }}
+{% endif %}
+{% if peer_conf.vti is defined and peer_conf.vti.bind is defined %}
+ updown = "/etc/ipsec.d/vti-up-down {{ peer_conf.vti.bind }} {{ peer_conf.dhcp_interface if peer_conf.dhcp_interface is defined else 'no' }}"
+ if_id_in = {{ peer_conf.vti.bind | replace('vti', '') }}
+ if_id_out = {{ peer_conf.vti.bind | replace('vti', '') }}
+{% endif %}
+ }
+{% if tunnel_conf.passthrough is defined and tunnel_conf.passthrough %}
+ peer_{{ name }}_tunnel_{{ tunnel_id }}_passthough {
+ local_ts = {{ tunnel_conf.passthrough | join(",") }}
+ remote_ts = {{ tunnel_conf.passthrough | join(",") }}
+ start_action = trap
+ mode = pass
+ }
+{% endif %}
+{% endfor %}
+{% endif %}
+ }
+ }
+{% endmacro %}
diff --git a/data/templates/ipsec/swanctl/profile.tmpl b/data/templates/ipsec/swanctl/profile.tmpl
new file mode 100644
index 000000000..0a7268405
--- /dev/null
+++ b/data/templates/ipsec/swanctl/profile.tmpl
@@ -0,0 +1,39 @@
+{% macro conn(name, profile_conf, ike_group, esp_group) %}
+{# 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] %}
+{% if profile_conf.bind is defined and profile_conf.bind.tunnel is defined %}
+{% for interface in profile_conf.bind.tunnel %}
+ dmvpn-{{ name }}-{{ interface }} {
+ proposals = {{ ike_group[profile_conf.ike_group] | get_esp_ike_cipher | join(',') }}
+ version = {{ ike.key_exchange[4:] if ike is defined and ike.key_exchange is defined else "0" }}
+ rekey_time = {{ ike.lifetime }}s
+ keyingtries = 0
+{% if profile_conf.authentication is defined and profile_conf.authentication.mode is defined and profile_conf.authentication.mode == 'pre-shared-secret' %}
+ local {
+ auth = psk
+ }
+ remote {
+ auth = psk
+ }
+{% endif %}
+ children {
+ dmvpn {
+ esp_proposals = {{ esp | get_esp_ike_cipher | join(',') }}
+ rekey_time = {{ esp.lifetime }}s
+ rand_time = 540s
+ local_ts = dynamic[gre]
+ remote_ts = dynamic[gre]
+ mode = {{ esp.mode }}
+{% if ike.dead_peer_detection is defined and ike.dead_peer_detection.action is defined %}
+ dpd_action = {{ ike.dead_peer_detection.action }}
+{% endif %}
+{% if esp.compression is defined and esp.compression == 'enable' %}
+ ipcomp = yes
+{% endif %}
+ }
+ }
+ }
+{% endfor %}
+{% endif %}
+{% endmacro %}
diff --git a/data/templates/ipsec/swanctl/remote_access.tmpl b/data/templates/ipsec/swanctl/remote_access.tmpl
new file mode 100644
index 000000000..456842488
--- /dev/null
+++ b/data/templates/ipsec/swanctl/remote_access.tmpl
@@ -0,0 +1,47 @@
+{% macro conn(name, rw_conf, ike_group, esp_group) %}
+{# peer needs to reference the global IKE configuration for certain values #}
+{% set ike = ike_group[rw_conf.ike_group] %}
+{% set esp = esp_group[rw_conf.esp_group] %}
+ ra-{{ name }} {
+ remote_addrs = %any
+ local_addrs = {{ rw_conf.local_address if rw_conf.local_address is defined else '%any' }}
+ proposals = {{ ike_group[rw_conf.ike_group] | get_esp_ike_cipher | join(',') }}
+ version = {{ ike.key_exchange[4:] if ike is defined and ike.key_exchange is defined else "0" }}
+ send_certreq = no
+ rekey_time = {{ ike.lifetime }}s
+ keyingtries = 0
+ unique = {{ rw_conf.unique }}
+{% if rw_conf.pool is defined and rw_conf.pool is not none %}
+ pools = {{ rw_conf.pool | join(',') }}
+{% endif %}
+ local {
+{% if rw_conf.authentication.id is defined and rw_conf.authentication.use_x509_id is not defined %}
+ id = "{{ rw_conf.authentication.id }}"
+{% endif %}
+{% if rw_conf.authentication.server_mode == 'x509' %}
+ auth = pubkey
+ certs = {{ rw_conf.authentication.x509.certificate }}.pem
+{% elif rw_conf.authentication.server_mode == 'pre-shared-secret' %}
+ auth = psk
+{% endif %}
+ }
+ remote {
+ auth = {{ rw_conf.authentication.client_mode }}
+{% if rw_conf.authentication.client_mode.startswith("eap") %}
+ eap_id = %any
+{% endif %}
+ }
+ children {
+ ikev2-vpn {
+ esp_proposals = {{ esp | get_esp_ike_cipher | join(',') }}
+ rekey_time = {{ esp.lifetime }}s
+ rand_time = 540s
+ dpd_action = clear
+{% set local_prefix = rw_conf.local.prefix if rw_conf.local is defined and rw_conf.local.prefix is defined else ['0.0.0.0/0', '::/0'] %}
+{% set local_port = rw_conf.local.port if rw_conf.local is defined and rw_conf.local.port is defined else '' %}
+{% set local_suffix = '[%any/{1}]'.format(local_port) if local_port else '' %}
+ local_ts = {{ local_prefix | join(local_suffix + ",") }}{{ local_suffix }}
+ }
+ }
+ }
+{% endmacro %}
diff --git a/data/templates/ipsec/windows_profile.tmpl b/data/templates/ipsec/windows_profile.tmpl
new file mode 100644
index 000000000..8c26944be
--- /dev/null
+++ b/data/templates/ipsec/windows_profile.tmpl
@@ -0,0 +1,4 @@
+Remove-VpnConnection -Name "{{ vpn_name }}" -Force -PassThru
+
+Add-VpnConnection -Name "{{ vpn_name }}" -ServerAddress "{{ remote }}" -TunnelType "Ikev2"
+Set-VpnConnectionIPsecConfiguration -ConnectionName "{{ vpn_name }}" -AuthenticationTransformConstants {{ ike_encryption.encryption }} -CipherTransformConstants {{ ike_encryption.encryption }} -EncryptionMethod {{ esp_encryption.encryption }} -IntegrityCheckMethod {{ esp_encryption.hash }} -PfsGroup None -DHGroup "Group{{ ike_encryption.dh_group }}" -PassThru -Force
diff --git a/data/templates/nhrp/opennhrp.conf.tmpl b/data/templates/nhrp/opennhrp.conf.tmpl
new file mode 100644
index 000000000..948327198
--- /dev/null
+++ b/data/templates/nhrp/opennhrp.conf.tmpl
@@ -0,0 +1,41 @@
+# Created by VyOS - manual changes will be overwritten
+
+{% if tunnel is defined and tunnel is not none %}
+{% for name, tunnel_conf in tunnel.items() %}
+{% set type = 'spoke' if tunnel_conf.map is defined or tunnel_conf.dynamic_map is defined else 'hub' %}
+{% set profile_name = profile_map[name] if profile_map is defined and name in profile_map else '' %}
+interface {{ name }} #{{ type }} {{ profile_name }}
+{% if tunnel_conf.map is defined and tunnel_conf.map is not none %}
+{% for map, map_conf in tunnel_conf.map.items() %}
+{% set cisco = ' cisco' if map_conf.cisco is defined else '' %}
+{% set register = ' register' if map_conf.register is defined else '' %}
+ map {{ map }} {{ map_conf.nbma_address }}{{ register }}{{ cisco }}
+{% endfor %}
+{% endif %}
+{% if tunnel_conf.dynamic_map is defined and tunnel_conf.dynamic_map is not none %}
+{% for map, map_conf in tunnel_conf.dynamic_map.items() %}
+ dynamic-map {{ map }} {{ map_conf.nbma_domain_name }}
+{% endfor %}
+{% endif %}
+{% if tunnel_conf.cisco_authentication is defined and tunnel_conf.cisco_authentication is not none %}
+ cisco-authentication {{ tunnel_conf.cisco_authentication }}
+{% endif %}
+{% if tunnel_conf.holding_time is defined and tunnel_conf.holding_time is not none %}
+ holding-time {{ tunnel_conf.holding_time }}
+{% endif %}
+{% if tunnel_conf.multicast is defined and tunnel_conf.multicast is not none %}
+ multicast {{ tunnel_conf.multicast }}
+{% endif %}
+{% for key in ['non_caching', 'redirect', 'shortcut', 'shortcut_destination'] %}
+{% if key in tunnel_conf %}
+ {{ key | replace("_", "-") }}
+{% endif %}
+{% endfor %}
+{% if tunnel_conf.shortcut_target is defined and tunnel_conf.shortcut_target is not none %}
+{% for target, shortcut_conf in tunnel_conf.shortcut_target.items() %}
+ shortcut-target {{ target }} {{ shortcut_conf.holding_time if shortcut_conf.holding_time is defined else '' }}
+{% endfor %}
+{% endif %}
+
+{% endfor %}
+{% endif %}
diff --git a/data/templates/ocserv/ocserv_config.tmpl b/data/templates/ocserv/ocserv_config.tmpl
index 328af0c0d..0be805235 100644
--- a/data/templates/ocserv/ocserv_config.tmpl
+++ b/data/templates/ocserv/ocserv_config.tmpl
@@ -12,16 +12,16 @@ auth = "radius [config=/run/ocserv/radiusclient.conf]"
auth = "plain[/run/ocserv/ocpasswd]"
{% endif %}
-{% if ssl.cert_file %}
-server-cert = {{ ssl.cert_file }}
+{% if ssl.certificate is defined %}
+server-cert = /run/ocserv/cert.pem
+server-key = /run/ocserv/cert.key
+{% if ssl.passphrase is defined %}
+key-pin = {{ ssl.passphrase }}
{% endif %}
-
-{% if ssl.key_file %}
-server-key = {{ ssl.key_file }}
{% endif %}
-{% if ssl.ca_cert_file %}
-ca-cert = {{ ssl.ca_cert_file }}
+{% if ssl.ca_certificate is defined %}
+ca-cert = /run/ocserv/ca.pem
{% endif %}
socket-file = /run/ocserv/ocserv.socket
diff --git a/data/templates/openvpn/server.conf.tmpl b/data/templates/openvpn/server.conf.tmpl
index 79288e40f..d9f01310e 100644
--- a/data/templates/openvpn/server.conf.tmpl
+++ b/data/templates/openvpn/server.conf.tmpl
@@ -12,7 +12,6 @@ group {{ daemon_group }}
dev-type {{ device_type }}
dev {{ ifname }}
persist-key
-iproute /usr/libexec/vyos/system/unpriv-ip
{% if protocol == 'tcp-active' %}
proto tcp-client
{% elif protocol == 'tcp-passive' %}
@@ -37,8 +36,8 @@ rport {{ remote_port }}
remote {{ remote }}
{% endfor %}
{% endif %}
-{% if shared_secret_key_file is defined and shared_secret_key_file is not none %}
-secret {{ shared_secret_key_file }}
+{% if shared_secret_key is defined and shared_secret_key is not none %}
+secret /run/openvpn/{{ ifname }}_shared.key
{% endif %}
{% if persistent_tunnel is defined %}
persist-tun
@@ -158,32 +157,32 @@ ifconfig-ipv6 {{ laddr }} {{ raddr }}
{% if tls is defined and tls is not none %}
# TLS options
-{% if tls.ca_cert_file is defined and tls.ca_cert_file is not none %}
-ca {{ tls.ca_cert_file }}
+{% if tls.ca_certificate is defined and tls.ca_certificate is not none %}
+ca /run/openvpn/{{ ifname }}_ca.pem
{% endif %}
-{% if tls.cert_file is defined and tls.cert_file is not none %}
-cert {{ tls.cert_file }}
+{% if tls.certificate is defined and tls.certificate is not none %}
+cert /run/openvpn/{{ ifname }}_cert.pem
{% endif %}
-{% if tls.key_file is defined and tls.key_file is not none %}
-key {{ tls.key_file }}
+{% if tls.private_key is defined %}
+key /run/openvpn/{{ ifname }}_cert.key
{% endif %}
-{% if tls.crypt_file is defined and tls.crypt_file is not none %}
-tls-crypt {{ tls.crypt_file }}
+{% if tls.crypt_key is defined and tls.crypt_key is not none %}
+tls-crypt /run/openvpn/{{ ifname }}_crypt.key
{% endif %}
-{% if tls.crl_file is defined and tls.crl_file is not none %}
-crl-verify {{ tls.crl_file }}
+{% if tls.crl is defined %}
+crl-verify /run/openvpn/{{ ifname }}_crl.pem
{% endif %}
{% if tls.tls_version_min is defined and tls.tls_version_min is not none %}
tls-version-min {{ tls.tls_version_min }}
{% endif %}
-{% if tls.dh_file is defined and tls.dh_file is not none %}
-dh {{ tls.dh_file }}
+{% if tls.dh_params is defined and tls.dh_params is not none %}
+dh /run/openvpn/{{ ifname }}_dh.pem
{% endif %}
-{% if tls.auth_file is defined and tls.auth_file is not none %}
+{% if tls.auth_key is defined and tls.auth_key is not none %}
{% if mode == 'client' %}
-tls-auth {{ tls.auth_file }} 1
+tls-auth /run/openvpn/{{ ifname }}_auth.key 1
{% elif mode == 'server' %}
-tls-auth {{ tls.auth_file }} 0
+tls-auth /run/openvpn/{{ ifname }}_auth.key 0
{% endif %}
{% endif %}
{% if tls.role is defined and tls.role is not none %}
@@ -198,58 +197,15 @@ tls-server
# Encryption options
{% if encryption is defined and encryption is not none %}
{% if encryption.cipher is defined and encryption.cipher is not none %}
-{% if encryption.cipher == 'none' %}
-cipher none
-{% elif encryption.cipher == 'des' %}
-cipher des-cbc
-{% elif encryption.cipher == '3des' %}
-cipher des-ede3-cbc
-{% elif encryption.cipher == 'bf128' %}
-cipher bf-cbc
+cipher {{ encryption.cipher | openvpn_cipher }}
+{% if encryption.cipher == 'bf128' %}
keysize 128
{% elif encryption.cipher == 'bf256' %}
-cipher bf-cbc
-keysize 25
-{% elif encryption.cipher == 'aes128gcm' %}
-cipher aes-128-gcm
-{% elif encryption.cipher == 'aes128' %}
-cipher aes-128-cbc
-{% elif encryption.cipher == 'aes192gcm' %}
-cipher aes-192-gcm
-{% elif encryption.cipher == 'aes192' %}
-cipher aes-192-cbc
-{% elif encryption.cipher == 'aes256gcm' %}
-cipher aes-256-gcm
-{% elif encryption.cipher == 'aes256' %}
-cipher aes-256-cbc
+keysize 256
{% endif %}
{% endif %}
{% if encryption.ncp_ciphers is defined and encryption.ncp_ciphers is not none %}
-{% set cipher_list = [] %}
-{% for cipher in encryption.ncp_ciphers %}
-{% if cipher == 'none' %}
-{% set cipher_list = cipher_list.append('none') %}
-{% elif cipher == 'des' %}
-{% set cipher_list = cipher_list.append('des-cbc') %}
-{% elif cipher == '3des' %}
-{% set cipher_list = cipher_list.append('des-ede3-cbc') %}
-{% elif cipher == 'aes128' %}
-{% set cipher_list = cipher_list.append('aes-128-cbc') %}
-{% elif cipher == 'aes128gcm' %}
-{% set cipher_list = cipher_list.append('aes-128-gcm') %}
-{% elif cipher == 'aes192' %}
-{% set cipher_list = cipher_list.append('aes-192-cbc') %}
-{% elif cipher == 'aes192gcm' %}
-{% set cipher_list = cipher_list.append('aes-192-gcm') %}
-{% elif cipher == 'aes256' %}
-{% set cipher_list = cipher_list.append('aes-256-cbc') %}
-{% elif cipher == 'aes256gcm' %}
-{% set cipher_list = cipher_list.append('aes-256-gcm') %}
-{% endif %}
-{% endfor %}
-ncp-ciphers {{ cipher_list | join(':') }}:{{ cipher_list | join(':') | upper }}
-{% elif encryption.disable_ncp is defined %}
-ncp-disable
+data-ciphers {{ encryption.ncp_ciphers | openvpn_ncp_ciphers }}
{% endif %}
{% endif %}
@@ -262,20 +218,6 @@ auth-user-pass {{ auth_user_pass_file }}
auth-retry nointeract
{% endif %}
-# DEPRECATED This option will be removed in OpenVPN 2.5
-# Until OpenVPN v2.3 the format of the X.509 Subject fields was formatted like this:
-# /C=US/L=Somewhere/CN=John Doe/emailAddress=john@example.com In addition the old
-# behaviour was to remap any character other than alphanumeric, underscore ('_'),
-# dash ('-'), dot ('.'), and slash ('/') to underscore ('_'). The X.509 Subject
-# string as returned by the tls_id environmental variable, could additionally
-# contain colon (':') or equal ('='). When using the --compat-names option, this
-# old formatting and remapping will be re-enabled again. This is purely implemented
-# for compatibility reasons when using older plug-ins or scripts which does not
-# handle the new formatting or UTF-8 characters.
-#
-# See https://phabricator.vyos.net/T1512
-compat-names
-
{% if openvpn_option is defined and openvpn_option is not none %}
#
# Custom options added by user (not validated)
diff --git a/data/templates/proxy-ndp/ndppd.conf.tmpl b/data/templates/proxy-ndp/ndppd.conf.tmpl
index 0137d8135..ccd1d37ad 100644
--- a/data/templates/proxy-ndp/ndppd.conf.tmpl
+++ b/data/templates/proxy-ndp/ndppd.conf.tmpl
@@ -21,8 +21,8 @@
{% if config.outbound_interface not in global.ndppd_interfaces %}
{% set global.ndppd_interfaces = global.ndppd_interfaces + [config.outbound_interface] %}
{% endif %}
-{% if config.translation.prefix is defined %}
-{% set global.ndppd_prefixs = global.ndppd_prefixs + [{'interface':config.outbound_interface,'rule':config.translation.prefix}] %}
+{% if config.translation.address is defined and config.translation.address | is_ip_network %}
+{% set global.ndppd_prefixs = global.ndppd_prefixs + [{'interface':config.outbound_interface,'rule':config.translation.address}] %}
{% endif %}
{% endif %}
{% endfor %}
diff --git a/data/templates/router-advert/radvd.conf.tmpl b/data/templates/router-advert/radvd.conf.tmpl
index 2fde78fec..88d066491 100644
--- a/data/templates/router-advert/radvd.conf.tmpl
+++ b/data/templates/router-advert/radvd.conf.tmpl
@@ -1,45 +1,64 @@
### Autogenerated by service_router-advert.py ###
{% if interface is defined and interface is not none %}
-{% for iface in interface %}
+{% for iface, iface_config in interface.items() %}
interface {{ iface }} {
IgnoreIfMissing on;
-{% if interface[iface].default_preference is defined and interface[iface].default_preference is not none %}
- AdvDefaultPreference {{ interface[iface].default_preference }};
+{% if iface_config.default_preference is defined and iface_config.default_preference is not none %}
+ AdvDefaultPreference {{ iface_config.default_preference }};
{% endif %}
-{% if interface[iface].managed_flag is defined and interface[iface].managed_flag is not none %}
- AdvManagedFlag {{ 'on' if interface[iface].managed_flag is defined else 'off' }};
+{% if iface_config.managed_flag is defined and iface_config.managed_flag is not none %}
+ AdvManagedFlag {{ 'on' if iface_config.managed_flag is defined else 'off' }};
{% endif %}
-{% if interface[iface].interval.max is defined and interface[iface].interval.max is not none %}
- MaxRtrAdvInterval {{ interface[iface].interval.max }};
+{% if iface_config.interval.max is defined and iface_config.interval.max is not none %}
+ MaxRtrAdvInterval {{ iface_config.interval.max }};
{% endif %}
-{% if interface[iface].interval.min is defined and interface[iface].interval.min is not none %}
- MinRtrAdvInterval {{ interface[iface].interval.min }};
+{% if iface_config.interval.min is defined and iface_config.interval.min is not none %}
+ MinRtrAdvInterval {{ iface_config.interval.min }};
{% endif %}
-{% if interface[iface].reachable_time is defined and interface[iface].reachable_time is not none %}
- AdvReachableTime {{ interface[iface].reachable_time }};
+{% if iface_config.reachable_time is defined and iface_config.reachable_time is not none %}
+ AdvReachableTime {{ iface_config.reachable_time }};
{% endif %}
- AdvIntervalOpt {{ 'off' if interface[iface].no_send_advert is defined else 'on' }};
- AdvSendAdvert {{ 'off' if interface[iface].no_send_advert is defined else 'on' }};
-{% if interface[iface].default_lifetime is defined %}
- AdvDefaultLifetime {{ interface[iface].default_lifetime }};
-{% endif %}
-{% if interface[iface].link_mtu is defined %}
- AdvLinkMTU {{ interface[iface].link_mtu }};
-{% endif %}
- AdvOtherConfigFlag {{ 'on' if interface[iface].other_config_flag is defined else 'off' }};
- AdvRetransTimer {{ interface[iface].retrans_timer }};
- AdvCurHopLimit {{ interface[iface].hop_limit }};
-{% for prefix in interface[iface].prefix %}
+ AdvIntervalOpt {{ 'off' if iface_config.no_send_advert is defined else 'on' }};
+ AdvSendAdvert {{ 'off' if iface_config.no_send_advert is defined else 'on' }};
+{% if iface_config.default_lifetime is defined %}
+ AdvDefaultLifetime {{ iface_config.default_lifetime }};
+{% endif %}
+{% if iface_config.link_mtu is defined %}
+ AdvLinkMTU {{ iface_config.link_mtu }};
+{% endif %}
+ AdvOtherConfigFlag {{ 'on' if iface_config.other_config_flag is defined else 'off' }};
+ AdvRetransTimer {{ iface_config.retrans_timer }};
+ AdvCurHopLimit {{ iface_config.hop_limit }};
+{% if iface_config.route is defined %}
+{% for route, route_options in iface_config.route.items() %}
+ route {{ route }} {
+{% if route_options.valid_lifetime is defined %}
+ AdvRouteLifetime {{ route_options.valid_lifetime }};
+{% endif %}
+{% if route_options.route_preference is defined %}
+ AdvRoutePreference {{ route_options.route_preference }};
+{% endif %}
+ RemoveRoute {{ 'off' if route_options.no_remove_route is defined else 'on' }};
+ };
+{% endfor %}
+{% endif %}
+{% if iface_config.prefix is defined and iface_config.prefix is not none %}
+{% for prefix, prefix_options in iface_config.prefix.items() %}
prefix {{ prefix }} {
- AdvAutonomous {{ 'off' if interface[iface].prefix[prefix].no_autonomous_flag is defined else 'on' }};
- AdvValidLifetime {{ interface[iface].prefix[prefix].valid_lifetime }};
- AdvOnLink {{ 'off' if interface[iface].prefix[prefix].no_on_link_flag is defined else 'on' }};
- AdvPreferredLifetime {{ interface[iface].prefix[prefix].preferred_lifetime }};
+ AdvAutonomous {{ 'off' if prefix_options.no_autonomous_flag is defined else 'on' }};
+ AdvValidLifetime {{ prefix_options.valid_lifetime }};
+ AdvOnLink {{ 'off' if prefix_options.no_on_link_flag is defined else 'on' }};
+ AdvPreferredLifetime {{ prefix_options.preferred_lifetime }};
};
-{% endfor %}
-{% if interface[iface].name_server is defined %}
- RDNSS {{ interface[iface].name_server | join(" ") }} {
+{% endfor %}
+{% endif %}
+{% if iface_config.name_server is defined %}
+ RDNSS {{ iface_config.name_server | join(" ") }} {
+ };
+{% endif %}
+{% if iface_config.dnssl is defined %}
+ DNSSL {{ iface_config.dnssl | join(" ") }} {
};
{% endif %}
};
diff --git a/data/templates/snmp/override.conf.tmpl b/data/templates/snmp/override.conf.tmpl
index 68f5fd931..2ac45a89f 100644
--- a/data/templates/snmp/override.conf.tmpl
+++ b/data/templates/snmp/override.conf.tmpl
@@ -1,13 +1,14 @@
{% set vrf_command = 'ip vrf exec ' + vrf + ' ' if vrf is defined else '' %}
+{% set oid_route_table = ' ' if route_table is sameas true else '-I -ipCidrRouteTable,inetCidrRouteTable' %}
[Unit]
StartLimitIntervalSec=0
After=vyos-router.service
[Service]
Environment=
-Environment="MIBSDIR=/usr/share/snmp/mibs:/usr/share/snmp/mibs/iana:/usr/share/snmp/mibs/ietf:/usr/share/mibs/site:/usr/share/snmp/mibs:/usr/share/mibs/iana:/usr/share/mibs/ietf:/usr/share/mibs/netsnmp"
+Environment="MIBDIRS=/usr/share/snmp/mibs:/usr/share/snmp/mibs/iana:/usr/share/snmp/mibs/ietf:/usr/share/vyos/mibs"
ExecStart=
-ExecStart={{vrf_command}}/usr/sbin/snmpd -LS0-5d -Lf /dev/null -u Debian-snmp -g Debian-snmp -I -ipCidrRouteTable,inetCidrRouteTable -f -p /run/snmpd.pid
+ExecStart={{vrf_command}}/usr/sbin/snmpd -LS0-5d -Lf /dev/null -u Debian-snmp -g Debian-snmp {{oid_route_table}} -f -p /run/snmpd.pid
Restart=always
RestartSec=10
diff --git a/data/templates/system/sysctl.conf.tmpl b/data/templates/system/sysctl.conf.tmpl
new file mode 100644
index 000000000..72af82ee5
--- /dev/null
+++ b/data/templates/system/sysctl.conf.tmpl
@@ -0,0 +1,7 @@
+# autogenerated by system_sysctl.py
+
+{% if parameter is defined and parameter is not none %}
+{% for k, v in parameter.items() %}
+{{ k }} = {{ v.value }}
+{% endfor %}
+{% endif %}
diff --git a/data/templates/wwan/chat.tmpl b/data/templates/wwan/chat.tmpl
deleted file mode 100644
index 386af37e6..000000000
--- a/data/templates/wwan/chat.tmpl
+++ /dev/null
@@ -1,10 +0,0 @@
-ABORT 'NO DIAL TONE' ABORT 'NO ANSWER' ABORT 'NO CARRIER' ABORT DELAYED
-'' AT
-OK ATZ
-{% if ipv6 is defined and ipv6.address is defined and ipv6.address.autoconf is defined %}
-OK 'AT+CGDCONT=1,"IPV4V6","{{ apn }}"'
-{% else %}
-OK 'AT+CGDCONT=1,"IP","{{ apn }}"'
-{% endif %}
-OK ATD*99#
-CONNECT ''
diff --git a/data/templates/wwan/ip-down.script.tmpl b/data/templates/wwan/ip-down.script.tmpl
deleted file mode 100644
index 9dc15ea99..000000000
--- a/data/templates/wwan/ip-down.script.tmpl
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/bin/sh
-
-# Script parameters will be like:
-# wlm0 /dev/serial/by-bus/usb0b1.3p1.3 115200 10.100.118.91 10.64.64.64 wlm0
-
-# Only applicable for Wireless Modems (WWAN)
-if [ -z $(echo $2 | egrep "(ttyS[0-9]+|usb[0-9]+b.*)$") ]; then
- exit 0
-fi
-
-# Determine if we are running inside a VRF or not, required for proper routing table
-# NOTE: the down script can not be properly templated as we need the VRF name,
-# which is not present on deletion, thus we read it from the operating system.
-if [ -d /sys/class/net/{{ ifname }}/upper_* ]; then
- # Determine upper (VRF) interface
- VRF=$(basename $(ls -d /sys/class/net/{{ ifname }}/upper_*))
- # Remove upper_ prefix from result string
- VRF_NAME=${VRF#"upper_"}
- # Remove default route from VRF routing table
- vtysh -c "conf t" -c "vrf ${VRF_NAME}" -c "no ip route 0.0.0.0/0 {{ ifname }}"
-else
- # Remove default route from GRT (global routing table)
- vtysh -c "conf t" -c "no ip route 0.0.0.0/0 {{ ifname }}"
-fi
-
-DIALER_PID=$(cat /var/run/{{ ifname }}.pid)
-logger -t pppd[$DIALER_PID] "removed default route via {{ ifname }} metric {{ backup.distance }}"
diff --git a/data/templates/wwan/ip-pre-up.script.tmpl b/data/templates/wwan/ip-pre-up.script.tmpl
deleted file mode 100644
index 199150947..000000000
--- a/data/templates/wwan/ip-pre-up.script.tmpl
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/sh
-# As WWAN is an "on demand" interface we need to re-configure it when it
-# becomes 'up'
-
-ipparam=$6
-
-# device name and metric are received using ipparam
-device=`echo "$ipparam"|awk '{ print $1 }'`
-
-if [ "$device" != "{{ ifname }}" ]; then
- exit
-fi
-
-# add some info to syslog
-DIALER_PID=$(cat /var/run/{{ ifname }}.pid)
-logger -t pppd[$DIALER_PID] "executing $0"
-
-echo "{{ description }}" > /sys/class/net/{{ ifname }}/ifalias
-
-{% if vrf %}
-logger -t pppd[$DIALER_PID] "configuring interface {{ ifname }} for VRF {{ vrf }}"
-ip link set dev {{ ifname }} master {{ vrf }}
-{% endif %}
diff --git a/data/templates/wwan/ip-up.script.tmpl b/data/templates/wwan/ip-up.script.tmpl
deleted file mode 100644
index 2603a0286..000000000
--- a/data/templates/wwan/ip-up.script.tmpl
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh
-
-# Script parameters will be like:
-# wlm0 /dev/serial/by-bus/usb0b1.3p1.3 115200 10.100.118.91 10.64.64.64 wlm0
-
-# Only applicable for Wireless Modems (WWAN)
-if [ -z $(echo $2 | egrep "(ttyS[0-9]+|usb[0-9]+b.*)$") ]; then
- exit 0
-fi
-
-# Determine if we are running inside a VRF or not, required for proper routing table
-if [ -d /sys/class/net/{{ ifname }}/upper_* ]; then
- # Determine upper (VRF) interface
- VRF=$(basename $(ls -d /sys/class/net/{{ ifname }}/upper_*))
- # Remove upper_ prefix from result string
- VRF_NAME=${VRF#"upper_"}
- # Remove default route from VRF routing table
- vtysh -c "conf t" -c "vrf ${VRF_NAME}" -c "ip route 0.0.0.0/0 {{ ifname }} {{ backup.distance }}"
-else
- # Remove default route from GRT (global routing table)
- vtysh -c "conf t" -c "ip route 0.0.0.0/0 {{ ifname }} {{ backup.distance }}"
-fi
-
-DIALER_PID=$(cat /var/run/{{ ifname }}.pid)
-logger -t pppd[$DIALER_PID] "added default route via {{ ifname }} metric {{ backup.distance }} ${VRF_NAME}"
diff --git a/data/templates/wwan/peer.tmpl b/data/templates/wwan/peer.tmpl
deleted file mode 100644
index 2807a79a4..000000000
--- a/data/templates/wwan/peer.tmpl
+++ /dev/null
@@ -1,31 +0,0 @@
-### Autogenerated by interfaces-wirelessmodem.py ###
-
-{{ "# description: " + description if description is defined }}
-ifname {{ ifname }}
-ipparam {{ ifname }}
-linkname {{ ifname }}
-
-{{ "usepeerdns" if no_peer_dns is defined }}
-# physical device
-{{ device }}
-lcp-echo-failure 0
-115200
-debug
-mtu {{ mtu }}
-mru {{ mtu }}
-{% if ipv6 is defined and ipv6.address is defined and ipv6.address.autoconf is defined %}
-+ipv6
-ipv6cp-use-ipaddr
-{% endif %}
-nodefaultroute
-ipcp-max-failure 4
-ipcp-accept-local
-ipcp-accept-remote
-noauth
-crtscts
-lock
-persist
-{{ "demand" if connect_on_demand is defined }}
-
-connect '/usr/sbin/chat -v -t6 -f /etc/ppp/peers/chat.{{ ifname }}'
-