diff options
Diffstat (limited to 'data')
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 }}' - |