diff options
Diffstat (limited to 'data/templates')
88 files changed, 4950 insertions, 0 deletions
diff --git a/data/templates/accel-ppp/chap-secrets.ipoe.tmpl b/data/templates/accel-ppp/chap-secrets.ipoe.tmpl new file mode 100644 index 000000000..a7d899354 --- /dev/null +++ b/data/templates/accel-ppp/chap-secrets.ipoe.tmpl @@ -0,0 +1,18 @@ +# username server password acceptable local IP addresses shaper +{% for interface in auth_interfaces -%} +{% for mac in interface.mac -%} +{% if mac.rate_upload and mac.rate_download -%} +{% if mac.vlan_id -%} +{{ interface.name }}.{{ mac.vlan_id }} * {{ mac.address | lower }} * {{ mac.rate_download }}/{{ mac.rate_upload }} +{% else -%} +{{ interface.name }} * {{ mac.address | lower }} * {{ mac.rate_download }}/{{ mac.rate_upload }} +{% endif -%} +{% else -%} +{% if mac.vlan_id -%} +{{ interface.name }}.{{ mac.vlan_id }} * {{ mac.address | lower }} * +{% else -%} +{{ interface.name }} * {{ mac.address | lower }} * +{% endif -%} +{% endif -%} +{% endfor -%} +{% endfor -%} diff --git a/data/templates/accel-ppp/chap-secrets.tmpl b/data/templates/accel-ppp/chap-secrets.tmpl new file mode 100644 index 000000000..dd00d7bd0 --- /dev/null +++ b/data/templates/accel-ppp/chap-secrets.tmpl @@ -0,0 +1,10 @@ +# username server password acceptable local IP addresses shaper +{% for user in local_users %} +{% if user.state == 'enabled' %} +{% if user.upload and user.download %} +{{ "%-12s" | format(user.name) }} * {{ "%-16s" | format(user.password) }} {{ "%-16s" | format(user.ip) }} {{ user.download }} / {{ user.upload }} +{% else %} +{{ "%-12s" | format(user.name) }} * {{ "%-16s" | format(user.password) }} {{ "%-16s" | format(user.ip) }} +{% endif %} +{% endif %} +{% endfor %} diff --git a/data/templates/accel-ppp/ipoe.config.tmpl b/data/templates/accel-ppp/ipoe.config.tmpl new file mode 100644 index 000000000..fca520efa --- /dev/null +++ b/data/templates/accel-ppp/ipoe.config.tmpl @@ -0,0 +1,111 @@ +### generated by ipoe.py ### +[modules] +log_syslog +ipoe +shaper +ipv6pool +ipv6_nd +ipv6_dhcp +ippool +{% if auth_mode == 'radius' %} +radius +{% elif auth_mode == 'local' %} +chap-secrets +{% endif %} + +[core] +thread-count={{ thread_cnt }} + +[log] +syslog=accel-ipoe,daemon +copy=1 +level=5 + +[ipoe] +verbose=1 +{% for interface in interfaces %} +{% if interface.vlan_mon %} +interface=re:{{ interface.name }}\.\d+,{% else %}interface={{ interface.name }},{% endif %}shared={{ interface.shared }},mode={{ interface.mode }},ifcfg={{ interface.ifcfg }},range={{ interface.range }},start={{ interface.sess_start }},ipv6=1 +{% endfor %} +{% if auth_mode == 'noauth' %} +noauth=1 +{% elif auth_mode == 'local' %} +username=ifname +password=csid +{% endif %} + +{%- for interface in interfaces %} +{% if (interface.shared == '0') and (interface.vlan_mon) %} +vlan-mon={{ interface.name }},{{ interface.vlan_mon | join(',') }} +{% endif %} +{% endfor %} + +{% if dnsv4 %} +[dns] +{% for dns in dnsv4 -%} +dns{{ loop.index }}={{ dns }} +{% endfor -%} +{% endif %} + +{% if dnsv6 %} +[ipv6-dns] +{% for dns in dnsv6 -%} +{{ dns }} +{% endfor -%} +{% endif %} + +[ipv6-nd] +verbose=1 + +[ipv6-dhcp] +verbose=1 + +{% if client_ipv6_pool %} +[ipv6-pool] +{% for p in client_ipv6_pool %} +{{ p.prefix }},{{ p.mask }} +{% endfor %} +{% for p in client_ipv6_delegate_prefix %} +delegate={{ p.prefix }},{{ p.mask }} +{% endfor %} +{% endif %} + +{% if auth_mode == 'local' %} +[chap-secrets] +chap-secrets={{ chap_secrets_file }} +{% elif auth_mode == 'radius' %} +[radius] +verbose=1 +{% for r in radius_server %} +server={{ r.server }},{{ r.key }},auth-port={{ r.port }},acct-port={{ r.acct_port }},req-limit=0,fail-time={{ r.fail_time }} +{% endfor -%} + +acct-timeout={{ radius_acct_tmo }} +timeout={{ radius_timeout }} +max-try={{ radius_max_try }} +{% if radius_nas_id %} +nas-identifier={{ radius_nas_id }} +{% endif -%} +{% if radius_nas_ip %} +nas-ip-address={{ radius_nas_ip }} +{% endif -%} +{% if radius_source_address %} +bind={{ radius_source_address }} +{% endif -%} + +{% if radius_dynamic_author %} +dae-server={{ radius_dynamic_author.server }}:{{ radius_dynamic_author.port }},{{ radius_dynamic_author.key }} +{% endif -%} + +{% if radius_shaper_attr %} +[shaper] +verbose=1 +attr={{ radius_shaper_attr }} +{% if radius_shaper_vendor %} +vendor={{ radius_shaper_vendor }} +{% endif -%} +{% endif -%} +{% endif %} + +[cli] +tcp=127.0.0.1:2002 diff --git a/data/templates/accel-ppp/l2tp.config.tmpl b/data/templates/accel-ppp/l2tp.config.tmpl new file mode 100644 index 000000000..b9131684d --- /dev/null +++ b/data/templates/accel-ppp/l2tp.config.tmpl @@ -0,0 +1,148 @@ +### generated by accel_l2tp.py ### +[modules] +log_syslog +l2tp +chap-secrets +{% for proto in auth_proto: %} +{{proto}} +{% endfor%} + +{% if auth_mode == 'radius' %} +radius +{% endif -%} + +ippool +shaper +ipv6pool +ipv6_nd +ipv6_dhcp + +[core] +thread-count={{thread_cnt}} + +[log] +syslog=accel-l2tp,daemon +copy=1 +level=5 + +{% if dnsv4 %} +[dns] +{% for dns in dnsv4 -%} +dns{{ loop.index }}={{ dns }} +{% endfor -%} +{% endif %} + +{% if dnsv6 %} +[ipv6-dns] +{% for dns in dnsv6 -%} +{{ dns }} +{% endfor -%} +{% endif %} + +{% if wins %} +[wins] +{% for server in wins -%} +wins{{ loop.index }}={{ server }} +{% endfor -%} +{% endif %} + +[l2tp] +verbose=1 +ifname=l2tp%d +ppp-max-mtu={{ mtu }} +mppe={{ ppp_mppe }} +{% if outside_addr %} +bind={{ outside_addr }} +{% endif %} +{% if lns_shared_secret %} +secret={{ lns_shared_secret }} +{% endif %} + +[client-ip-range] +0.0.0.0/0 + +{% if client_ip_pool or client_ip_subnets %} +[ip-pool] +{% if client_ip_pool %} +{{ client_ip_pool }} +{% endif -%} +{% if client_ip_subnets %} +{% for sn in client_ip_subnets %} +{{sn}} +{% endfor -%} +{% endif %} +{% endif %} +{% if gateway_address %} +gw-ip-address={{ gateway_address }} +{% endif %} + +{% if auth_mode == 'local' %} +[chap-secrets] +chap-secrets={{ chap_secrets_file }} +{% elif auth_mode == 'radius' %} +[radius] +verbose=1 +{% for r in radius_server %} +server={{ r.server }},{{ r.key }},auth-port={{ r.port }},acct-port={{ r.acct_port }},req-limit=0,fail-time={{ r.fail_time }} +{% endfor -%} + +acct-timeout={{ radius_acct_tmo }} +timeout={{ radius_timeout }} +max-try={{ radius_max_try }} + +{% if radius_nas_id %} +nas-identifier={{ radius_nas_id }} +{% endif -%} +{% if radius_nas_ip %} +nas-ip-address={{ radius_nas_ip }} +{% endif -%} +{% if radius_source_address %} +bind={{ radius_source_address }} +{% endif -%} +{% endif %} +{% if gateway_address %} +gw-ip-address={{ gateway_address }} +{% endif %} + +[ppp] +verbose=1 +check-ip=1 +single-session=replace +lcp-echo-timeout={{ ppp_echo_timeout }} +lcp-echo-interval={{ ppp_echo_interval }} +lcp-echo-failure={{ ppp_echo_failure }} +{% if ccp_disable %} +ccp=0 +{% endif %} +{% if client_ipv6_pool %} +ipv6=allow +{% endif %} + + +{% if client_ipv6_pool %} +[ipv6-pool] +{% for p in client_ipv6_pool %} +{{ p.prefix }},{{ p.mask }} +{% endfor %} +{% for p in client_ipv6_delegate_prefix %} +delegate={{ p.prefix }},{{ p.mask }} +{% endfor %} +{% endif %} + +{% if client_ipv6_delegate_prefix %} +[ipv6-dhcp] +verbose=1 +{% endif %} + +{% if radius_shaper_attr %} +[shaper] +verbose=1 +attr={{ radius_shaper_attr }} +{% if radius_shaper_vendor %} +vendor={{ radius_shaper_vendor }} +{% endif -%} +{% endif %} + +[cli] +tcp=127.0.0.1:2004 +sessions-columns=ifname,username,calling-sid,ip,{{ ip6_column | join(',') }}{{ ',' if ip6_column }}rate-limit,type,comp,state,rx-bytes,tx-bytes,uptime diff --git a/data/templates/accel-ppp/pppoe.config.tmpl b/data/templates/accel-ppp/pppoe.config.tmpl new file mode 100644 index 000000000..5ad628fde --- /dev/null +++ b/data/templates/accel-ppp/pppoe.config.tmpl @@ -0,0 +1,204 @@ +### generated by accel_pppoe.py ### +[modules] +log_syslog +pppoe +{% if auth_mode == 'radius' %} +radius +{% endif %} +chap-secrets +ippool +{% if ppp_ipv6 != 'deny' %} +ipv6pool +ipv6_nd +ipv6_dhcp +{% endif %} +{% for proto in auth_proto: %} +{{proto}} +{% endfor%} +shaper +{% if snmp %} +net-snmp +{% endif %} +{% if limits %} +connlimit +{% endif %} + +[core] +thread-count={{ thread_cnt }} + +[log] +syslog=accel-pppoe,daemon +copy=1 +level=5 + +{% if snmp == 'enable-ma' %} +[snmp] +master=1 +{% endif %} + +[client-ip-range] +disable + +{% if ppp_gw %} +[ip-pool] +gw-ip-address={{ ppp_gw }} +{% if client_ip_pool %} +{{ client_ip_pool }} +{% endif -%} +{% if client_ip_subnets %} +{% for subnet in client_ip_subnets %} +{{ subnet }} +{% endfor %} +{% endif %} +{% endif %} + +{% if client_ipv6_pool %} +[ipv6-nd] +AdvAutonomousFlag=1 + +[ipv6-pool] +{% for p in client_ipv6_pool %} +{{ p.prefix }},{{ p.mask }} +{% endfor %} +{% for p in client_ipv6_delegate_prefix %} +delegate={{ p.prefix }},{{ p.mask }} +{% endfor %} +{% endif %} + +{% if dnsv4 %} +[dns] +{% for dns in dnsv4 -%} +dns{{ loop.index }}={{ dns }} +{% endfor -%} +{% endif %} + +{% if dnsv6 %} +[ipv6-dns] +{% for dns in dnsv6 -%} +{{ dns }} +{% endfor -%} +{% endif %} + +{% if wins %} +[wins] +{% for server in wins -%} +wins{{ loop.index }}={{ server }} +{% endfor -%} +{% endif %} + +{% if auth_mode == 'local' %} +[chap-secrets] +chap-secrets={{ chap_secrets_file }} +{% elif auth_mode == 'radius' %} +[radius] +verbose=1 +{% for r in radius_server %} +server={{ r.server }},{{ r.key }},auth-port={{ r.port }},acct-port={{ r.acct_port }},req-limit=0,fail-time={{ r.fail_time }} +{% endfor -%} + +acct-timeout={{ radius_acct_tmo }} +timeout={{ radius_timeout }} +max-try={{ radius_max_try }} + +{% if radius_nas_id %} +nas-identifier={{ radius_nas_id }} +{% endif -%} +{% if radius_nas_ip %} +nas-ip-address={{ radius_nas_ip }} +{% endif -%} +{% if radius_source_address %} +bind={{ radius_source_address }} +{% endif -%} + + +{% if radius_dynamic_author %} +dae-server={{ radius_dynamic_author.server }}:{{ radius_dynamic_author.port }},{{ radius_dynamic_author.key }} +{% endif -%} +{% endif %} +{% if ppp_gw %} +gw-ip-address={{ ppp_gw }} +{% endif %} + +{% if sesscrtl != 'disable' %} +[common] +single-session={{ sesscrtl }} +{% endif %} + +[ppp] +verbose=1 +check-ip=1 +{% if ppp_ccp %} +ccp=1 +{% else %} +ccp=0 +{% endif %} +{% if ppp_min_mtu %} +min-mtu={{ ppp_min_mtu }} +{% else %} +min-mtu={{ mtu }} +{% endif %} +{% if ppp_mru %} +mru={{ ppp_mru }} +{% endif %} +mppe={{ ppp_mppe }} +lcp-echo-interval={{ ppp_echo_interval }} +lcp-echo-timeout={{ ppp_echo_timeout }} +lcp-echo-failure={{ ppp_echo_failure }} +{% if ppp_ipv4 %} +ipv4={{ ppp_ipv4 }} +{% endif %} +{% if client_ipv6_pool %} +ipv6=allow +{% endif %} + +{% if ppp_ipv6 %} +ipv6={{ ppp_ipv6 }} +{% if ppp_ipv6_intf_id %} +ipv6-intf-id={{ ppp_ipv6_intf_id }} +{% endif %} +{% if ppp_ipv6_peer_intf_id %} +ipv6-peer-intf-id={{ ppp_ipv6_peer_intf_id }} +{% endif %} +{% if ppp_ipv6_accept_peer_intf_id %} +ipv6-accept-peer-intf-id={{ ppp_ipv6_accept_peer_intf_id }} +{% endif %} +{% endif %} +mtu={{ mtu }} + +[pppoe] +verbose=1 +ac-name={{ concentrator }} + +{% if interfaces %} +{% for interface in interfaces %} +interface={{ interface.name }} +{% if interface.vlans %} +vlan-mon={{ interface.name }},{{ interface.vlans | join(',') }} +interface=re:{{ interface.name }}\.\d+ +{% endif %} +{% endfor -%} +{% endif -%} + +{% if svc_name %} +service-name={{ svc_name|join(',') }} +{% endif -%} + +{% if pado_delay %} +pado-delay={{ pado_delay }} +{% endif %} + +{% if limits_burst or limits_connections or limits_connections %} +[connlimit] +{% if limits_connections %} +limit={{ limits_connections }} +{% endif %} +{% if limits_burst %} +burst={{ limits_burst }} +{% endif %} +{% if limits_timeout %} +timeout={{ limits_timeout }} +{% endif %} +{% endif %} + +[cli] +tcp=127.0.0.1:2001 diff --git a/data/templates/accel-ppp/pptp.config.tmpl b/data/templates/accel-ppp/pptp.config.tmpl new file mode 100644 index 000000000..e0f2c6da9 --- /dev/null +++ b/data/templates/accel-ppp/pptp.config.tmpl @@ -0,0 +1,89 @@ +### generated by accel_pptp.py ### +[modules] +log_syslog +pptp +ippool +{% if auth_mode == 'local' %} +chap-secrets +{% elif auth_mode == 'radius' %} +radius +{% endif -%} +{% for proto in auth_proto %} +{{proto}} +{% endfor %} + +[core] +thread-count={{ thread_cnt }} + +[log] +syslog=accel-pptp,daemon +copy=1 +level=5 + +{% if dnsv4 %} +[dns] +{% for dns in dnsv4 -%} +dns{{ loop.index }}={{ dns }} +{% endfor -%} +{% endif %} + +{% if wins %} +[wins] +{% for server in wins -%} +wins{{ loop.index }}={{ server }} +{% endfor -%} +{% endif %} + + +[pptp] +ifname=pptp%d +{% if outside_addr %} +bind={{ outside_addr }} +{% endif %} +verbose=1 +ppp-max-mtu={{mtu}} +mppe={{ ppp_mppe }} +echo-interval=10 +echo-failure=3 + + +[client-ip-range] +0.0.0.0/0 + +[ip-pool] +tunnel={{ client_ip_pool }} +gw-ip-address={{ gw_ip }} + +[ppp] +verbose=5 +check-ip=1 +single-session=replace + +{% if auth_mode == 'local' %} +[chap-secrets] +chap-secrets={{ chap_secrets_file }} +{% elif auth_mode == 'radius' %} +[radius] +verbose=1 +{% for r in radius_server %} +server={{ r.server }},{{ r.key }},auth-port={{ r.port }},acct-port={{ r.acct_port }},req-limit=0,fail-time={{ r.fail_time }} +{% endfor -%} + +acct-timeout={{ radius_acct_tmo }} +timeout={{ radius_timeout }} +max-try={{ radius_max_try }} + +{% if radius_nas_id %} +nas-identifier={{ radius_nas_id }} +{% endif -%} +{% if radius_nas_ip %} +nas-ip-address={{ radius_nas_ip }} +{% endif -%} +{% if radius_source_address %} +bind={{ radius_source_address }} +{% endif -%} +{% endif %} + +[cli] +tcp=127.0.0.1:2003 + diff --git a/data/templates/accel-ppp/sstp.config.tmpl b/data/templates/accel-ppp/sstp.config.tmpl new file mode 100644 index 000000000..c9e4a1d7d --- /dev/null +++ b/data/templates/accel-ppp/sstp.config.tmpl @@ -0,0 +1,146 @@ +### generated by vpn_sstp.py ### +[modules] +log_syslog +sstp +shaper +{% if auth_mode == 'local' %} +chap-secrets +{% elif auth_mode == 'radius' %} +radius +{% endif -%} +ippool +ipv6pool +ipv6_nd +ipv6_dhcp + +{% for proto in auth_proto %} +{{proto}} +{% endfor %} + +[core] +thread-count={{thread_cnt}} + +[common] +single-session=replace + +[log] +syslog=accel-sstp,daemon +copy=1 +level=5 + +[client-ip-range] +disable + +[sstp] +verbose=1 +ifname=sstp%d +accept=ssl +ssl-ca-file={{ ssl_ca }} +ssl-pemfile={{ ssl_cert }} +ssl-keyfile={{ ssl_key }} + +{% if client_ip_pool %} +[ip-pool] +gw-ip-address={{ client_gateway }} +{% for subnet in client_ip_pool %} +{{ subnet }} +{% endfor %} +{% endif %} + +{% if dnsv4 %} +[dns] +{% for dns in dnsv4 -%} +dns{{ loop.index }}={{ dns }} +{% endfor -%} +{% endif %} + +{% if dnsv6 %} +[ipv6-dns] +{% for dns in dnsv6 -%} +{{ dns }} +{% endfor -%} +{% endif %} + + +{% if auth_mode == 'local' %} +[chap-secrets] +chap-secrets={{ chap_secrets_file }} +{% elif auth_mode == 'radius' %} +[radius] +verbose=1 +{% for r in radius_server %} +server={{ r.server }},{{ r.key }},auth-port={{ r.port }},acct-port={{ r.acct_port }},req-limit=0,fail-time={{ r.fail_time }} +{% endfor -%} + +acct-timeout={{ radius_acct_tmo }} +timeout={{ radius_timeout }} +max-try={{ radius_max_try }} + +{% if radius_nas_id %} +nas-identifier={{ radius_nas_id }} +{% endif -%} +{% if radius_nas_ip %} +nas-ip-address={{ radius_nas_ip }} +{% endif -%} +{% if radius_source_address %} +bind={{ radius_source_address }} +{% endif -%} + + +{% if radius_dynamic_author %} +dae-server={{ radius_dynamic_author.server }}:{{ radius_dynamic_author.port }},{{ radius_dynamic_author.key }} +{% endif -%} +{% endif %} +{% if client_gateway %} +gw-ip-address={{ client_gateway }} +{% endif %} + +[ppp] +verbose=1 +check-ip=1 +{% if mtu %} +mtu={{ mtu }} +{% endif -%} +{% if client_ipv6_pool %} +ipv6=allow +{% endif %} + +{% if ppp_mppe %} +mppe={{ ppp_mppe }} +{% endif -%} +{% if ppp_echo_interval %} +lcp-echo-interval={{ ppp_echo_interval }} +{% endif -%} +{% if ppp_echo_failure %} +lcp-echo-failure={{ ppp_echo_failure }} +{% endif -%} +{% if ppp_echo_timeout %} +lcp-echo-timeout={{ ppp_echo_timeout }} +{% endif %} + +{% if client_ipv6_pool %} +[ipv6-pool] +{% for p in client_ipv6_pool %} +{{ p.prefix }},{{ p.mask }} +{% endfor %} +{% for p in client_ipv6_delegate_prefix %} +delegate={{ p.prefix }},{{ p.mask }} +{% endfor %} +{% endif %} + +{% if client_ipv6_delegate_prefix %} +[ipv6-dhcp] +verbose=1 +{% endif %} + +{% if radius_shaper_attr %} +[shaper] +verbose=1 +attr={{ radius_shaper_attr }} +{% if radius_shaper_vendor %} +vendor={{ radius_shaper_vendor }} +{% endif -%} +{% endif %} + +[cli] +tcp=127.0.0.1:2005 diff --git a/data/templates/bcast-relay/udp-broadcast-relay.tmpl b/data/templates/bcast-relay/udp-broadcast-relay.tmpl new file mode 100644 index 000000000..d0c7d8bf9 --- /dev/null +++ b/data/templates/bcast-relay/udp-broadcast-relay.tmpl @@ -0,0 +1,7 @@ +### Autogenerated by bcast_relay.py ### + +# UDP broadcast relay configuration for instance {{ id }} +{%- if description %} +# Comment: {{ description }} +{% endif %} +DAEMON_ARGS="{{ '-s ' + address if address is defined }} {{ instance }} {{ port }} {{ interface | join(' ') }}" diff --git a/data/templates/conserver/conserver.conf.tmpl b/data/templates/conserver/conserver.conf.tmpl new file mode 100644 index 000000000..4e7b5d8d7 --- /dev/null +++ b/data/templates/conserver/conserver.conf.tmpl @@ -0,0 +1,37 @@ +### Autogenerated by service_console-server.py ### + +# See https://www.conserver.com/docs/conserver.cf.man.html for additional options + +config * { + primaryport 3109; + daemonmode false; +} + +default * { + motd "VyOS Console Server"; + rw *; +} + +## +## list of consoles we serve +## +{% for key, value in device.items() %} +{# Depending on our USB serial console we could require a path adjustment #} +{% set path = '/dev' if key.startswith('ttyS') else '/dev/serial/by-bus' %} +console {{ key }} { + master localhost; + type device; + device {{ path }}/{{ key }}; + baud {{ value.speed }}; + parity {{ value.parity }}; + options {{ "!" if value.stop_bits == "1" }}cstopb; +} +{% endfor %} + +## +## list of clients we allow +## +access * { + trusted localhost; + allowed localhost; +} diff --git a/data/templates/dhcp-client/daemon-options.tmpl b/data/templates/dhcp-client/daemon-options.tmpl new file mode 100644 index 000000000..290aefa49 --- /dev/null +++ b/data/templates/dhcp-client/daemon-options.tmpl @@ -0,0 +1,4 @@ +### Autogenerated by interface.py ### + +DHCLIENT_OPTS="-nw -cf /var/lib/dhcp/dhclient_{{ifname}}.conf -pf /var/lib/dhcp/dhclient_{{ifname}}.pid -lf /var/lib/dhcp/dhclient_{{ifname}}.leases {{ifname}}" + diff --git a/data/templates/dhcp-client/ipv4.tmpl b/data/templates/dhcp-client/ipv4.tmpl new file mode 100644 index 000000000..8a44a9761 --- /dev/null +++ b/data/templates/dhcp-client/ipv4.tmpl @@ -0,0 +1,19 @@ +### Autogenerated by interface.py ### + +option rfc3442-classless-static-routes code 121 = array of unsigned integer 8; +timeout 60; +retry 300; + +interface "{{ ifname }}" { + send host-name "{{ dhcp_options.host_name }}"; +{% if dhcp_options.client_id is defined and dhcp_options.client_id is not none %} + send dhcp-client-identifier "{{ dhcp_options.client_id }}"; +{% endif %} +{% if dhcp_options.vendor_class_id is defined and dhcp_options.vendor_class_id is not none %} + send vendor-class-identifier "{{ dhcp_options.vendor_class_id }}"; +{% endif %} + request subnet-mask, broadcast-address, routers, domain-name-servers, + rfc3442-classless-static-routes, domain-name, interface-mtu; + require subnet-mask; +} + diff --git a/data/templates/dhcp-client/ipv6.tmpl b/data/templates/dhcp-client/ipv6.tmpl new file mode 100644 index 000000000..68f668117 --- /dev/null +++ b/data/templates/dhcp-client/ipv6.tmpl @@ -0,0 +1,57 @@ +### Autogenerated by interface.py ### + +# man https://www.unix.com/man-page/debian/5/dhcp6c.conf/ +interface {{ ifname }} { +{% if address is defined and 'dhcpv6' in address %} + request domain-name-servers; + request domain-name; +{% if dhcpv6_options is defined and dhcpv6_options.parameters_only is defined %} + information-only; +{% endif %} +{% if dhcpv6_options is not defined or dhcpv6_options.temporary is not defined %} + send ia-na 0; # non-temporary address +{% endif %} +{% if dhcpv6_options is defined and dhcpv6_options.rapid_commit is defined %} + send rapid-commit; # wait for immediate reply instead of advertisements +{% endif %} +{% endif %} +{% if dhcpv6_options is defined and dhcpv6_options.pd is defined %} +{% for pd in dhcpv6_options.pd %} + send ia-pd {{ pd }}; # prefix delegation #{{ pd }} +{% endfor %} +{% endif %} +}; + +{% if address is defined and 'dhcpv6' in address %} +{% if dhcpv6_options is not defined or dhcpv6_options.temporary is not defined %} +id-assoc na 0 { + # Identity association for non temporary address +}; +{% endif %} +{% endif %} + +{% if dhcpv6_options is defined and dhcpv6_options.pd is defined %} +{% for pd in dhcpv6_options.pd %} +id-assoc pd {{ pd }} { +{# length got a default value #} + prefix ::/{{ dhcpv6_options.pd[pd].length }} infinity; +{% set sla_len = 64 - dhcpv6_options.pd[pd].length|int %} +{% set count = namespace(value=0) %} +{% for interface in dhcpv6_options.pd[pd].interface if dhcpv6_options.pd[pd].interface is defined %} + prefix-interface {{ interface }} { + sla-len {{ sla_len }}; +{% if dhcpv6_options.pd[pd].interface[interface].sla_id is defined and dhcpv6_options.pd[pd].interface[interface].sla_id is not none %} + sla-id {{ dhcpv6_options.pd[pd].interface[interface].sla_id }}; +{% else %} + sla-id {{ count.value }}; +{% endif %} +{% if dhcpv6_options.pd[pd].interface[interface].address is defined and dhcpv6_options.pd[pd].interface[interface].address is not none %} + ifid {{ dhcpv6_options.pd[pd].interface[interface].address }}; +{% endif %} + }; +{% set count.value = count.value + 1 %} +{% endfor %} +}; +{% endfor %} +{% endif %} + diff --git a/data/templates/dhcp-relay/config.tmpl b/data/templates/dhcp-relay/config.tmpl new file mode 100644 index 000000000..b223807cf --- /dev/null +++ b/data/templates/dhcp-relay/config.tmpl @@ -0,0 +1,4 @@ +### Autogenerated by dhcp_relay.py ### + +# Defaults for isc-dhcp-relay6.service +OPTIONS="{{ options | join(' ') }} -i {{ interface | join(' -i ') }} {{ server | join(' ') }}" diff --git a/data/templates/dhcp-server/dhcpd.conf.tmpl b/data/templates/dhcp-server/dhcpd.conf.tmpl new file mode 100644 index 000000000..5f5129451 --- /dev/null +++ b/data/templates/dhcp-server/dhcpd.conf.tmpl @@ -0,0 +1,195 @@ + +### Autogenerated by dhcp_server.py ### + +# For options please consult the following website: +# https://www.isc.org/wp-content/uploads/2017/08/dhcp43options.html +# +# log-facility local7; + +{% if hostfile_update %} +on release { + set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name); + set ClientIp = binary-to-ascii(10, 8, ".",leased-address); + set ClientMac = binary-to-ascii(16, 8, ":",substring(hardware, 1, 6)); + set ClientDomain = pick-first-value(config-option domain-name, "..YYZ!"); + execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "release", ClientName, ClientIp, ClientMac, ClientDomain); +} + +on expiry { + set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name); + set ClientIp = binary-to-ascii(10, 8, ".",leased-address); + set ClientMac = binary-to-ascii(16, 8, ":",substring(hardware, 1, 6)); + set ClientDomain = pick-first-value(config-option domain-name, "..YYZ!"); + execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "release", ClientName, ClientIp, ClientMac, ClientDomain); +} +{% endif %} +{%- if host_decl_name %} +use-host-decl-names on; +{%- endif %} +ddns-update-style {% if ddns_enable -%} interim {%- else -%} none {%- endif %}; +{% if static_route -%} +option rfc3442-static-route code 121 = array of integer 8; +option windows-static-route code 249 = array of integer 8; +{%- endif %} +{% if wpad -%} +option wpad-url code 252 = text; +{% endif %} + +{%- if global_parameters %} +# The following {{ global_parameters | length }} line(s) were added as global-parameters in the CLI and have not been validated +{%- for param in global_parameters %} +{{ param }} +{%- endfor -%} +{%- endif %} + +# Failover configuration +{% for network in shared_network %} +{%- if not network.disabled -%} +{%- for subnet in network.subnet %} +{%- if subnet.failover_name -%} +failover peer "{{ subnet.failover_name }}" { +{%- if subnet.failover_status == 'primary' %} + primary; + mclt 1800; + split 128; +{%- elif subnet.failover_status == 'secondary' %} + secondary; +{%- endif %} + address {{ subnet.failover_local_addr }}; + port 520; + peer address {{ subnet.failover_peer_addr }}; + peer port 520; + max-response-delay 30; + max-unacked-updates 10; + load balance max seconds 3; +} +{% endif -%} +{% endfor -%} +{% endif -%} +{% endfor %} + +# Shared network configration(s) +{% for network in shared_network %} +{%- if not network.disabled -%} +shared-network {{ network.name }} { + {%- if network.authoritative %} + authoritative; + {%- endif %} + {%- if network.network_parameters %} + # The following {{ network.network_parameters | length }} line(s) were added as shared-network-parameters in the CLI and have not been validated + {%- for param in network.network_parameters %} + {{ param }} + {%- endfor %} + {%- endif %} + {%- for subnet in network.subnet %} + subnet {{ subnet.address }} netmask {{ subnet.netmask }} { + {%- if subnet.dns_server %} + option domain-name-servers {{ subnet.dns_server | join(', ') }}; + {%- endif %} + {%- if subnet.domain_search %} + option domain-search {{ subnet.domain_search | join(', ') }}; + {%- endif %} + {%- if subnet.ntp_server %} + option ntp-servers {{ subnet.ntp_server | join(', ') }}; + {%- endif %} + {%- if subnet.pop_server %} + option pop-server {{ subnet.pop_server | join(', ') }}; + {%- endif %} + {%- if subnet.smtp_server %} + option smtp-server {{ subnet.smtp_server | join(', ') }}; + {%- endif %} + {%- if subnet.time_server %} + option time-servers {{ subnet.time_server | join(', ') }}; + {%- endif %} + {%- if subnet.wins_server %} + option netbios-name-servers {{ subnet.wins_server | join(', ') }}; + {%- endif %} + {%- if subnet.static_route %} + option rfc3442-static-route {{ subnet.static_route }}{% if subnet.rfc3442_default_router %}, {{ subnet.rfc3442_default_router }}{% endif %}; + option windows-static-route {{ subnet.static_route }}; + {%- endif %} + {%- if subnet.ip_forwarding %} + option ip-forwarding true; + {%- endif -%} + {%- if subnet.default_router %} + option routers {{ subnet.default_router }}; + {%- endif -%} + {%- if subnet.server_identifier %} + option dhcp-server-identifier {{ subnet.server_identifier }}; + {%- endif -%} + {%- if subnet.domain_name %} + option domain-name "{{ subnet.domain_name }}"; + {%- endif -%} + {%- if subnet.subnet_parameters %} + # The following {{ subnet.subnet_parameters | length }} line(s) were added as subnet-parameters in the CLI and have not been validated + {%- for param in subnet.subnet_parameters %} + {{ param }} + {%- endfor -%} + {%- endif %} + {%- if subnet.tftp_server %} + option tftp-server-name "{{ subnet.tftp_server }}"; + {%- endif -%} + {%- if subnet.bootfile_name %} + option bootfile-name "{{ subnet.bootfile_name }}"; + filename "{{ subnet.bootfile_name }}"; + {%- endif -%} + {%- if subnet.bootfile_server %} + next-server {{ subnet.bootfile_server }}; + {%- endif -%} + {%- if subnet.time_offset %} + option time-offset {{ subnet.time_offset }}; + {%- endif -%} + {%- if subnet.wpad_url %} + option wpad-url "{{ subnet.wpad_url }}"; + {%- endif -%} + {%- if subnet.client_prefix_length %} + option subnet-mask {{ subnet.client_prefix_length }}; + {%- endif -%} + {% if subnet.lease %} + default-lease-time {{ subnet.lease }}; + max-lease-time {{ subnet.lease }}; + {%- endif -%} + {%- for host in subnet.static_mapping %} + {% if not host.disabled -%} + host {% if host_decl_name -%} {{ host.name }} {%- else -%} {{ network.name }}_{{ host.name }} {%- endif %} { + {%- if host.ip_address %} + fixed-address {{ host.ip_address }}; + {%- endif %} + hardware ethernet {{ host.mac_address }}; + {%- if host.static_parameters %} + # The following {{ host.static_parameters | length }} line(s) were added as static-mapping-parameters in the CLI and have not been validated + {%- for param in host.static_parameters %} + {{ param }} + {%- endfor -%} + {%- endif %} + } + {%- endif %} + {%- endfor %} + {%- if subnet.failover_name %} + pool { + failover peer "{{ subnet.failover_name }}"; + deny dynamic bootp clients; + {%- for range in subnet.range %} + range {{ range.start }} {{ range.stop }}; + {%- endfor %} + } + {%- else %} + {%- for range in subnet.range %} + range {{ range.start }} {{ range.stop }}; + {%- endfor %} + {%- endif %} + } + {%- endfor %} + on commit { + set shared-networkname = "{{ network.name }}"; + {% if hostfile_update -%} + set ClientName = pick-first-value(host-decl-name, option fqdn.hostname, option host-name); + set ClientIp = binary-to-ascii(10, 8, ".", leased-address); + set ClientMac = binary-to-ascii(16, 8, ":", substring(hardware, 1, 6)); + set ClientDomain = pick-first-value(config-option domain-name, "..YYZ!"); + execute("/usr/libexec/vyos/system/on-dhcp-event.sh", "commit", ClientName, ClientIp, ClientMac, ClientDomain); + {%- endif %} + } +} +{%- endif %} +{% endfor %} diff --git a/data/templates/dhcpv6-relay/config.tmpl b/data/templates/dhcpv6-relay/config.tmpl new file mode 100644 index 000000000..55035ae6c --- /dev/null +++ b/data/templates/dhcpv6-relay/config.tmpl @@ -0,0 +1,4 @@ +### Autogenerated by dhcpv6_relay.py ### + +# Defaults for isc-dhcp-relay6.service +OPTIONS="-l {{ listen_addr | join(' -l ') }} -u {{ upstream_addr | join(' -u ') }} {{ options | join(' ') }}" diff --git a/data/templates/dhcpv6-server/dhcpdv6.conf.tmpl b/data/templates/dhcpv6-server/dhcpdv6.conf.tmpl new file mode 100644 index 000000000..ff7822b0d --- /dev/null +++ b/data/templates/dhcpv6-server/dhcpdv6.conf.tmpl @@ -0,0 +1,81 @@ +### Autogenerated by dhcpv6_server.py ### + +# For options please consult the following website: +# https://www.isc.org/wp-content/uploads/2017/08/dhcp43options.html + +log-facility local7; +{%- if preference %} +option dhcp6.preference {{ preference }}; +{%- endif %} + +# Shared network configration(s) +{% for network in shared_network %} +{%- if not network.disabled -%} +shared-network {{ network.name }} { + {%- for subnet in network.subnet %} + subnet6 {{ subnet.network }} { + {%- for range in subnet.range6_prefix %} + range6 {{ range.prefix }}{{ " temporary" if range.temporary }}; + {%- endfor %} + {%- for range in subnet.range6 %} + range6 {{ range.start }} {{ range.stop }}; + {%- endfor %} + {%- if subnet.domain_search %} + option dhcp6.domain-search "{{ subnet.domain_search | join('", "') }}"; + {%- endif %} + {%- if subnet.lease_def %} + default-lease-time {{ subnet.lease_def }}; + {%- endif %} + {%- if subnet.lease_max %} + max-lease-time {{ subnet.lease_max }}; + {%- endif %} + {%- if subnet.lease_min %} + min-lease-time {{ subnet.lease_min }}; + {%- endif %} + {%- if subnet.dns_server %} + option dhcp6.name-servers {{ subnet.dns_server | join(', ') }}; + {%- endif %} + {%- if subnet.nis_domain %} + option dhcp6.nis-domain-name "{{ subnet.nis_domain }}"; + {%- endif %} + {%- if subnet.nis_server %} + option dhcp6.nis-servers {{ subnet.nis_server | join(', ') }}; + {%- endif %} + {%- if subnet.nisp_domain %} + option dhcp6.nisp-domain-name "{{ subnet.nisp_domain }}"; + {%- endif %} + {%- if subnet.nisp_server %} + option dhcp6.nisp-servers {{ subnet.nisp_server | join(', ') }}; + {%- endif %} + {%- if subnet.sip_address %} + option dhcp6.sip-servers-addresses {{ subnet.sip_address | join(', ') }}; + {%- endif %} + {%- if subnet.sip_hostname %} + option dhcp6.sip-servers-names "{{ subnet.sip_hostname | join('", "') }}"; + {%- endif %} + {%- if subnet.sntp_server %} + option dhcp6.sntp-servers {{ subnet.sntp_server | join(', ') }}; + {%- endif %} + {%- for prefix in subnet.prefix_delegation %} + prefix6 {{ prefix.start }} {{ prefix.stop }} /{{ prefix.length }}; + {%- endfor %} + {%- for host in subnet.static_mapping %} + {% if not host.disabled -%} + host {{ network.name }}_{{ host.name }} { + {%- if host.client_identifier %} + host-identifier option dhcp6.client-id {{ host.client_identifier }}; + {%- endif %} + {%- if host.ipv6_address %} + fixed-address6 {{ host.ipv6_address }}; + {%- endif %} + } + {%- endif %} + {%- endfor %} + } + {%- endfor %} + on commit { + set shared-networkname = "{{ network.name }}"; + } +} +{%- endif %} +{% endfor %} diff --git a/data/templates/dns-forwarding/recursor.conf.lua.tmpl b/data/templates/dns-forwarding/recursor.conf.lua.tmpl new file mode 100644 index 000000000..e2506238d --- /dev/null +++ b/data/templates/dns-forwarding/recursor.conf.lua.tmpl @@ -0,0 +1,9 @@ +-- Autogenerated by VyOS (dns_forwarding.py) -- +-- Do not edit, your changes will get overwritten -- + +-- Load DNSSEC root keys from dns-root-data package. +dofile("/usr/share/pdns-recursor/lua-config/rootkeys.lua") + +-- Load lua from vyos-hostsd -- +dofile("recursor.vyos-hostsd.conf.lua") + diff --git a/data/templates/dns-forwarding/recursor.conf.tmpl b/data/templates/dns-forwarding/recursor.conf.tmpl new file mode 100644 index 000000000..d233b8abc --- /dev/null +++ b/data/templates/dns-forwarding/recursor.conf.tmpl @@ -0,0 +1,33 @@ +### Autogenerated by dns_forwarding.py ### + +# XXX: pdns recursor doesn't like whitespace near entry separators, +# especially in the semicolon-separated lists of name servers. +# Please be careful if you edit the template. + +# Non-configurable defaults +daemon=yes +threads=1 +allow-from={{ allow_from | join(',') }} +log-common-errors=yes +non-local-bind=yes +query-local-address=0.0.0.0 +query-local-address6=:: +lua-config-file=recursor.conf.lua + +# cache-size +max-cache-entries={{ cache_size }} + +# negative TTL for NXDOMAIN +max-negative-ttl={{ negative_ttl }} + +# ignore-hosts-file +export-etc-hosts={{ export_hosts_file }} + +# listen-address +local-address={{ listen_address | join(',') }} + +# dnssec +dnssec={{ dnssec }} + +forward-zones-file=recursor.forward-zones.conf + diff --git a/data/templates/dns-forwarding/recursor.forward-zones.conf.tmpl b/data/templates/dns-forwarding/recursor.forward-zones.conf.tmpl new file mode 100644 index 000000000..de5eaee00 --- /dev/null +++ b/data/templates/dns-forwarding/recursor.forward-zones.conf.tmpl @@ -0,0 +1,28 @@ +# Autogenerated by VyOS (vyos-hostsd) +# Do not edit, your changes will get overwritten + +# dot zone (catch-all): '+' indicates recursion is desired +# (same as forward-zones-recurse) +{#- the code below ensures the order of nameservers is determined first by #} +{#- the order of tags, then by the order of nameservers within that tag #} +{%- set n = namespace(dot_zone_ns='') %} +{%- for tag in name_server_tags_recursor %} +{%- set ns = '' %} +{%- if tag in name_servers %} +{%- set ns = ns + name_servers[tag]|join(', ') %} +{%- set n.dot_zone_ns = (n.dot_zone_ns, ns)|join(', ') if n.dot_zone_ns != '' else ns %} +{%- endif %} +# {{ tag }}: {{ ns }} +{%- endfor %} + +{%- if n.dot_zone_ns %} ++.={{ n.dot_zone_ns }} +{%- endif %} + +{% if forward_zones -%} +# zones added via 'service dns forwarding domain' +{%- for zone, zonedata in forward_zones.items() %} +{% if zonedata['recursion-desired'] %}+{% endif %}{{ zone }}={{ zonedata['nslist']|join(', ') }} +{%- endfor %} +{%- endif %} + diff --git a/data/templates/dns-forwarding/recursor.vyos-hostsd.conf.lua.tmpl b/data/templates/dns-forwarding/recursor.vyos-hostsd.conf.lua.tmpl new file mode 100644 index 000000000..b0d99d9ae --- /dev/null +++ b/data/templates/dns-forwarding/recursor.vyos-hostsd.conf.lua.tmpl @@ -0,0 +1,24 @@ +-- Autogenerated by VyOS (vyos-hostsd) -- +-- Do not edit, your changes will get overwritten -- + +{% if hosts -%} +-- from 'system static-host-mapping' and DHCP server +{%- for tag, taghosts in hosts.items() %} +{%- for host, hostprops in taghosts.items() %} +addNTA("{{ host }}.", "{{ tag }}") +{%- for a in hostprops['aliases'] %} +addNTA("{{ a }}.", "{{ tag }} alias") +{%- endfor %} +{%- endfor %} +{%- endfor %} +{%- endif %} + +{% if forward_zones -%} +-- from 'service dns forwarding domain' +{%- for zone, zonedata in forward_zones.items() %} +{%- if zonedata['addNTA'] %} +addNTA("{{ zone }}", "static") +{%- endif %} +{%- endfor %} +{%- endif %} + diff --git a/data/templates/dynamic-dns/ddclient.conf.tmpl b/data/templates/dynamic-dns/ddclient.conf.tmpl new file mode 100644 index 000000000..9c7219230 --- /dev/null +++ b/data/templates/dynamic-dns/ddclient.conf.tmpl @@ -0,0 +1,46 @@ +### Autogenerated by dynamic_dns.py ### +daemon=1m +syslog=yes +ssl=yes + +{% for interface in interfaces -%} + +# +# ddclient configuration for interface "{{ interface.interface }}": +# +{% if interface.web_url -%} +use=web, web='{{ interface.web_url}}' {%- if interface.web_skip %}, web-skip='{{ interface.web_skip }}'{% endif %} +{% else -%} +use=if, if={{ interface.interface }} +{% endif -%} + +{% for rfc in interface.rfc2136 -%} +{% for record in rfc.record %} +# RFC2136 dynamic DNS configuration for {{ record }}.{{ rfc.zone }} +server={{ rfc.server }} +protocol=nsupdate +password={{ rfc.keyfile }} +ttl={{ rfc.ttl }} +zone={{ rfc.zone }} +{{ record }} +{% endfor -%} +{% endfor -%} + +{% for srv in interface.service %} +{% for host in srv.host %} +# DynDNS provider configuration for {{ host }} +protocol={{ srv.protocol }}, +max-interval=28d, +login={{ srv.login }}, +password='{{ srv.password }}', +{% if srv.server -%} +server={{ srv.server }}, +{% endif -%} +{% if srv.zone -%} +zone={{ srv.zone }}, +{% endif -%} +{{ host }} +{% endfor %} +{% endfor %} + +{% endfor %} diff --git a/data/templates/firewall/nftables-nat.tmpl b/data/templates/firewall/nftables-nat.tmpl new file mode 100644 index 000000000..0c29f536b --- /dev/null +++ b/data/templates/firewall/nftables-nat.tmpl @@ -0,0 +1,157 @@ +#!/usr/sbin/nft -f + +# Start with clean NAT table +flush table nat + +{% if helper_functions == 'remove' %} +{# NAT if going to be disabled - remove rules and targets from nftables #} + +{% set base_command = "delete rule ip raw" %} +{{ base_command }} PREROUTING handle {{ pre_ct_ignore }} +{{ base_command }} OUTPUT handle {{ out_ct_ignore }} +{{ base_command }} PREROUTING handle {{ pre_ct_conntrack }} +{{ base_command }} OUTPUT handle {{ out_ct_conntrack }} + +delete chain ip raw NAT_CONNTRACK + +{% elif helper_functions == 'add' %} +{# NAT if enabled - add targets to nftables #} +add chain ip raw NAT_CONNTRACK +add rule ip raw NAT_CONNTRACK counter accept + +{% set base_command = "add rule ip raw" %} + +{{ base_command }} PREROUTING position {{ pre_ct_ignore }} counter jump VYATTA_CT_HELPER +{{ base_command }} OUTPUT position {{ out_ct_ignore }} counter jump VYATTA_CT_HELPER +{{ base_command }} PREROUTING position {{ pre_ct_conntrack }} counter jump NAT_CONNTRACK +{{ base_command }} OUTPUT position {{ out_ct_conntrack }} counter jump NAT_CONNTRACK +{% endif %} + +{% macro nat_rule(rule, chain) %} +{% set src_addr = "ip saddr " + rule.source_address if rule.source_address %} +{% set dst_addr = "ip daddr " + rule.dest_address if rule.dest_address %} + +{# negated port groups need special treatment, move != in front of { } group #} +{% if rule.source_port.startswith('!=') %} +{% set src_port = "sport != { " + rule.source_port.replace('!=','') +" }" if rule.source_port %} +{% else %} +{% set src_port = "sport { " + rule.source_port +" }" if rule.source_port %} +{% endif %} + +{# negated port groups need special treatment, move != in front of { } group #} +{% if rule.dest_port.startswith('!=') %} +{% set dst_port = "dport != { " + rule.dest_port.replace('!=','') +" }" if rule.dest_port %} +{% else %} +{% set dst_port = "dport { " + rule.dest_port +" }" if rule.dest_port %} +{% endif %} + +{% set comment = "DST-NAT-" + rule.number %} + +{% if chain == "PREROUTING" %} +{% set interface = " iifname \"" + rule.interface_in + "\"" if rule.interface_in is defined and rule.interface_in != 'any' else '' %} +{% set trns_addr = "dnat to " + rule.translation_address %} + +{% elif chain == "POSTROUTING" %} +{% set interface = " oifname \"" + rule.interface_out + "\"" if rule.interface_out is defined and rule.interface_out != 'any' else '' %} +{% if rule.translation_address == 'masquerade' %} +{% set trns_addr = rule.translation_address %} +{% if rule.translation_port %} +{% set trns_addr = trns_addr + " to " %} +{% endif %} +{% else %} +{% set trns_addr = "snat to " + rule.translation_address %} +{% endif %} +{% endif %} +{% set trns_port = ":" + rule.translation_port if rule.translation_port %} + +{% if rule.protocol == "tcp_udp" %} +{% set protocol = "tcp" %} +{% set comment = comment + " tcp_udp" %} +{% else %} +{% set protocol = rule.protocol %} +{% endif %} + +{% if rule.log %} +{% set base_log = "[NAT-DST-" + rule.number %} +{% if rule.exclude %} +{% set log = base_log + "-EXCL]" %} +{% elif rule.translation_address == 'masquerade' %} +{% set log = base_log + "-MASQ]" %} +{% else %} +{% set log = base_log + "]" %} +{% endif %} +{% endif %} + +{% if rule.exclude %} +{# rule has been marked as "exclude" thus we simply return here #} +{% set trns_addr = "return" %} +{% set trns_port = "" %} +{% endif %} + +{% set output = "add rule ip nat " + chain + interface %} + +{% if protocol != "all" %} +{% set output = output + " ip protocol " + protocol %} +{% endif %} + +{% if src_addr %} +{% set output = output + " " + src_addr %} +{% endif %} +{% if src_port %} +{% set output = output + " " + protocol + " " + src_port %} +{% endif %} + +{% if dst_addr %} +{% set output = output + " " + dst_addr %} +{% endif %} +{% if dst_port %} +{% set output = output + " " + protocol + " " + dst_port %} +{% endif %} + +{# Count packets #} +{% set output = output + " counter" %} + +{# Special handling of log option, we must repeat the entire rule before the #} +{# NAT translation options are added, this is essential #} +{% if log %} +{% set log_output = output + " log prefix \"" + log + "\" comment \"" + comment + "\"" %} +{% endif %} + +{% if trns_addr %} +{% set output = output + " " + trns_addr %} +{% endif %} + +{% if trns_port %} +{# Do not add a whitespace here, translation port must be directly added after IP address #} +{# e.g. 192.0.2.10:3389 #} +{% set output = output + trns_port %} +{% endif %} + +{% if comment %} +{% set output = output + " comment \"" + comment + "\"" %} +{% endif %} + +{{ log_output if log_output }} +{{ output }} + +{# Special handling if protocol is tcp_udp, we must repeat the entire rule with udp as protocol #} +{% if rule.protocol == "tcp_udp" %} +{# Beware of trailing whitespace, without it the comment tcp_udp will be changed to udp_udp #} +{{ log_output | replace("tcp ", "udp ") if log_output }} +{{ output | replace("tcp ", "udp ") }} +{% endif %} +{% endmacro %} + +# +# Destination NAT rules build up here +# +{% for rule in destination if not rule.disabled -%} +{{ nat_rule(rule, 'PREROUTING') }} +{% endfor %} + +# +# Source NAT rules build up here +# +{% for rule in source if not rule.disabled -%} +{{ nat_rule(rule, 'POSTROUTING') }} +{% endfor %} diff --git a/data/templates/frr/bfd.frr.tmpl b/data/templates/frr/bfd.frr.tmpl new file mode 100644 index 000000000..7df4bfd01 --- /dev/null +++ b/data/templates/frr/bfd.frr.tmpl @@ -0,0 +1,16 @@ +! +bfd +{% for peer in old_peers -%} + no peer {{ peer.remote }}{% if peer.multihop %} multihop{% endif %}{% if peer.src_addr %} local-address {{ peer.src_addr }}{% endif %}{% if peer.src_if %} interface {{ peer.src_if }}{% endif %} +{% endfor -%} +! +{% for peer in new_peers -%} + peer {{ peer.remote }}{% if peer.multihop %} multihop{% endif %}{% if peer.src_addr %} local-address {{ peer.src_addr }}{% endif %}{% if peer.src_if %} interface {{ peer.src_if }}{% endif %} + detect-multiplier {{ peer.multiplier }} + receive-interval {{ peer.rx_interval }} + transmit-interval {{ peer.tx_interval }} + {% if peer.echo_mode %}echo-mode{% endif %} + {% if peer.echo_interval != '' %}echo-interval {{ peer.echo_interval }}{% endif %} + {% if not peer.shutdown %}no {% endif %}shutdown +{% endfor -%} +! diff --git a/data/templates/frr/bgp.frr.tmpl b/data/templates/frr/bgp.frr.tmpl new file mode 100644 index 000000000..cdf4cb4fe --- /dev/null +++ b/data/templates/frr/bgp.frr.tmpl @@ -0,0 +1 @@ +! diff --git a/data/templates/frr/igmp.frr.tmpl b/data/templates/frr/igmp.frr.tmpl new file mode 100644 index 000000000..de4696c1f --- /dev/null +++ b/data/templates/frr/igmp.frr.tmpl @@ -0,0 +1,41 @@ +! +{% for iface in old_ifaces -%} +interface {{ iface }} +{% for group in old_ifaces[iface].gr_join -%} +{% if old_ifaces[iface].gr_join[group] -%} +{% for source in old_ifaces[iface].gr_join[group] -%} +no ip igmp join {{ group }} {{ source }} +{% endfor -%} +{% else -%} +no ip igmp join {{ group }} +{% endif -%} +{% endfor -%} +no ip igmp +! +{% endfor -%} +{% for iface in ifaces -%} +interface {{ iface }} +{% if ifaces[iface].version -%} +ip igmp version {{ ifaces[iface].version }} +{% else -%} +{# IGMP default version 3 #} +ip igmp +{% endif -%} +{% if ifaces[iface].query_interval -%} +ip igmp query-interval {{ ifaces[iface].query_interval }} +{% endif -%} +{% if ifaces[iface].query_max_resp_time -%} +ip igmp query-max-response-time {{ ifaces[iface].query_max_resp_time }} +{% endif -%} +{% for group in ifaces[iface].gr_join -%} +{% if ifaces[iface].gr_join[group] -%} +{% for source in ifaces[iface].gr_join[group] -%} +ip igmp join {{ group }} {{ source }} +{% endfor -%} +{% else -%} +ip igmp join {{ group }} +{% endif -%} +{% endfor -%} +! +{% endfor -%} +! diff --git a/data/templates/frr/ldpd.frr.tmpl b/data/templates/frr/ldpd.frr.tmpl new file mode 100644 index 000000000..dbaa917e8 --- /dev/null +++ b/data/templates/frr/ldpd.frr.tmpl @@ -0,0 +1,70 @@ +! +{% if mpls_ldp -%} +mpls ldp +{% if old_router_id -%} +no router-id {{ old_router_id }} +{% endif -%} +{% if router_id -%} +router-id {{ router_id }} +{% endif -%} +{% for neighbor_id in old_ldp.neighbors -%} +no neighbor {{neighbor_id}} password {{old_ldp.neighbors[neighbor_id].password}} +{% endfor -%} +{% for neighbor_id in ldp.neighbors -%} +neighbor {{neighbor_id}} password {{ldp.neighbors[neighbor_id].password}} +{% endfor -%} +address-family ipv4 +label local allocate host-routes +{% if old_ldp.d_transp_ipv4 -%} +no discovery transport-address {{ old_ldp.d_transp_ipv4 }} +{% endif -%} +{% if ldp.d_transp_ipv4 -%} +discovery transport-address {{ ldp.d_transp_ipv4 }} +{% endif -%} +{% if old_ldp.hello_holdtime -%} +no discovery hello holdtime {{ old_ldp.hello_holdtime }} +{% endif -%} +{% if ldp.hello_holdtime -%} +discovery hello holdtime {{ ldp.hello_holdtime }} +{% endif -%} +{% if old_ldp.hello_interval -%} +no discovery hello interval {{ old_ldp.hello_interval }} +{% endif -%} +{% if ldp.hello_interval -%} +discovery hello interval {{ ldp.hello_interval }} +{% endif -%} +{% for interface in old_ldp.interfaces -%} +no interface {{interface}} +{% endfor -%} +{% for interface in ldp.interfaces -%} +interface {{interface}} +{% endfor -%} +! +! +exit-address-family +! +{% if ldp.d_transp_ipv6 -%} +address-family ipv6 +label local allocate host-routes +{% if old_ldp.d_transp_ipv6 -%} +no discovery transport-address {{ old_ldp.d_transp_ipv6 }} +{% endif -%} +{% if ldp.d_transp_ipv6 -%} +discovery transport-address {{ ldp.d_transp_ipv6 }} +{% endif -%} +{% for interface in old_ldp.interfaces -%} +no interface {{interface}} +{% endfor -%} +{% for interface in ldp.interfaces -%} +interface {{interface}} +{% endfor -%} +! +exit-address-family +{% else -%} +no address-family ipv6 +{% endif -%} +! +{% else -%} +no mpls ldp +{% endif -%} +! diff --git a/data/templates/frr/pimd.frr.tmpl b/data/templates/frr/pimd.frr.tmpl new file mode 100644 index 000000000..1d1532c60 --- /dev/null +++ b/data/templates/frr/pimd.frr.tmpl @@ -0,0 +1,34 @@ +! +{% for rp_addr in old_pim.rp -%} +{% for group in old_pim.rp[rp_addr] -%} +no ip pim rp {{ rp_addr }} {{ group }} +{% endfor -%} +{% endfor -%} +{% if old_pim.rp_keep_alive -%} +no ip pim rp keep-alive-timer {{ old_pim.rp_keep_alive }} +{% endif -%} +{% for iface in old_pim.ifaces -%} +interface {{ iface }} +no ip pim +! +{% endfor -%} +{% for iface in pim.ifaces -%} +interface {{ iface }} +ip pim +{% if pim.ifaces[iface].dr_prio -%} +ip pim drpriority {{ pim.ifaces[iface].dr_prio }} +{% endif -%} +{% if pim.ifaces[iface].hello -%} +ip pim hello {{ pim.ifaces[iface].hello }} +{% endif -%} +! +{% endfor -%} +{% for rp_addr in pim.rp -%} +{% for group in pim.rp[rp_addr] -%} +ip pim rp {{ rp_addr }} {{ group }} +{% endfor -%} +{% endfor -%} +{% if pim.rp_keep_alive -%} +ip pim rp keep-alive-timer {{ pim.rp_keep_alive }} +{% endif -%} +! diff --git a/data/templates/frr/rip.frr.tmpl b/data/templates/frr/rip.frr.tmpl new file mode 100644 index 000000000..60bc686bd --- /dev/null +++ b/data/templates/frr/rip.frr.tmpl @@ -0,0 +1,143 @@ +! +{% if rip_conf -%} +router rip +{% if old_default_distance -%} +no distance {{old_default_distance}} +{% endif -%} +{% if default_distance -%} +distance {{default_distance}} +{% endif -%} +{% if old_default_originate -%} +no default-information originate +{% endif -%} +{% if default_originate -%} +default-information originate +{% endif -%} +{% if old_rip.default_metric -%} +no default-metric {{old_rip.default_metric}} +{% endif -%} +{% if rip.default_metric -%} +default-metric {{rip.default_metric}} +{% endif -%} +{% for protocol in old_rip.redist -%} +{% if old_rip.redist[protocol]['metric'] and old_rip.redist[protocol]['route_map'] -%} +no redistribute {{protocol}} metric {{rip.redist[protocol]['metric']}} route-map {{rip.redist[protocol]['route_map']}} +{% elif old_rip.redist[protocol]['metric'] -%} +no redistribute {{protocol}} metric {{old_rip.redist[protocol]['metric']}} +{% elif old_rip.redist[protocol]['route_map'] -%} +no redistribute {{protocol}} route-map {{old_rip.redist[protocol]['route_map']}} +{% else -%} +no redistribute {{protocol}} +{% endif -%} +{% endfor -%} +{% for protocol in rip.redist -%} +{% if rip.redist[protocol]['metric'] and rip.redist[protocol]['route_map'] -%} +redistribute {{protocol}} metric {{rip.redist[protocol]['metric']}} route-map {{rip.redist[protocol]['route_map']}} +{% elif rip.redist[protocol]['metric'] -%} +redistribute {{protocol}} metric {{rip.redist[protocol]['metric']}} +{% elif rip.redist[protocol]['route_map'] -%} +redistribute {{protocol}} route-map {{rip.redist[protocol]['route_map']}} +{% else -%} +redistribute {{protocol}} +{% endif -%} +{% endfor -%} +{% for iface in old_rip.distribute -%} +{% if old_rip.distribute[iface].iface_access_list_in -%} +no distribute-list {{old_rip.distribute[iface].iface_access_list_in}} in {{iface}} +{% endif -%} +{% if old_rip.distribute[iface].iface_access_list_out -%} +no distribute-list {{old_rip.distribute[iface].iface_access_list_out}} out {{iface}} +{% endif -%} +{% if old_rip.distribute[iface].iface_prefix_list_in -%} +no distribute-list prefix {{old_rip.distribute[iface].iface_prefix_list_in}} in {{iface}} +{% endif -%} +{% if old_rip.distribute[iface].iface_prefix_list_out -%} +no distribute-list prefix {{old_rip.distribute[iface].iface_prefix_list_out}} out {{iface}} +{% endif -%} +{% endfor -%} +{% for iface in rip.distribute -%} +{% if rip.distribute[iface].iface_access_list_in -%} +distribute-list {{rip.distribute[iface].iface_access_list_in}} in {{iface}} +{% endif -%} +{% if rip.distribute[iface].iface_access_list_out -%} +distribute-list {{rip.distribute[iface].iface_access_list_out}} out {{iface}} +{% endif -%} +{% if rip.distribute[iface].iface_prefix_list_in -%} +distribute-list prefix {{rip.distribute[iface].iface_prefix_list_in}} in {{iface}} +{% endif -%} +{% if rip.distribute[iface].iface_prefix_list_out -%} +distribute-list prefix {{rip.distribute[iface].iface_prefix_list_out}} out {{iface}} +{% endif -%} +{% endfor -%} +{% if old_rip.dist_acl_in -%} +no distribute-list {{old_rip.dist_acl_in}} in +{% endif -%} +{% if rip.dist_acl_in -%} +distribute-list {{rip.dist_acl_in}} in +{% endif -%} +{% if old_rip.dist_acl_out -%} +no distribute-list {{old_rip.dist_acl_out}} out +{% endif -%} +{% if rip.dist_acl_out -%} +distribute-list {{rip.dist_acl_out}} out +{% endif -%} +{% if old_rip.dist_prfx_in -%} +no distribute-list prefix {{old_rip.dist_prfx_in}} in +{% endif -%} +{% if rip.dist_prfx_in -%} +distribute-list prefix {{rip.dist_prfx_in}} in +{% endif -%} +{% if old_rip.dist_prfx_out -%} +no distribute-list prefix {{old_rip.dist_prfx_out}} out +{% endif -%} +{% if rip.dist_prfx_out -%} +distribute-list prefix {{rip.dist_prfx_out}} out +{% endif -%} +{% for network in old_rip.networks -%} +no network {{network}} +{% endfor -%} +{% for network in rip.networks -%} +network {{network}} +{% endfor -%} +{% for iface in old_rip.ifaces -%} +no network {{iface}} +{% endfor -%} +{% for iface in rip.ifaces -%} +network {{iface}} +{% endfor -%} +{% for neighbor in old_rip.neighbors -%} +no neighbor {{neighbor}} +{% endfor -%} +{% for neighbor in rip.neighbors -%} +neighbor {{neighbor}} +{% endfor -%} +{% for net in rip.net_distance -%} +{% if rip.net_distance[net].access_list and rip.net_distance[net].distance -%} +distance {{rip.net_distance[net].distance}} {{net}} {{rip.net_distance[net].access_list}} +{% else -%} +distance {{rip.net_distance[net].distance}} {{net}} +{% endif -%} +{% endfor -%} +{% for passive_iface in old_rip.passive_iface -%} +no passive-interface {{passive_iface}} +{% endfor -%} +{% for passive_iface in rip.passive_iface -%} +passive-interface {{passive_iface}} +{% endfor -%} +{% for route in old_rip.route -%} +no route {{route}} +{% endfor -%} +{% for route in rip.route -%} +route {{route}} +{% endfor -%} +{% if old_rip.timer_update or old_rip.timer_timeout or old_rip.timer_garbage -%} +no timers basic +{% endif -%} +{% if rip.timer_update or rip.timer_timeout or rip.timer_garbage -%} +timers basic {{rip.timer_update}} {{rip.timer_timeout}} {{rip.timer_garbage}} +{% endif -%} +! +{% else -%} +no router rip +! +{% endif -%} diff --git a/data/templates/frr/static_mcast.frr.tmpl b/data/templates/frr/static_mcast.frr.tmpl new file mode 100644 index 000000000..86d619ab0 --- /dev/null +++ b/data/templates/frr/static_mcast.frr.tmpl @@ -0,0 +1,20 @@ +! +{% for route_gr in old_mroute -%} +{% for nh in old_mroute[route_gr] -%} +{% if old_mroute[route_gr][nh] -%} +no ip mroute {{ route_gr }} {{ nh }} {{ old_mroute[route_gr][nh] }} +{% else -%} +no ip mroute {{ route_gr }} {{ nh }} +{% endif -%} +{% endfor -%} +{% endfor -%} +{% for route_gr in mroute -%} +{% for nh in mroute[route_gr] -%} +{% if mroute[route_gr][nh] -%} +ip mroute {{ route_gr }} {{ nh }} {{ mroute[route_gr][nh] }} +{% else -%} +ip mroute {{ route_gr }} {{ nh }} +{% endif -%} +{% endfor -%} +{% endfor -%} +! diff --git a/data/templates/getty/serial-getty.service.tmpl b/data/templates/getty/serial-getty.service.tmpl new file mode 100644 index 000000000..0183eae7d --- /dev/null +++ b/data/templates/getty/serial-getty.service.tmpl @@ -0,0 +1,37 @@ +[Unit] +Description=Serial Getty on %I +Documentation=man:agetty(8) man:systemd-getty-generator(8) +Documentation=http://0pointer.de/blog/projects/serial-console.html +BindsTo=dev-%i.device +After=dev-%i.device systemd-user-sessions.service plymouth-quit-wait.service getty-pre.target +After=vyos-router.service + +# If additional gettys are spawned during boot then we should make +# sure that this is synchronized before getty.target, even though +# getty.target didn't actually pull it in. +Before=getty.target +IgnoreOnIsolate=yes + +# IgnoreOnIsolate causes issues with sulogin, if someone isolates +# rescue.target or starts rescue.service from multi-user.target or +# graphical.target. +Conflicts=rescue.service +Before=rescue.service + +[Service] +# The '-o' option value tells agetty to replace 'login' arguments with an +# option to preserve environment (-p), followed by '--' for safety, and then +# the entered username. +ExecStart=-/sbin/agetty -o '-p -- \\u' --keep-baud {{ speed }} %I $TERM +Type=idle +Restart=always +UtmpIdentifier=%I +TTYPath=/dev/%I +TTYReset=yes +TTYVHangup=yes +KillMode=process +IgnoreSIGPIPE=no +SendSIGHUP=yes + +[Install] +WantedBy=getty.target diff --git a/data/templates/https/nginx.default.tmpl b/data/templates/https/nginx.default.tmpl new file mode 100644 index 000000000..a20be45ae --- /dev/null +++ b/data/templates/https/nginx.default.tmpl @@ -0,0 +1,69 @@ +### Autogenerated by https.py ### +# Default server configuration +# +server { + listen 80 default_server; + listen [::]:80 default_server; + server_name _; + return 301 https://$server_name$request_uri; +} + +{% for server in server_block_list %} +server { + + # SSL configuration + # +{% if server.address == '*' %} + listen {{ server.port }} ssl; + listen [::]:{{ server.port }} ssl; +{% else %} + listen {{ server.address }}:{{ server.port }} ssl; +{% endif %} + +{% for name in server.name %} + server_name {{ name }}; +{% endfor %} + +{% if server.certbot %} + ssl_certificate {{ server.certbot_dir }}/live/{{ server.certbot_domain_dir }}/fullchain.pem; + ssl_certificate_key {{ server.certbot_dir }}/live/{{ server.certbot_domain_dir }}/privkey.pem; + 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 }}; +{% else %} + # + # Self signed certs generated by the ssl-cert package + # Don't use them in a production server! + # + include snippets/snakeoil.conf; +{% endif %} + + # proxy settings for HTTP API, if enabled; 503, if not + location ~ /(retrieve|configure|config-file|image|generate|show) { +{% if server.api %} + proxy_pass http://localhost:{{ server.api.port }}; + proxy_read_timeout 600; + proxy_buffering off; +{% else %} + return 503; +{% endif %} + } + + error_page 501 502 503 =200 @50*_json; + +{% if api_set %} + location @50*_json { + default_type application/json; + return 200 '{"error": "service https api unavailable at this proxy address: set service https api-restrict virtual-host"}'; + } +{% else %} + location @50*_json { + default_type application/json; + return 200 '{"error": "Start service in configuration mode: set service https api"}'; + } +{% endif %} + +} + +{% endfor %} diff --git a/data/templates/ids/fastnetmon.tmpl b/data/templates/ids/fastnetmon.tmpl new file mode 100644 index 000000000..71a1b2bd7 --- /dev/null +++ b/data/templates/ids/fastnetmon.tmpl @@ -0,0 +1,60 @@ +# enable this option if you want to send logs to local syslog facility +logging:local_syslog_logging = on + +# list of all your networks in CIDR format +networks_list_path = /etc/networks_list + +# list networks in CIDR format which will be not monitored for attacks +white_list_path = /etc/networks_whitelist + +# Enable/Disable any actions in case of attack +enable_ban = on + +## How many packets will be collected from attack traffic +ban_details_records_count = 500 + +## How long (in seconds) we should keep an IP in blocked state +## If you set 0 here it completely disables unban capability +ban_time = 1900 + +# Check if the attack is still active, before triggering an unban callback with this option +# If the attack is still active, check each run of the unban watchdog +unban_only_if_attack_finished = on + +# enable per subnet speed meters +# For each subnet, list track speed in bps and pps for both directions +enable_subnet_counters = off + +{% if "mirror" in mode %} +mirror_afpacket = on +{% endif -%} + +{% if "in" in direction %} +process_incoming_traffic = on +{% endif -%} +{% if "out" in direction %} +process_outgoing_traffic = on +{% endif -%} +{% for th in threshold %} +{% if th == "fps" %} +ban_for_flows = on +threshold_flows = {{ threshold[th] }} +{% endif -%} +{% if th == "mbps" %} +ban_for_bandwidth = on +threshold_mbps = {{ threshold[th] }} +{% endif -%} +{% if th == "pps" %} +ban_for_pps = on +threshold_pps = {{ threshold[th] }} +{% endif -%} +{% endfor -%} + +{% if listen_interface %} +{% set value = listen_interface if listen_interface is string else listen_interface | join(',') %} +interfaces = {{ value }} +{% endif -%} + +{% if alert_script %} +notify_script_path = {{ alert_script }} +{% endif -%} diff --git a/data/templates/ids/fastnetmon_networks_list.tmpl b/data/templates/ids/fastnetmon_networks_list.tmpl new file mode 100644 index 000000000..d58990053 --- /dev/null +++ b/data/templates/ids/fastnetmon_networks_list.tmpl @@ -0,0 +1,7 @@ +{% if network is string %} +{{ network }} +{% else %} +{% for net in network %} +{{ net }} +{% endfor %} +{% endif %} diff --git a/data/templates/igmp-proxy/igmpproxy.conf.tmpl b/data/templates/igmp-proxy/igmpproxy.conf.tmpl new file mode 100644 index 000000000..c7fc5cef5 --- /dev/null +++ b/data/templates/igmp-proxy/igmpproxy.conf.tmpl @@ -0,0 +1,37 @@ +######################################################## +# +# autogenerated by igmp_proxy.py +# +# The configuration file must define one upstream +# interface, and one or more downstream interfaces. +# +# If multicast traffic originates outside the +# upstream subnet, the "altnet" option can be +# used in order to define legal multicast sources. +# (Se example...) +# +# The "quickleave" should be used to avoid saturation +# of the upstream link. The option should only +# be used if it's absolutely nessecary to +# accurately imitate just one Client. +# +######################################################## + +{% if not disable_quickleave -%} +quickleave +{% endif -%} + +{% for interface in interfaces %} +# Configuration for {{ interface.name }} ({{ interface.role }} interface) +{% if interface.role == 'disabled' -%} +phyint {{ interface.name }} disabled +{%- else -%} +phyint {{ interface.name }} {{ interface.role }} ratelimit 0 threshold {{ interface.threshold }} +{%- endif -%} +{%- for subnet in interface.alt_subnet %} + altnet {{ subnet }} +{%- endfor %} +{%- for subnet in interface.whitelist %} + whitelist {{ subnet }} +{%- endfor %} +{% endfor %} diff --git a/data/templates/ipsec/charon.tmpl b/data/templates/ipsec/charon.tmpl new file mode 100644 index 000000000..4d710921e --- /dev/null +++ b/data/templates/ipsec/charon.tmpl @@ -0,0 +1,342 @@ +# Options for the charon IKE daemon. +charon { + + # Accept unencrypted ID and HASH payloads in IKEv1 Main Mode. + # accept_unencrypted_mainmode_messages = no + + # Maximum number of half-open IKE_SAs for a single peer IP. + # block_threshold = 5 + + # Whether Certicate Revocation Lists (CRLs) fetched via HTTP or LDAP should + # be saved under a unique file name derived from the public key of the + # Certification Authority (CA) to /etc/ipsec.d/crls (stroke) or + # /etc/swanctl/x509crl (vici), respectively. + # cache_crls = no + + # Whether relations in validated certificate chains should be cached in + # memory. + # cert_cache = yes + + # Send Cisco Unity vendor ID payload (IKEv1 only). + # cisco_unity = no + + # Close the IKE_SA if setup of the CHILD_SA along with IKE_AUTH failed. + # close_ike_on_child_failure = no + + # Number of half-open IKE_SAs that activate the cookie mechanism. + # cookie_threshold = 10 + + # Delete CHILD_SAs right after they got successfully rekeyed (IKEv1 only). + # delete_rekeyed = no + + # Use ANSI X9.42 DH exponent size or optimum size matched to cryptographic + # strength. + # dh_exponent_ansi_x9_42 = yes + + # Use RTLD_NOW with dlopen when loading plugins and IMV/IMCs to reveal + # missing symbols immediately. + # dlopen_use_rtld_now = no + + # DNS server assigned to peer via configuration payload (CP). + # dns1 = + + # DNS server assigned to peer via configuration payload (CP). + # dns2 = + + # Enable Denial of Service protection using cookies and aggressiveness + # checks. + # dos_protection = yes + + # Compliance with the errata for RFC 4753. + # ecp_x_coordinate_only = yes + + # Free objects during authentication (might conflict with plugins). + # flush_auth_cfg = no + + # Whether to follow IKEv2 redirects (RFC 5685). + # follow_redirects = yes + + # Maximum size (complete IP datagram size in bytes) of a sent IKE fragment + # when using proprietary IKEv1 or standardized IKEv2 fragmentation, defaults + # to 1280 (use 0 for address family specific default values, which uses a + # lower value for IPv4). If specified this limit is used for both IPv4 and + # IPv6. + # fragment_size = 1280 + + # Name of the group the daemon changes to after startup. + # group = + + # Timeout in seconds for connecting IKE_SAs (also see IKE_SA_INIT DROPPING). + # half_open_timeout = 30 + + # Enable hash and URL support. + # hash_and_url = no + + # Allow IKEv1 Aggressive Mode with pre-shared keys as responder. + # i_dont_care_about_security_and_use_aggressive_mode_psk = no + + # Whether to ignore the traffic selectors from the kernel's acquire events + # for IKEv2 connections (they are not used for IKEv1). + # ignore_acquire_ts = no + + # A space-separated list of routing tables to be excluded from route + # lookups. + # ignore_routing_tables = + + # Maximum number of IKE_SAs that can be established at the same time before + # new connection attempts are blocked. + # ikesa_limit = 0 + + # Number of exclusively locked segments in the hash table. + # ikesa_table_segments = 1 + + # Size of the IKE_SA hash table. + # ikesa_table_size = 1 + + # Whether to close IKE_SA if the only CHILD_SA closed due to inactivity. + # inactivity_close_ike = no + + # Limit new connections based on the current number of half open IKE_SAs, + # see IKE_SA_INIT DROPPING in strongswan.conf(5). + # init_limit_half_open = 0 + + # Limit new connections based on the number of queued jobs. + # init_limit_job_load = 0 + + # Causes charon daemon to ignore IKE initiation requests. + # initiator_only = no + + # Install routes into a separate routing table for established IPsec + # tunnels. + install_routes = {{ install_routes }} + + # Install virtual IP addresses. + # install_virtual_ip = yes + + # The name of the interface on which virtual IP addresses should be + # installed. + # install_virtual_ip_on = + + # Check daemon, libstrongswan and plugin integrity at startup. + # integrity_test = no + + # A comma-separated list of network interfaces that should be ignored, if + # interfaces_use is specified this option has no effect. + # interfaces_ignore = + + # A comma-separated list of network interfaces that should be used by + # charon. All other interfaces are ignored. + # interfaces_use = + + # NAT keep alive interval. + # keep_alive = 20s + + # Plugins to load in the IKE daemon charon. + # load = + + # Determine plugins to load via each plugin's load option. + # load_modular = no + + # Initiate IKEv2 reauthentication with a make-before-break scheme. + # make_before_break = no + + # Maximum number of IKEv1 phase 2 exchanges per IKE_SA to keep state about + # and track concurrently. + # max_ikev1_exchanges = 3 + + # Maximum packet size accepted by charon. + # max_packet = 10000 + + # Enable multiple authentication exchanges (RFC 4739). + # multiple_authentication = yes + + # WINS servers assigned to peer via configuration payload (CP). + # nbns1 = + + # WINS servers assigned to peer via configuration payload (CP). + # nbns2 = + + # UDP port used locally. If set to 0 a random port will be allocated. + # port = 500 + + # UDP port used locally in case of NAT-T. If set to 0 a random port will be + # allocated. Has to be different from charon.port, otherwise a random port + # will be allocated. + # port_nat_t = 4500 + + # Prefer locally configured proposals for IKE/IPsec over supplied ones as + # responder (disabling this can avoid keying retries due to + # INVALID_KE_PAYLOAD notifies). + # prefer_configured_proposals = yes + + # By default public IPv6 addresses are preferred over temporary ones (RFC + # 4941), to make connections more stable. Enable this option to reverse + # this. + # prefer_temporary_addrs = no + + # Process RTM_NEWROUTE and RTM_DELROUTE events. + # process_route = yes + + # Delay in ms for receiving packets, to simulate larger RTT. + # receive_delay = 0 + + # Delay request messages. + # receive_delay_request = yes + + # Delay response messages. + # receive_delay_response = yes + + # Specific IKEv2 message type to delay, 0 for any. + # receive_delay_type = 0 + + # Size of the AH/ESP replay window, in packets. + # replay_window = 32 + + # Base to use for calculating exponential back off, see IKEv2 RETRANSMISSION + # in strongswan.conf(5). + # retransmit_base = 1.8 + + # Timeout in seconds before sending first retransmit. + # retransmit_timeout = 4.0 + + # Number of times to retransmit a packet before giving up. + # retransmit_tries = 5 + + # Interval in seconds to use when retrying to initiate an IKE_SA (e.g. if + # DNS resolution failed), 0 to disable retries. + # retry_initiate_interval = 0 + + # Initiate CHILD_SA within existing IKE_SAs (always enabled for IKEv1). + # reuse_ikesa = yes + + # Numerical routing table to install routes to. + # routing_table = + + # Priority of the routing table. + # routing_table_prio = + + # Delay in ms for sending packets, to simulate larger RTT. + # send_delay = 0 + + # Delay request messages. + # send_delay_request = yes + + # Delay response messages. + # send_delay_response = yes + + # Specific IKEv2 message type to delay, 0 for any. + # send_delay_type = 0 + + # Send strongSwan vendor ID payload + # send_vendor_id = no + + # Whether to enable Signature Authentication as per RFC 7427. + # signature_authentication = yes + + # Whether to enable constraints against IKEv2 signature schemes. + # signature_authentication_constraints = yes + + # Number of worker threads in charon. + # threads = 16 + + # Name of the user the daemon changes to after startup. + # user = + + crypto_test { + + # Benchmark crypto algorithms and order them by efficiency. + # bench = no + + # Buffer size used for crypto benchmark. + # bench_size = 1024 + + # Number of iterations to test each algorithm. + # bench_time = 50 + + # Test crypto algorithms during registration (requires test vectors + # provided by the test-vectors plugin). + # on_add = no + + # Test crypto algorithms on each crypto primitive instantiation. + # on_create = no + + # Strictly require at least one test vector to enable an algorithm. + # required = no + + # Whether to test RNG with TRUE quality; requires a lot of entropy. + # rng_true = no + + } + + host_resolver { + + # Maximum number of concurrent resolver threads (they are terminated if + # unused). + # max_threads = 3 + + # Minimum number of resolver threads to keep around. + # min_threads = 0 + + } + + leak_detective { + + # Includes source file names and line numbers in leak detective output. + # detailed = yes + + # Threshold in bytes for leaks to be reported (0 to report all). + # usage_threshold = 10240 + + # Threshold in number of allocations for leaks to be reported (0 to + # report all). + # usage_threshold_count = 0 + + } + + processor { + + # Section to configure the number of reserved threads per priority class + # see JOB PRIORITY MANAGEMENT in strongswan.conf(5). + priority_threads { + + } + + } + + # Section containing a list of scripts (name = path) that are executed when + # the daemon is started. + start-scripts { + + } + + # Section containing a list of scripts (name = path) that are executed when + # the daemon is terminated. + stop-scripts { + + } + + tls { + + # List of TLS encryption ciphers. + # cipher = + + # List of TLS key exchange methods. + # key_exchange = + + # List of TLS MAC algorithms. + # mac = + + # List of TLS cipher suites. + # suites = + + } + + x509 { + + # Discard certificates with unsupported or unknown critical extensions. + # enforce_critical = yes + + } + +} + diff --git a/data/templates/ipsec/ipsec.conf.tmpl b/data/templates/ipsec/ipsec.conf.tmpl new file mode 100644 index 000000000..d0b60765b --- /dev/null +++ b/data/templates/ipsec/ipsec.conf.tmpl @@ -0,0 +1,3 @@ +{{delim_ipsec_l2tp_begin}} +include {{ipsec_ra_conn_file}} +{{delim_ipsec_l2tp_end}} diff --git a/data/templates/ipsec/ipsec.secrets.tmpl b/data/templates/ipsec/ipsec.secrets.tmpl new file mode 100644 index 000000000..55c010a3b --- /dev/null +++ b/data/templates/ipsec/ipsec.secrets.tmpl @@ -0,0 +1,7 @@ +{{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}} diff --git a/data/templates/ipsec/remote-access.tmpl b/data/templates/ipsec/remote-access.tmpl new file mode 100644 index 000000000..fae48232f --- /dev/null +++ b/data/templates/ipsec/remote-access.tmpl @@ -0,0 +1,28 @@ +{{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/lcd/LCDd.conf.tmpl b/data/templates/lcd/LCDd.conf.tmpl new file mode 100644 index 000000000..6cf6a440f --- /dev/null +++ b/data/templates/lcd/LCDd.conf.tmpl @@ -0,0 +1,132 @@ +### Autogenerted by system-display.py ## + +# LCDd.conf -- configuration file for the LCDproc server daemon LCDd +# +# This file contains the configuration for the LCDd server. +# +# The format is ini-file-like. It is divided into sections that start at +# markers that look like [section]. Comments are all line-based comments, +# and are lines that start with '#' or ';'. +# +# The server has a 'central' section named [server]. For the menu there is +# a section called [menu]. Further each driver has a section which +# defines how the driver acts. +# +# The drivers are activated by specifying them in a driver= line in the +# server section, like: +# +# Driver=curses +# +# This tells LCDd to use the curses driver. +# The first driver that is loaded and is capable of output defines the +# size of the display. The default driver to use is curses. +# If the driver is specified using the -d <driver> command line option, +# the Driver= options in the config file are ignored. +# +# The drivers read their own options from the respective sections. + +## Server section with all kinds of settings for the LCDd server ## +[server] + +# Where can we find the driver modules ? +# NOTE: Always place a slash as last character ! +DriverPath=/usr/lib/x86_64-linux-gnu/lcdproc/ + +# Tells the server to load the given drivers. Multiple lines can be given. +# The name of the driver is case sensitive and determines the section +# where to look for further configuration options of the specific driver +# as well as the name of the dynamic driver module to load at runtime. +# The latter one can be changed by giving a File= directive in the +# driver specific section. +# +# The following drivers are supported: +# bayrad, CFontz, CFontzPacket, curses, CwLnx, ea65, EyeboxOne, futaba, +# g15, glcd, glcdlib, glk, hd44780, icp_a106, imon, imonlcd,, IOWarrior, +# irman, joy, lb216, lcdm001, lcterm, linux_input, lirc, lis, MD8800, +# mdm166a, ms6931, mtc_s16209x, MtxOrb, mx5000, NoritakeVFD, +# Olimex_MOD_LCD1x9, picolcd, pyramid, rawserial, sdeclcd, sed1330, +# sed1520, serialPOS, serialVFD, shuttleVFD, sli, stv5730, svga, t6963, +# text, tyan, ula200, vlsys_m428, xosd, yard2LCD + +{% if model is defined %} +{% if model.startswith('cfa-') %} +Driver=CFontzPacket +{% elif model == 'sdec' %} +Driver=sdeclcd +{% endif %} +{% endif %} + +# Tells the driver to bind to the given interface. [default: 127.0.0.1] +Bind=127.0.0.1 + +# Listen on this specified port. [default: 13666] +Port=13666 + +# Sets the reporting level; defaults to warnings and errors only. +# [default: 2; legal: 0-5] +ReportLevel=3 + +# Should we report to syslog instead of stderr? [default: no; legal: yes, no] +ReportToSyslog=yes + +# User to run as. LCDd will drop its root privileges and run as this user +# instead. [default: nobody] +User=nobody + +# The server will stay in the foreground if set to yes. +# [default: no, legal: yes, no] +Foreground=yes + +# Hello message: each entry represents a display line; default: builtin +Hello="Starting VyOS..." + +# GoodBye message: each entry represents a display line; default: builtin +GoodBye="VyOS shutdown..." + +# Sets the interval in microseconds for updating the display. +# [default: 125000 meaning 8Hz] +FrameInterval=500000 # 2 updates per second + +# Sets the default time in seconds to displays a screen. [default: 4] +WaitTime=1 + +# If set to no, LCDd will start with screen rotation disabled. This has the +# same effect as if the ToggleRotateKey had been pressed. Rotation will start +# if the ToggleRotateKey is pressed. Note that this setting does not turn off +# priority sorting of screens. [default: on; legal: on, off] +AutoRotate=on + +# If yes, the the serverscreen will be rotated as a usual info screen. If no, +# it will be a background screen, only visible when no other screens are +# active. The special value 'blank' is similar to no, but only a blank screen +# is displayed. [default: on; legal: on, off, blank] +ServerScreen=blank + +# Set master backlight setting. If set to 'open' a client may control the +# backlight for its own screens (only). [default: open; legal: off, open, on] +Backlight=on + +# Set master heartbeat setting. If set to 'open' a client may control the +# heartbeat for its own screens (only). [default: open; legal: off, open, on] +Heartbeat=off + +# set title scrolling speed [default: 10; legal: 0-10] +TitleSpeed=10 + +{% if model is defined and model is not none %} +{% if model.startswith('cfa-') %} +## CrystalFontz packet driver (for CFA533, CFA631, CFA633 & CFA635) ## +[CFontzPacket] +Model={{ model.split('-')[1] }} +Device={{ device }} +Contrast=350 +Brightness=500 +OffBrightness=50 +Reboot=yes +USB=yes +{% elif model == 'sdec' %} +## SDEC driver for Lanner, Watchguard, Sophos sppliances ## +[sdeclcd] +# No options +{% endif %} +{% endif %} diff --git a/data/templates/lcd/lcdproc.conf.tmpl b/data/templates/lcd/lcdproc.conf.tmpl new file mode 100644 index 000000000..c79f3cd0d --- /dev/null +++ b/data/templates/lcd/lcdproc.conf.tmpl @@ -0,0 +1,60 @@ +### autogenerated by system-lcd.py ### + +# LCDproc client configuration file + +[lcdproc] +Server=127.0.0.1 +Port=13666 + +# set reporting level +ReportLevel=3 + +# report to to syslog ? +ReportToSyslog=true + +Foreground=yes + +[CPU] +Active=true +OnTime=1 +OffTime=2 +ShowInvisible=false + +[SMP-CPU] +Active=false + +[Memory] +Active=false + +[Load] +Active=false + +[Uptime] +Active=true + +[ProcSize] +Active=false + +[Disk] +Active=false + +[About] +Active=false + +[TimeDate] +Active=true +TimeFormat="%H:%M:%S" + +[OldTime] +Active=false + +[BigClock] +Active=false + +[MiniClock] +Active=false + +# Display the title bar in two-line mode. Note that with four lines or more +# the title is always shown. [default: true; legal: true, false] +ShowTitle=false + diff --git a/data/templates/lldp/lldpd.tmpl b/data/templates/lldp/lldpd.tmpl new file mode 100644 index 000000000..3db955b48 --- /dev/null +++ b/data/templates/lldp/lldpd.tmpl @@ -0,0 +1,3 @@ +### Autogenerated by lldp.py ### +DAEMON_ARGS="-M 4{% if options.snmp %} -x{% endif %}{% if options.cdp %} -c{% endif %}{% if options.edp %} -e{% endif %}{% if options.fdp %} -f{% endif %}{% if options.sonmp %} -s{% endif %}" + diff --git a/data/templates/lldp/vyos.conf.tmpl b/data/templates/lldp/vyos.conf.tmpl new file mode 100644 index 000000000..e724f42c6 --- /dev/null +++ b/data/templates/lldp/vyos.conf.tmpl @@ -0,0 +1,20 @@ +### Autogenerated by lldp.py ### + +configure system platform VyOS +configure system description "VyOS {{ options.description }}" +{% if options.listen_on -%} +configure system interface pattern "{{ ( options.listen_on | select('equalto','all') | map('replace','all','*') | list + options.listen_on | select('equalto','!all') | map('replace','!all','!*') | list + options.listen_on | reject('equalto','all') | reject('equalto','!all') | list ) | unique | join(",") }}" +{%- endif %} +{% if options.mgmt_addr -%} +configure system ip management pattern {{ options.mgmt_addr | join(",") }} +{%- endif %} +{%- for loc in location -%} +{%- if loc.elin %} +configure ports {{ loc.name }} med location elin "{{ loc.elin }}" +{%- endif %} +{%- if loc.coordinate_based %} +configure ports {{ loc.name }} med location coordinate {% if loc.coordinate_based.latitude %}latitude {{ loc.coordinate_based.latitude }}{% endif %} {% if loc.coordinate_based.longitude %}longitude {{ loc.coordinate_based.longitude }}{% endif %} {% if loc.coordinate_based.altitude %}altitude {{ loc.coordinate_based.altitude }} m{% endif %} {% if loc.coordinate_based.datum %}datum {{ loc.coordinate_based.datum }}{% endif %} +{%- endif %} + + +{% endfor %} diff --git a/data/templates/macsec/wpa_supplicant.conf.tmpl b/data/templates/macsec/wpa_supplicant.conf.tmpl new file mode 100644 index 000000000..1731bf160 --- /dev/null +++ b/data/templates/macsec/wpa_supplicant.conf.tmpl @@ -0,0 +1,89 @@ +# autogenerated by interfaces-macsec.py + +# see full documentation: +# https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf + +# For UNIX domain sockets (default on Linux and BSD): This is a directory that +# will be created for UNIX domain sockets for listening to requests from +# external programs (CLI/GUI, etc.) for status information and configuration. +# The socket file will be named based on the interface name, so multiple +# wpa_supplicant processes can be run at the same time if more than one +# interface is used. +# /var/run/wpa_supplicant is the recommended directory for sockets and by +# default, wpa_cli will use it when trying to connect with wpa_supplicant. +ctrl_interface=/run/wpa_supplicant + +# Note: When using MACsec, eapol_version shall be set to 3, which is +# defined in IEEE Std 802.1X-2010. +eapol_version=3 + +# No need to scan for access points in MACsec mode +ap_scan=0 + +# EAP fast re-authentication +fast_reauth=1 + +network={ + key_mgmt=NONE + + # Note: When using wired authentication (including MACsec drivers), + # eapol_flags must be set to 0 for the authentication to be completed + # successfully. + eapol_flags=0 + + # macsec_policy: IEEE 802.1X/MACsec options + # This determines how sessions are secured with MACsec (only for MACsec + # drivers). + # 0: MACsec not in use (default) + # 1: MACsec enabled - Should secure, accept key server's advice to + # determine whether to use a secure session or not. + macsec_policy=1 + + # macsec_integ_only: IEEE 802.1X/MACsec transmit mode + # This setting applies only when MACsec is in use, i.e., + # - macsec_policy is enabled + # - the key server has decided to enable MACsec + # 0: Encrypt traffic (default) + # 1: Integrity only + macsec_integ_only={{ '0' if security is defined and security.encrypt is defined else '1' }} + +{% if security is defined %} +{% if security.encrypt is defined %} + # mka_cak, mka_ckn, and mka_priority: IEEE 802.1X/MACsec pre-shared key mode + # This allows to configure MACsec with a pre-shared key using a (CAK,CKN) pair. + # In this mode, instances of wpa_supplicant can act as MACsec peers. The peer + # with lower priority will become the key server and start distributing SAKs. + # mka_cak (CAK = Secure Connectivity Association Key) takes a 16-byte (128-bit) + # hex-string (32 hex-digits) or a 32-byte (256-bit) hex-string (64 hex-digits) + # mka_ckn (CKN = CAK Name) takes a 1..32-bytes (8..256 bit) hex-string + # (2..64 hex-digits) + mka_cak={{ security.mka.cak }} + mka_ckn={{ security.mka.ckn }} + + # mka_priority (Priority of MKA Actor) is in 0..255 range with 255 being + # default priority + mka_priority={{ security.mka.priority }} +{% endif %} + +{% if security.replay_window is defined %} + # macsec_replay_protect: IEEE 802.1X/MACsec replay protection + # This setting applies only when MACsec is in use, i.e., + # - macsec_policy is enabled + # - the key server has decided to enable MACsec + # 0: Replay protection disabled (default) + # 1: Replay protection enabled + macsec_replay_protect=1 + + # macsec_replay_window: IEEE 802.1X/MACsec replay protection window + # This determines a window in which replay is tolerated, to allow receipt + # of frames that have been misordered by the network. + # This setting applies only when MACsec replay protection active, i.e., + # - macsec_replay_protect is enabled + # - the key server has decided to enable MACsec + # 0: No replay window, strict check (default) + # 1..2^32-1: number of packets that could be misordered + macsec_replay_window={{ security.replay_window }} +{% endif %} +{% endif %} +} + diff --git a/data/templates/mdns-repeater/mdns-repeater.tmpl b/data/templates/mdns-repeater/mdns-repeater.tmpl new file mode 100644 index 000000000..80f4ab047 --- /dev/null +++ b/data/templates/mdns-repeater/mdns-repeater.tmpl @@ -0,0 +1,2 @@ +### Autogenerated by mdns_repeater.py ### +DAEMON_ARGS="{{ interface | join(' ') }}" diff --git a/data/templates/netflow/uacctd.conf.tmpl b/data/templates/netflow/uacctd.conf.tmpl new file mode 100644 index 000000000..d8615566f --- /dev/null +++ b/data/templates/netflow/uacctd.conf.tmpl @@ -0,0 +1,69 @@ +# Genereated from VyOS configuration +daemonize: true +promisc: false +pidfile: /var/run/uacctd.pid +uacctd_group: 2 +uacctd_nl_size: 2097152 +snaplen: {{ snaplen }} +aggregate: in_iface,src_mac,dst_mac,vlan,src_host,dst_host,src_port,dst_port,proto,tos,flows +plugin_pipe_size: {{ templatecfg['plugin_pipe_size'] }} +plugin_buffer_size: {{ templatecfg['plugin_buffer_size'] }} +{%- if templatecfg['syslog-facility'] != none %} +syslog: {{ templatecfg['syslog-facility'] }} +{%- endif %} +{%- if templatecfg['disable-imt'] == none %} +imt_path: /tmp/uacctd.pipe +imt_mem_pools_number: 169 +{%- endif %} +plugins: +{%- if templatecfg['netflow']['servers'] != none -%} + {% for server in templatecfg['netflow']['servers'] %} + {%- if loop.last -%}nfprobe[nf_{{ server['address'] }}]{%- else %}nfprobe[nf_{{ server['address'] }}],{%- endif %} + {%- endfor -%} + {% set plugins_presented = true %} +{%- endif %} +{%- if templatecfg['sflow']['servers'] != none -%} + {% if plugins_presented -%} + {%- for server in templatecfg['sflow']['servers'] -%} + ,sfprobe[sf_{{ server['address'] }}] + {%- endfor %} + {%- else %} + {%- for server in templatecfg['sflow']['servers'] %} + {%- if loop.last -%}sfprobe[sf_{{ server['address'] }}]{%- else %}sfprobe[sf_{{ server['address'] }}],{%- endif %} + {%- endfor %} + {%- endif -%} + {% set plugins_presented = true %} +{%- endif %} +{%- if templatecfg['disable-imt'] == none %} + {%- if plugins_presented -%},memory{%- else %}memory{%- endif %} +{%- endif %} +{%- if templatecfg['netflow']['servers'] != none %} +{%- for server in templatecfg['netflow']['servers'] %} +nfprobe_receiver[nf_{{ server['address'] }}]: {{ server['address'] }}:{{ server['port'] }} +nfprobe_version[nf_{{ server['address'] }}]: {{ templatecfg['netflow']['version'] }} +{%- if templatecfg['netflow']['engine-id'] != none %} +nfprobe_engine[nf_{{ server['address'] }}]: {{ templatecfg['netflow']['engine-id'] }} +{%- endif %} +{%- if templatecfg['netflow']['max-flows'] != none %} +nfprobe_maxflows[nf_{{ server['address'] }}]: {{ templatecfg['netflow']['max-flows'] }} +{%- endif %} +{%- if templatecfg['netflow']['sampling-rate'] != none %} +sampling_rate[nf_{{ server['address'] }}]: {{ templatecfg['netflow']['sampling-rate'] }} +{%- endif %} +{%- if templatecfg['netflow']['source-ip'] != none %} +nfprobe_source_ip[nf_{{ server['address'] }}]: {{ templatecfg['netflow']['source-ip'] }} +{%- endif %} +{%- if templatecfg['netflow']['timeout_string'] != '' %} +nfprobe_timeouts[nf_{{ server['address'] }}]: {{ templatecfg['netflow']['timeout_string'] }} +{%- endif %} +{%- endfor %} +{%- endif %} +{%- if templatecfg['sflow']['servers'] != none %} +{%- for server in templatecfg['sflow']['servers'] %} +sfprobe_receiver[sf_{{ server['address'] }}]: {{ server['address'] }}:{{ server['port'] }} +sfprobe_agentip[sf_{{ server['address'] }}]: {{ templatecfg['sflow']['agent-address'] }} +{%- if templatecfg['sflow']['sampling-rate'] != none %} +sampling_rate[sf_{{ server['address'] }}]: {{ templatecfg['sflow']['sampling-rate'] }} +{%- endif %} +{%- endfor %} +{% endif %} diff --git a/data/templates/ntp/ntp.conf.tmpl b/data/templates/ntp/ntp.conf.tmpl new file mode 100644 index 000000000..6ef0c0f2c --- /dev/null +++ b/data/templates/ntp/ntp.conf.tmpl @@ -0,0 +1,47 @@ +### Autogenerated by ntp.py ### + +# +# Non-configurable defaults +# +driftfile /var/lib/ntp/ntp.drift +# By default, only allow ntpd to query time sources, ignore any incoming requests +restrict default noquery nopeer notrap nomodify +# Local users have unrestricted access, allowing reconfiguration via ntpdc +restrict 127.0.0.1 +restrict -6 ::1 + +# +# Configurable section +# +{% if server %} +{% for srv in server %} +{% set options = '' %} +{% set options = options + 'noselect ' if server[srv].noselect is defined else '' %} +{% set options = options + 'preempt ' if server[srv].preempt is defined else '' %} +{% set options = options + 'prefer ' if server[srv].prefer is defined else '' %} +server {{ srv | replace('_', '-') }} iburst {{ options }} +{% endfor %} +{% endif %} + +{% if allow_clients is defined and allow_clients.address is defined %} +# Allowed clients configuration +{% if allow_clients.address is string %} +restrict {{ allow_clients.address|address_from_cidr }} mask {{ allow_clients.address|netmask_from_cidr }} nomodify notrap nopeer +{% else %} +{% for address in allow_clients.address %} +restrict {{ address|address_from_cidr }} mask {{ address|netmask_from_cidr }} nomodify notrap nopeer +{% endfor %} +{% endif %} +{% endif %} + +{% if listen_address %} +# NTP should listen on configured addresses only +interface ignore wildcard +{% if listen_address is string %} +interface listen {{ listen_address }} +{% else %} +{% for address in listen_address %} +interface listen {{ address }} +{% endfor %} +{% endif %} +{% endif %} diff --git a/data/templates/ntp/override.conf.tmpl b/data/templates/ntp/override.conf.tmpl new file mode 100644 index 000000000..466638e5a --- /dev/null +++ b/data/templates/ntp/override.conf.tmpl @@ -0,0 +1,11 @@ +{% set vrf_command = '/sbin/ip vrf exec ' + vrf + ' ' if vrf is defined else '' %} +[Unit] +StartLimitIntervalSec=0 +After=vyos-router.service + +[Service] +ExecStart= +ExecStart={{vrf_command}}/usr/lib/ntp/ntp-systemd-wrapper +Restart=on-failure +RestartSec=10 + diff --git a/data/templates/ocserv/ocserv_config.tmpl b/data/templates/ocserv/ocserv_config.tmpl new file mode 100644 index 000000000..6aaeff693 --- /dev/null +++ b/data/templates/ocserv/ocserv_config.tmpl @@ -0,0 +1,82 @@ +### generated by vpn_anyconnect.py ### + +tcp-port = {{ listen_ports.tcp }} +udp-port = {{ listen_ports.udp }} + +run-as-user = nobody +run-as-group = daemon + +{% if "radius" in authentication.mode %} +auth = "radius [config=/run/ocserv/radiusclient.conf]" +{% else %} +auth = "plain[/run/ocserv/ocpasswd]" +{% endif %} + +{% if ssl.cert_file %} +server-cert = {{ ssl.cert_file }} +{% endif %} + +{% if ssl.key_file %} +server-key = {{ ssl.key_file }} +{% endif %} + +{% if ssl.ca_cert_file %} +ca-cert = {{ ssl.ca_cert_file }} +{% endif %} + +socket-file = /run/ocserv/ocserv.socket +occtl-socket-file = /run/ocserv/occtl.socket +use-occtl = true +isolate-workers = true +keepalive = 300 +dpd = 60 +mobile-dpd = 300 +switch-to-tcp-timeout = 30 +tls-priorities = "NORMAL:%SERVER_PRECEDENCE:%COMPAT:-RSA:-VERS-SSL3.0:-ARCFOUR-128" +auth-timeout = 240 +idle-timeout = 1200 +mobile-idle-timeout = 1800 +min-reauth-time = 3 +cookie-timeout = 300 +rekey-method = ssl +try-mtu-discovery = true +cisco-client-compat = true +dtls-legacy = true + + +# The name to use for the tun device +device = sslvpn + +# An alternative way of specifying the network: +{% if network_settings %} +# DNS settings +{% if network_settings.name_server is string %} +dns = {{ network_settings.name_server }} +{% else %} +{% for dns in network_settings.name_server %} +dns = {{ dns }} +{% endfor %} +{% endif %} +# IPv4 network pool +{% if network_settings.client_ip_settings %} +{% if network_settings.client_ip_settings.subnet %} +ipv4-network = {{ network_settings.client_ip_settings.subnet }} +{% endif %} +{% endif %} +# IPv6 network pool +{% if network_settings.client_ipv6_pool %} +{% if network_settings.client_ipv6_pool.prefix %} +ipv6-network = {{ network_settings.client_ipv6_pool.prefix }} +ipv6-subnet-prefix = {{ network_settings.client_ipv6_pool.mask }} +{% endif %} +{% endif %} +{% endif %} + +{% if network_settings.push_route is string %} +route = {{ network_settings.push_route }} +{% else %} +{% for route in network_settings.push_route %} +route = {{ route }} +{% endfor %} +{% endif %} + diff --git a/data/templates/ocserv/ocserv_passwd.tmpl b/data/templates/ocserv/ocserv_passwd.tmpl new file mode 100644 index 000000000..ffadb4860 --- /dev/null +++ b/data/templates/ocserv/ocserv_passwd.tmpl @@ -0,0 +1,6 @@ +#<username>:<group>:<hash> +{% for user in username if username is defined %} +{% if not "disable" in username[user] %} +{{ user }}:*:{{ username[user].hash }} +{% endif %} +{% endfor %}
\ No newline at end of file diff --git a/data/templates/ocserv/radius_conf.tmpl b/data/templates/ocserv/radius_conf.tmpl new file mode 100644 index 000000000..2d19306a0 --- /dev/null +++ b/data/templates/ocserv/radius_conf.tmpl @@ -0,0 +1,22 @@ +### generated by cpn_anyconnect.py ### +nas-identifier VyOS +{% for srv in server %} +{% if not "disable" in server[srv] %} +{% if "port" in server[srv] %} +authserver {{ srv }}:{{server[srv]["port"]}} +{% else %} +authserver {{ srv }} +{% endif %} +{% endif %} +{% endfor %} +radius_timeout {{ timeout }} +{% if source_address %} +bindaddr {{ source_address }} +{% else %} +bindaddr * +{% endif %} +servers /run/ocserv/radius_servers +dictionary /etc/radcli/dictionary +default_realm +radius_retries 3 +#
\ No newline at end of file diff --git a/data/templates/ocserv/radius_servers.tmpl b/data/templates/ocserv/radius_servers.tmpl new file mode 100644 index 000000000..ba21fa074 --- /dev/null +++ b/data/templates/ocserv/radius_servers.tmpl @@ -0,0 +1,7 @@ +### generated by cpn_anyconnect.py ### +# server key +{% for srv in server %} +{% if not "disable" in server[srv] %} +{{ srv }} {{ server[srv].key }} +{% endif %} +{% endfor %} diff --git a/data/templates/openvpn/client.conf.tmpl b/data/templates/openvpn/client.conf.tmpl new file mode 100644 index 000000000..508d8da94 --- /dev/null +++ b/data/templates/openvpn/client.conf.tmpl @@ -0,0 +1,35 @@ +### Autogenerated by interfaces-openvpn.py ### + +{% if ip -%} +ifconfig-push {{ ip[0] }} {{ remote_netmask }} +{% endif -%} + +{% for route in push_route -%} +push "route {{ route }}" +{% endfor -%} + +{% for net in subnet -%} +iroute {{ net }} +{% endfor -%} + +{# ipv6_remote is only set when IPv6 server is enabled #} +{% if ipv6_remote -%} +# IPv6 + +{%- if ipv6_ip %} +ifconfig-ipv6-push {{ ipv6_ip[0] }} {{ ipv6_remote }} +{%- endif %} + +{%- for route6 in ipv6_push_route %} +push "route-ipv6 {{ route6 }}" +{%- endfor %} + +{%- for net6 in ipv6_subnet %} +iroute {{ net6 }} +{%- endfor %} + +{% endif -%} + +{% if disable -%} +disable +{% endif -%} diff --git a/data/templates/openvpn/server.conf.tmpl b/data/templates/openvpn/server.conf.tmpl new file mode 100644 index 000000000..401f8e04b --- /dev/null +++ b/data/templates/openvpn/server.conf.tmpl @@ -0,0 +1,262 @@ +### Autogenerated by interfaces-openvpn.py ### +# +# See https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage +# for individual keyword definition + +{% if description -%} +# {{ description }} + +{% endif -%} + +verb 3 + +user {{ uid }} +group {{ gid }} + +dev-type {{ type }} +dev {{ intf }} +persist-key +iproute /usr/libexec/vyos/system/unpriv-ip + +proto {{ protocol_real }} + +{%- if local_host %} +local {{ local_host }} +{%- endif %} + +{%- if mode == 'server' and protocol == 'udp' and not local_host %} +multihome +{%- endif %} + +{%- if local_port %} +lport {{ local_port }} +{%- endif %} + +{% if remote_port -%} +rport {{ remote_port }} +{% endif %} + +{%- if remote_host %} +{%- for remote in remote_host -%} +remote {{ remote }} +{% endfor -%} +{% endif -%} + +{% if shared_secret_file %} +secret {{ shared_secret_file }} +{%- endif %} + +{%- if persistent_tunnel %} +persist-tun +{%- endif %} + +{%- if redirect_gateway %} +push "redirect-gateway {{ redirect_gateway }}" +{%- endif %} + +{%- if compress_lzo %} +compress lzo +{%- endif %} + +{% if 'client' in mode -%} +# +# OpenVPN Client mode +# +client +nobind + +{% elif 'server' in mode -%} +# +# OpenVPN Server mode +# + +{%- if server_topology %} +topology {% if server_topology == 'point-to-point' %}p2p{% else %}{{ server_topology }}{% endif %} +{%- endif %} + +{%- if is_bridge_member %} +mode server +tls-server +{%- else %} +server {{ server_subnet[0] }} nopool +{%- endif %} + +{%- if server_pool %} +ifconfig-pool {{ server_pool_start }} {{ server_pool_stop }}{% if server_pool_netmask %} {{ server_pool_netmask }}{% endif %} +{%- endif %} + +{%- if server_max_conn %} +max-clients {{ server_max_conn }} +{%- endif %} + +{%- if client %} +client-config-dir /run/openvpn/ccd/{{ intf }} +{%- endif %} + +{%- if server_reject_unconfigured %} +ccd-exclusive +{%- endif %} + +keepalive {{ ping_interval }} {{ ping_restart }} +management /run/openvpn/openvpn-mgmt-intf unix + +{% for route in server_push_route -%} +push "route {{ route }}" +{% endfor -%} + +{% for ns in server_dns_nameserver -%} +push "dhcp-option DNS {{ ns }}" +{% endfor -%} + +{%- if server_domain -%} +push "dhcp-option DOMAIN {{ server_domain }}" +{% endif -%} + +{%- if server_ipv6_local %} +# IPv6 +push "tun-ipv6" +ifconfig-ipv6 {{ server_ipv6_local }}/{{ server_ipv6_prefixlen }} {{ server_ipv6_remote }} + +{%- if server_ipv6_pool %} +ifconfig-ipv6-pool {{ server_ipv6_pool_base }}/{{ server_ipv6_pool_prefixlen }} +{%- endif %} + +{%- for route6 in server_ipv6_push_route %} +push "route-ipv6 {{ route6 }}" +{%- endfor %} + +{%- for ns6 in server_ipv6_dns_nameserver %} +push "dhcp-option DNS6 {{ ns6 }}" +{%- endfor %} + +{%- endif %} + +{% else -%} +# +# OpenVPN site-2-site mode +# +ping {{ ping_interval }} +ping-restart {{ ping_restart }} + +{% if local_address_subnet -%} +ifconfig {{ local_address[0] }} {{ local_address_subnet }} +{%- elif remote_address -%} +ifconfig {{ local_address[0] }} {{ remote_address[0] }} +{%- endif %} + +{% if ipv6_local_address -%} +ifconfig-ipv6 {{ ipv6_local_address[0] }} {{ ipv6_remote_address[0] }} +{%- endif %} + +{% endif -%} + +{% if tls -%} +# TLS options +{%- if tls_ca_cert %} +ca {{ tls_ca_cert }} +{%- endif %} + +{%- if tls_cert %} +cert {{ tls_cert }} +{%- endif %} + +{%- if tls_key %} +key {{ tls_key }} +{%- endif %} + +{%- if tls_crypt %} +tls-crypt {{ tls_crypt }} +{%- endif %} + +{%- if tls_crl %} +crl-verify {{ tls_crl }} +{%- endif %} + +{%- if tls_version_min %} +tls-version-min {{tls_version_min}} +{%- endif %} + +{%- if tls_dh %} +dh {{ tls_dh }} +{%- endif %} + +{%- if tls_auth %} +tls-auth {{tls_auth}} +{%- endif %} + +{%- if tls_role %} +{%- if 'active' in tls_role %} +tls-client +{%- elif 'passive' in tls_role %} +tls-server +{%- endif %} +{%- endif %} + +{%- endif %} + +# Encryption options +{%- if encryption %} +{% if encryption == 'des' -%} +cipher des-cbc +{%- elif encryption == '3des' -%} +cipher des-ede3-cbc +{%- elif encryption == 'bf128' -%} +cipher bf-cbc +keysize 128 +{%- elif encryption == 'bf256' -%} +cipher bf-cbc +keysize 25 +{%- elif encryption == 'aes128gcm' -%} +cipher aes-128-gcm +{%- elif encryption == 'aes128' -%} +cipher aes-128-cbc +{%- elif encryption == 'aes192gcm' -%} +cipher aes-192-gcm +{%- elif encryption == 'aes192' -%} +cipher aes-192-cbc +{%- elif encryption == 'aes256gcm' -%} +cipher aes-256-gcm +{%- elif encryption == 'aes256' -%} +cipher aes-256-cbc +{%- endif -%} +{%- endif %} + +{%- if ncp_ciphers %} +ncp-ciphers {{ncp_ciphers}} +{%- endif %} +{%- if disable_ncp %} +ncp-disable +{%- endif %} + +{% if hash -%} +auth {{ hash }} +{%- endif -%} + +{%- if auth %} +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 options -%} +# +# Custom options added by user (not validated) +# + +{% for option in options -%} +{{ option }} +{% endfor -%} +{%- endif %} diff --git a/data/templates/pppoe/ip-down.script.tmpl b/data/templates/pppoe/ip-down.script.tmpl new file mode 100644 index 000000000..c2d0cd09a --- /dev/null +++ b/data/templates/pppoe/ip-down.script.tmpl @@ -0,0 +1,36 @@ +#!/bin/sh + +# As PPPoE is an "on demand" interface we need to re-configure it when it +# becomes up +if [ "$6" != "{{ ifname }}" ]; then + exit +fi + +# add some info to syslog +DIALER_PID=$(cat /var/run/{{ ifname }}.pid) +logger -t pppd[$DIALER_PID] "executing $0" + +{% if connect_on_demand is not defined %} +# See https://phabricator.vyos.net/T2248. Determine if we are enslaved to a +# VRF, this is needed to properly insert the default route. +VRF_NAME="" +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=${VRF#"upper_"} + # Populate variable to run in VR context + VRF_NAME="vrf ${VRF_NAME}" +fi + +# Always delete default route when interface goes down +vtysh -c "conf t" ${VRF_NAME} -c "no ip route 0.0.0.0/0 {{ ifname }} ${VRF_NAME}" +{% if ipv6_enable %} +vtysh -c "conf t" ${VRF_NAME} -c "no ipv6 route ::/0 {{ ifname }} ${VRF_NAME}" +{% endif %} +{% endif %} + +{% if dhcpv6_options is defined and dhcpv6_options.pd is defined %} +# Stop wide dhcpv6 client +systemctl stop dhcp6c@{{ ifname }}.service +{% endif %} diff --git a/data/templates/pppoe/ip-pre-up.script.tmpl b/data/templates/pppoe/ip-pre-up.script.tmpl new file mode 100644 index 000000000..cf85ed067 --- /dev/null +++ b/data/templates/pppoe/ip-pre-up.script.tmpl @@ -0,0 +1,18 @@ +#!/bin/sh + +# As PPPoE is an "on demand" interface we need to re-configure it when it +# becomes up +if [ "$6" != "{{ 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 dialer interface $6 for VRF {{ vrf }}" +ip link set dev {{ ifname }} master {{ vrf }} +{% endif %} diff --git a/data/templates/pppoe/ip-up.script.tmpl b/data/templates/pppoe/ip-up.script.tmpl new file mode 100644 index 000000000..568e21c4e --- /dev/null +++ b/data/templates/pppoe/ip-up.script.tmpl @@ -0,0 +1,49 @@ +#!/bin/sh + +# As PPPoE is an "on demand" interface we need to re-configure it when it +# becomes up +if [ "$6" != "{{ ifname }}" ]; then + exit +fi + +{% if connect_on_demand is not defined %} +# add some info to syslog +DIALER_PID=$(cat /var/run/{{ ifname }}.pid) +logger -t pppd[$DIALER_PID] "executing $0" + +{% if default_route != 'none' -%} +# See https://phabricator.vyos.net/T2248 & T2220. Determine if we are enslaved +# to a VRF, this is needed to properly insert the default route. + +SED_OPT="^ip route" +VRF_NAME="" +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=${VRF#"upper_"} + # generate new SED command + SED_OPT="vrf ${VRF}" + # generate vtysh option + VRF_NAME="vrf ${VRF}" +fi + +{% if default_route == 'auto' -%} +# Only insert a new default route if there is no default route configured +routes=$(vtysh -c "show running-config" | sed -n "/${SED_OPT}/,/!/p" | grep 0.0.0.0/0 | wc -l) +if [ "$routes" -ne 0 ]; then + exit 1 +fi + +{% elif default_route == 'force' -%} +# Retrieve current static default routes and remove it from the routing table +vtysh -c "show running-config" | sed -n "/${SED_OPT}/,/!/p" | grep 0.0.0.0/0 | while read route ; do + vtysh -c "conf t" ${VTY_OPT} -c "no ${route} ${VRF_NAME}" +done +{% endif %} + +# Add default route to default or VRF routing table +vtysh -c "conf t" ${VTY_OPT} -c "ip route 0.0.0.0/0 {{ ifname }} ${VRF_NAME}" +logger -t pppd[$DIALER_PID] "added default route via {{ ifname }} ${VRF_NAME}" +{% endif %} +{% endif %} diff --git a/data/templates/pppoe/ipv6-up.script.tmpl b/data/templates/pppoe/ipv6-up.script.tmpl new file mode 100644 index 000000000..d0a62478c --- /dev/null +++ b/data/templates/pppoe/ipv6-up.script.tmpl @@ -0,0 +1,83 @@ +#!/bin/sh + +# As PPPoE is an "on demand" interface we need to re-configure it when it +# becomes up + +if [ "$6" != "{{ ifname }}" ]; then + exit +fi + +{% if ipv6 is defined and ipv6.address is defined and ipv6.address.autoconf is defined -%} +# add some info to syslog +DIALER_PID=$(cat /var/run/{{ ifname }}.pid) +logger -t pppd[$DIALER_PID] "executing $0" +logger -t pppd[$DIALER_PID] "configuring interface {{ ifname }} via {{ source_interface }}" + +# Configure interface-specific Host/Router behaviour. +# Note: It is recommended to have the same setting on all interfaces; mixed +# router/host scenarios are rather uncommon. Possible values are: +# +# 0 Forwarding disabled +# 1 Forwarding enabled +# +echo 1 > /proc/sys/net/ipv6/conf/{{ ifname }}/forwarding + +# Accept Router Advertisements; autoconfigure using them. +# +# It also determines whether or not to transmit Router +# Solicitations. If and only if the functional setting is to +# accept Router Advertisements, Router Solicitations will be +# transmitted. Possible values are: +# +# 0 Do not accept Router Advertisements. +# 1 Accept Router Advertisements if forwarding is disabled. +# 2 Overrule forwarding behaviour. Accept Router Advertisements +# even if forwarding is enabled. +# +echo 2 > /proc/sys/net/ipv6/conf/{{ ifname }}/accept_ra + +# Autoconfigure addresses using Prefix Information in Router Advertisements. +echo 1 > /proc/sys/net/ipv6/conf/{{ ifname }}/autoconf +{% endif %} + +{% if dhcpv6_options is defined and dhcpv6_options.pd is defined %} +# Start wide dhcpv6 client +systemctl start dhcp6c@{{ ifname }}.service +{% endif %} + +{% if default_route != 'none' -%} +# See https://phabricator.vyos.net/T2248 & T2220. Determine if we are enslaved +# to a VRF, this is needed to properly insert the default route. + +SED_OPT="^ipv6 route" +VRF_NAME="" +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=${VRF#"upper_"} + # generate new SED command + SED_OPT="vrf ${VRF}" + # generate vtysh option + VRF_NAME="vrf ${VRF}" +fi + +{% if default_route == 'auto' -%} +# Only insert a new default route if there is no default route configured +routes=$(vtysh -c "show running-config" | sed -n "/${SED_OPT}/,/!/p" | grep ::/0 | wc -l) +if [ "$routes" -ne 0 ]; then + exit 1 +fi + +{% elif default_route == 'force' -%} +# Retrieve current static default routes and remove it from the routing table +vtysh -c "show running-config" | sed -n "/${SED_OPT}/,/!/p" | grep ::/0 | while read route ; do + vtysh -c "conf t" ${VTY_OPT} -c "no ${route} ${VRF_NAME}" +done +{% endif %} + +# Add default route to default or VRF routing table +vtysh -c "conf t" ${VTY_OPT} -c "ipv6 route ::/0 {{ ifname }} ${VRF_NAME}" +logger -t pppd[$DIALER_PID] "added default route via {{ ifname }} ${VRF_NAME}" +{% endif %} + diff --git a/data/templates/pppoe/peer.tmpl b/data/templates/pppoe/peer.tmpl new file mode 100644 index 000000000..e909843a5 --- /dev/null +++ b/data/templates/pppoe/peer.tmpl @@ -0,0 +1,76 @@ +### Autogenerated by interfaces-pppoe.py ### + +{% if description %} +# {{ description }} +{% endif %} + +# Require peer to provide the local IP address if it is not +# specified explicitly in the config file. +noipdefault + +# Don't show the password in logfiles: +hide-password + +# Standard Link Control Protocol (LCP) parameters: +lcp-echo-interval 20 +lcp-echo-failure 3 + +# RFC 2516, paragraph 7 mandates that the following options MUST NOT be +# requested and MUST be rejected if requested by the peer: +# Address-and-Control-Field-Compression (ACFC) +noaccomp + +# Asynchronous-Control-Character-Map (ACCM) +default-asyncmap + +# Override any connect script that may have been set in /etc/ppp/options. +connect /bin/true + +# Don't try to authenticate the remote node +noauth + +# Don't try to proxy ARP for the remote endpoint. User can set proxy +# arp entries up manually if they wish. More importantly, having +# the "proxyarp" parameter set disables the "defaultroute" option. +noproxyarp + +# Unlimited connection attempts +maxfail 0 + +plugin rp-pppoe.so +{{ source_interface }} +persist +ifname {{ ifname }} +ipparam {{ ifname }} +debug +mtu {{ mtu }} +mru {{ mtu }} + +{% if authentication is defined %} +{{ "user " + authentication.user if authentication.user is defined }} +{{ "password " + authentication.password if authentication.password is defined }} +{% endif %} + +{{ "usepeerdns" if no_peer_dns is not defined }} + +{% if ipv6 is defined and ipv6.enable is defined -%} ++ipv6 +ipv6cp-use-ipaddr +{% endif %} + +{% if service_name is defined -%} +rp_pppoe_service "{{ service_name }}" +{% endif %} + +{% if connect_on_demand is defined %} +demand +# See T2249. PPP default route options should only be set when in on-demand +# mode. As soon as we are not in on-demand mode the default-route handling is +# passed to the ip-up.d/ip-down.s scripts which is required for VRF support. +{% if 'auto' in default_route -%} +defaultroute +{% elif 'force' in default_route -%} +defaultroute +replacedefaultroute +{% endif %} +{% endif %} diff --git a/data/templates/router-advert/radvd.conf.tmpl b/data/templates/router-advert/radvd.conf.tmpl new file mode 100644 index 000000000..cebfc54b5 --- /dev/null +++ b/data/templates/router-advert/radvd.conf.tmpl @@ -0,0 +1,47 @@ +### Autogenerated by service_router-advert.py ### + +{% if interface is defined and interface is not none %} +{% for iface in interface %} +interface {{ iface }} { + IgnoreIfMissing on; +{% if interface[iface].default_preference is defined and interface[iface].default_preference is not none %} + AdvDefaultPreference {{ interface[iface].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' }}; +{% endif %} +{% if interface[iface].interval.max is defined and interface[iface].interval.max is not none %} + MaxRtrAdvInterval {{ interface[iface].interval.max }}; +{% endif %} +{% if interface[iface].interval.min is defined and interface[iface].interval.min is not none %} + MinRtrAdvInterval {{ interface[iface].interval.min }}; +{% endif %} +{% if interface[iface].reachable_time is defined and interface[iface].reachable_time is not none %} + AdvReachableTime {{ interface[iface].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 %} + 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 }}; + }; +{% endfor %} +{% if interface[iface].name_server is defined %} + RDNSS {{ interface[iface].name_server | join(" ") }} { + }; +{% endif %} +}; +{% endfor -%} +{% endif %} diff --git a/data/templates/rsyslog/rsyslog.conf b/data/templates/rsyslog/rsyslog.conf new file mode 100644 index 000000000..ab60fc0f0 --- /dev/null +++ b/data/templates/rsyslog/rsyslog.conf @@ -0,0 +1,59 @@ +# /etc/rsyslog.conf Configuration file for rsyslog. +# + +################# +#### MODULES #### +################# + +$ModLoad imuxsock # provides support for local system logging +$ModLoad imklog # provides kernel logging support (previously done by rklogd) +#$ModLoad immark # provides --MARK-- message capability + +$OmitLocalLogging off +$SystemLogSocketName /run/systemd/journal/syslog + +$KLogPath /proc/kmsg + +# provides UDP syslog reception +#$ModLoad imudp +#$UDPServerRun 514 + +# provides TCP syslog reception +#$ModLoad imtcp +#$InputTCPServerRun 514 + +########################### +#### GLOBAL DIRECTIVES #### +########################### + +# +# Use traditional timestamp format. +# To enable high precision timestamps, comment out the following line. +# +$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat + +# Filter duplicated messages +$RepeatedMsgReduction on + +# +# Set the default permissions for all log files. +# +$FileOwner root +$FileGroup adm +$FileCreateMode 0640 +$DirCreateMode 0755 +$Umask 0022 + + +# +# Include all config files in /etc/rsyslog.d/ +# +$IncludeConfig /etc/rsyslog.d/*.conf + +############### +#### RULES #### +############### +# Emergencies are sent to everybody logged in. + +*.emerg :omusrmsg:* + diff --git a/data/templates/salt-minion/minion.tmpl b/data/templates/salt-minion/minion.tmpl new file mode 100644 index 000000000..9369573a4 --- /dev/null +++ b/data/templates/salt-minion/minion.tmpl @@ -0,0 +1,59 @@ +### Autogenerated by salt-minion.py ### + +##### Primary configuration settings ##### +########################################## + +# The hash_type is the hash to use when discovering the hash of a file on +# the master server. The default is sha256, but md5, sha1, sha224, sha384 and +# sha512 are also supported. +# +# WARNING: While md5 and sha1 are also supported, do not use them due to the +# high chance of possible collisions and thus security breach. +# +# Prior to changing this value, the master should be stopped and all Salt +# caches should be cleared. +hash_type: {{ hash }} + +##### Logging settings ##### +########################################## +# The location of the minion log file +# The minion log can be sent to a regular file, local path name, or network +# location. Remote logging works best when configured to use rsyslogd(8) (e.g.: +# ``file:///dev/log``), with rsyslogd(8) configured for network logging. The URI +# format is: <file|udp|tcp>://<host|socketpath>:<port-if-required>/<log-facility> +log_file: file:///dev/log + +# The level of messages to send to the console. +# One of 'garbage', 'trace', 'debug', info', 'warning', 'error', 'critical'. +# +# The following log levels are considered INSECURE and may log sensitive data: +# ['garbage', 'trace', 'debug'] +# +# Default: 'warning' +log_level: {{ log_level }} + +# Set the location of the salt master server, if the master server cannot be +# resolved, then the minion will fail to start. +master: +{% for host in master -%} +- {{ host }} +{% endfor %} + +# The user to run salt +user: {{ user }} + +# The directory to store the pki information in +pki_dir: /config/salt/pki/minion + +# Explicitly declare the id for this minion to use, if left commented the id +# will be the hostname as returned by the python call: socket.getfqdn() +# Since salt uses detached ids it is possible to run multiple minions on the +# same machine but with different ids, this can be useful for salt compute +# clusters. +id: {{ salt_id }} + + +# The number of minutes between mine updates. +mine_interval: {{ interval }} + +verify_master_pubkey_sign: {{ verify_master_pubkey_sign }} diff --git a/data/templates/snmp/etc.snmp.conf.tmpl b/data/templates/snmp/etc.snmp.conf.tmpl new file mode 100644 index 000000000..6e4c6f063 --- /dev/null +++ b/data/templates/snmp/etc.snmp.conf.tmpl @@ -0,0 +1,4 @@ +### Autogenerated by snmp.py ### +{% if trap_source %} +clientaddr {{ trap_source }} +{% endif %} diff --git a/data/templates/snmp/etc.snmpd.conf.tmpl b/data/templates/snmp/etc.snmpd.conf.tmpl new file mode 100644 index 000000000..278506350 --- /dev/null +++ b/data/templates/snmp/etc.snmpd.conf.tmpl @@ -0,0 +1,115 @@ +### Autogenerated by snmp.py ### + +# non configurable defaults +sysObjectID 1.3.6.1.4.1.44641 +sysServices 14 +master agentx +agentXPerms 0777 0777 +pass .1.3.6.1.2.1.31.1.1.1.18 /opt/vyatta/sbin/if-mib-alias +smuxpeer .1.3.6.1.2.1.83 +smuxpeer .1.3.6.1.2.1.157 +smuxsocket localhost + +# linkUp/Down configure the Event MIB tables to monitor +# the ifTable for network interfaces being taken up or down +# for making internal queries to retrieve any necessary information +iquerySecName {{ vyos_user }} + +# Modified from the default linkUpDownNotification +# to include more OIDs and poll more frequently +notificationEvent linkUpTrap linkUp ifIndex ifDescr ifType ifAdminStatus ifOperStatus +notificationEvent linkDownTrap linkDown ifIndex ifDescr ifType ifAdminStatus ifOperStatus +monitor -r 10 -e linkUpTrap "Generate linkUp" ifOperStatus != 2 +monitor -r 10 -e linkDownTrap "Generate linkDown" ifOperStatus == 2 + +######################## +# configurable section # +######################## + +# Default system description is VyOS version +sysDescr VyOS {{ version }} + +{% if description %} +# Description +SysDescr {{ description }} +{% endif %} + +# Listen +agentaddress unix:/run/snmpd.socket{% if listen_on %}{% for li in listen_on %},{{ li }}{% endfor %}{% else %},udp:161{% if ipv6_enabled %},udp6:161{% endif %}{% endif %} + +# SNMP communities +{% for c in communities %} +{% if c.network_v4 %} +{% for network in c.network_v4 %} +{{ c.authorization }}community {{ c.name }} {{ network }} +{% endfor %} +{% elif not c.has_source %} +{{ c.authorization }}community {{ c.name }} +{% endif %} +{% if c.network_v6 %} +{% for network in c.network_v6 %} +{{ c.authorization }}community6 {{ c.name }} {{ network }} +{% endfor %} +{% elif not c.has_source %} +{{ c.authorization }}community6 {{ c.name }} +{% endif %} +{% endfor %} + +{% if contact %} +# system contact information +SysContact {{ contact }} +{% endif %} + +{% if location %} +# system location information +SysLocation {{ location }} +{% endif %} + +{% if smux_peers %} +# additional smux peers +{% for sp in smux_peers %} +smuxpeer {{ sp }} +{% endfor %} +{% endif %} + +{% if trap_targets %} +# if there is a problem - tell someone! +{% for trap in trap_targets %} +trap2sink {{ trap.target }}{{ ":" + trap.port if trap.port is defined }} {{ trap.community }} +{% endfor %} +{% endif %} + +{% if v3_enabled %} +# +# SNMPv3 stuff goes here +# +# views +{% for view in v3_views %} +{% for oid in view.oids %} +view {{ view.name }} included .{{ oid.oid }} +{% endfor %} +{% endfor %} + +# access +# context sec.model sec.level match read write notif +{% for group in v3_groups %} +access {{ group.name }} "" usm {{ group.seclevel }} exact {{ group.view }} {% if group.mode == 'ro' %}none{% else %}{{ group.view }}{% endif %} none +{% endfor %} + +# trap-target +{% for t in v3_traps %} +trapsess -v 3 {{ '-Ci' if t.type == 'inform' }} -e {{ v3_engineid }} -u {{ t.secName }} -l {{ t.secLevel }} -a {{ t.authProtocol }} {% if t.authPassword %}-A {{ t.authPassword }}{% elif t.authMasterKey %}-3m {{ t.authMasterKey }}{% endif %} -x {{ t.privProtocol }} {% if t.privPassword %}-X {{ t.privPassword }}{% elif t.privMasterKey %}-3M {{ t.privMasterKey }}{% endif %} {{ t.ipProto }}:{{ t.ipAddr }}:{{ t.ipPort }} +{% endfor %} + +# group +{% for u in v3_users %} +group {{ u.group }} usm {{ u.name }} +{% endfor %} +{% endif %} + +{% if script_ext %} +# extension scripts +{% for ext in script_ext|sort(attribute='name') %} +extend {{ ext.name }} {{ ext.script }} +{% endfor %} +{% endif %} diff --git a/data/templates/snmp/override.conf.tmpl b/data/templates/snmp/override.conf.tmpl new file mode 100644 index 000000000..e6302a9e1 --- /dev/null +++ b/data/templates/snmp/override.conf.tmpl @@ -0,0 +1,13 @@ +{% set vrf_command = '/sbin/ip vrf exec ' + vrf + ' ' if vrf is defined else '' %} +[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" +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 +Restart=on-failure +RestartSec=10 + diff --git a/data/templates/snmp/usr.snmpd.conf.tmpl b/data/templates/snmp/usr.snmpd.conf.tmpl new file mode 100644 index 000000000..9c0337fa8 --- /dev/null +++ b/data/templates/snmp/usr.snmpd.conf.tmpl @@ -0,0 +1,6 @@ +### Autogenerated by snmp.py ### +{%- for u in v3_users %} +{{ u.mode }}user {{ u.name }} +{%- endfor %} + +rwuser {{ vyos_user }} diff --git a/data/templates/snmp/var.snmpd.conf.tmpl b/data/templates/snmp/var.snmpd.conf.tmpl new file mode 100644 index 000000000..6cbc687ef --- /dev/null +++ b/data/templates/snmp/var.snmpd.conf.tmpl @@ -0,0 +1,14 @@ +### Autogenerated by snmp.py ### +# user +{%- for u in v3_users %} +{%- if u.authOID == 'none' %} +createUser {{ u.name }} +{%- else %} +usmUser 1 3 0x{{ v3_engineid }} "{{ u.name }}" "{{ u.name }}" NULL {{ u.authOID }} 0x{{ u.authMasterKey }} {{ u.privOID }} 0x{{ u.privMasterKey }} 0x +{%- endif %} +{%- endfor %} + +createUser {{ vyos_user }} MD5 "{{ vyos_user_pass }}" DES +{%- if v3_engineid %} +oldEngineID 0x{{ v3_engineid }} +{%- endif %} diff --git a/data/templates/ssh/override.conf.tmpl b/data/templates/ssh/override.conf.tmpl new file mode 100644 index 000000000..843aa927b --- /dev/null +++ b/data/templates/ssh/override.conf.tmpl @@ -0,0 +1,11 @@ +{% set vrf_command = '/sbin/ip vrf exec ' + vrf + ' ' if vrf is defined else '' %} +[Unit] +StartLimitIntervalSec=0 +After=vyos-router.service +ConditionPathExists={{config_file}} + +[Service] +ExecStart= +ExecStart={{vrf_command}}/usr/sbin/sshd -f {{config_file}} -D $SSHD_OPTS +RestartSec=10 + diff --git a/data/templates/ssh/sshd_config.tmpl b/data/templates/ssh/sshd_config.tmpl new file mode 100644 index 000000000..4fde24255 --- /dev/null +++ b/data/templates/ssh/sshd_config.tmpl @@ -0,0 +1,114 @@ +### Autogenerated by ssh.py ### + +# https://linux.die.net/man/5/sshd_config + +# +# Non-configurable defaults +# +Protocol 2 +HostKey /etc/ssh/ssh_host_rsa_key +HostKey /etc/ssh/ssh_host_dsa_key +HostKey /etc/ssh/ssh_host_ecdsa_key +HostKey /etc/ssh/ssh_host_ed25519_key +SyslogFacility AUTH +LoginGraceTime 120 +StrictModes yes +PubkeyAuthentication yes +IgnoreRhosts yes +HostbasedAuthentication no +PermitEmptyPasswords no +ChallengeResponseAuthentication no +X11Forwarding yes +X11DisplayOffset 10 +PrintMotd no +PrintLastLog yes +TCPKeepAlive yes +Banner /etc/issue.net +Subsystem sftp /usr/lib/openssh/sftp-server +UsePAM yes +PermitRootLogin no + +# +# User configurable section +# + +# Look up remote host name and check that the resolved host name for the remote IP +# address maps back to the very same IP address. +UseDNS {{ "no" if disable_host_validation is defined else "yes" }} + +# Specifies the port number that sshd(8) listens on +{% if port is string %} +Port {{ port }} +{% else %} +{% for value in port %} +Port {{ value }} +{% endfor %} +{% endif %} + +# Gives the verbosity level that is used when logging messages from sshd +LogLevel {{ loglevel | upper }} + +# Specifies whether password authentication is allowed +PasswordAuthentication {{ "no" if disable_password_authentication is defined else "yes" }} + +{% if listen_address %} +# Specifies the local addresses sshd should listen on +{% if listen_address is string %} +ListenAddress {{ listen_address }} +{% else %} +{% for address in listen_address %} +ListenAddress {{ address }} +{% endfor %} +{% endif %} +{% endif %} + +{% if ciphers %} +# Specifies the ciphers allowed for protocol version 2 +{% set value = ciphers if ciphers is string else ciphers | join(',') %} +Ciphers {{ value }} +{% endif %} + +{% if mac %} +# Specifies the available MAC (message authentication code) algorithms +{% set value = mac if mac is string else mac | join(',') %} +MACs {{ value }} +{% endif %} + +{% if key_exchange %} +# Specifies the available Key Exchange algorithms +{% set value = key_exchange if key_exchange is string else key_exchange | join(',') %} +KexAlgorithms {{ value }} +{% endif %} + +{% if access_control is defined %} +{% if access_control.allow is defined %} +{% if access_control.allow.user is defined %} +# If specified, login is allowed only for user names that match +{% set value = access_control.allow.user if access_control.allow.user is string else access_control.allow.user | join(' ') %} +AllowUsers {{ value }} +{% endif %} +{% if access_control.allow.group is defined %} +# If specified, login is allowed only for users whose primary group or supplementary group list matches +{% set value = access_control.allow.group if access_control.allow.group is string else access_control.allow.group | join(' ') %} +AllowGroups {{ value }} +{% endif %} +{% endif %} +{% if access_control.deny is defined %} +{% if access_control.deny.user is defined %} +# Login is disallowed for user names that match +{% set value = access_control.deny.user if access_control.deny.user is string else access_control.deny.user | join(' ') %} +DenyUsers {{ value }} +{% endif %} +{% if access_control.deny.group is defined %} +# Login is disallowed for users whose primary group or supplementary group list matches +{% set value = access_control.deny.group if access_control.deny.group is string else access_control.deny.group | join(' ') %} +DenyGroups {{ value }} +{% endif %} +{% endif %} +{% endif %} + +{% if client_keepalive_interval %} +# Sets a timeout interval in seconds after which if no data has been received from the client, +# sshd(8) will send a message through the encrypted channel to request a response from the client +ClientAliveInterval {{ client_keepalive_interval }} +{% endif %} diff --git a/data/templates/syslog/logrotate.tmpl b/data/templates/syslog/logrotate.tmpl new file mode 100644 index 000000000..f758265e4 --- /dev/null +++ b/data/templates/syslog/logrotate.tmpl @@ -0,0 +1,12 @@ +{% for file in files %} +{{files[file]['log-file']}} { + missingok + notifempty + create + rotate {{files[file]['max-files']}} + size={{files[file]['max-size']//1024}}k + postrotate + invoke-rc.d rsyslog rotate > /dev/null + endscript +} +{% endfor %} diff --git a/data/templates/syslog/rsyslog.conf.tmpl b/data/templates/syslog/rsyslog.conf.tmpl new file mode 100644 index 000000000..bc3f7667b --- /dev/null +++ b/data/templates/syslog/rsyslog.conf.tmpl @@ -0,0 +1,44 @@ +## generated by syslog.py ## +## file based logging +{% if files['global']['marker'] -%} +$ModLoad immark +{% if files['global']['marker-interval'] %} +$MarkMessagePeriod {{files['global']['marker-interval']}} +{% endif %} +{% endif -%} +{% if files['global']['preserver_fqdn'] -%} +$PreserveFQDN on +{% endif -%} +{% for file in files %} +$outchannel {{file}},{{files[file]['log-file']}},{{files[file]['max-size']}},{{files[file]['action-on-max-size']}} +{{files[file]['selectors']}} :omfile:${{file}} +{% endfor %} +{% if console %} +## console logging +{% for con in console %} +{{console[con]['selectors']}} /dev/console +{% endfor %} +{% endif %} +{% if hosts %} +## remote logging +{% for host in hosts %} +{% if hosts[host]['proto'] == 'tcp' %} +{% if hosts[host]['port'] %} +{{hosts[host]['selectors']}} @@{{host}}:{{hosts[host]['port']}} +{% else %} +{{hosts[host]['selectors']}} @@{{host}} +{% endif %} +{% else %} +{% if hosts[host]['port'] %} +{{hosts[host]['selectors']}} @{{host}}:{{hosts[host]['port']}} +{% else %} +{{hosts[host]['selectors']}} @{{host}} +{% endif %} +{% endif %} +{% endfor %} +{% endif %} +{% if user %} +{% for u in user %} +{{user[u]['selectors']}} :omusrmsg:{{u}} +{% endfor %} +{% endif %} diff --git a/data/templates/system-login/pam_radius_auth.conf.tmpl b/data/templates/system-login/pam_radius_auth.conf.tmpl new file mode 100644 index 000000000..ec2d6df95 --- /dev/null +++ b/data/templates/system-login/pam_radius_auth.conf.tmpl @@ -0,0 +1,16 @@ +# Automatically generated by system-login.py +# RADIUS configuration file +{% if radius_server %} +# server[:port] shared_secret timeout source_ip +{% for s in radius_server|sort(attribute='priority') if not s.disabled %} +{% set addr_port = s.address + ":" + s.port %} +{{ "%-22s" | format(addr_port) }} {{ "%-25s" | format(s.key) }} {{ "%-10s" | format(s.timeout) }} {{ radius_source_address if radius_source_address }} +{% endfor %} + +priv-lvl 15 +mapped_priv_user radius_priv_user + +{% if radius_vrf %} +vrf-name {{ radius_vrf }} +{% endif %} +{% endif %} diff --git a/data/templates/system/curlrc.tmpl b/data/templates/system/curlrc.tmpl new file mode 100644 index 000000000..3e5ce801c --- /dev/null +++ b/data/templates/system/curlrc.tmpl @@ -0,0 +1,8 @@ +{% if http_client is defined %} +{% if http_client.source_interface is defined %} +--interface "{{ http_client.source_interface }}" +{% endif %} +{% if http_client.source_address is defined %} +--interface "{{ http_client.source_address }}" +{% endif %} +{% endif %} diff --git a/data/templates/system/ssh_config.tmpl b/data/templates/system/ssh_config.tmpl new file mode 100644 index 000000000..509bd5479 --- /dev/null +++ b/data/templates/system/ssh_config.tmpl @@ -0,0 +1,3 @@ +{% if ssh_client is defined and ssh_client.source_address is defined and ssh_client.source_address is not none %}
+BindAddress {{ ssh_client.source_address }}
+{% endif %}
diff --git a/data/templates/tftp-server/default.tmpl b/data/templates/tftp-server/default.tmpl new file mode 100644 index 000000000..18fee35d1 --- /dev/null +++ b/data/templates/tftp-server/default.tmpl @@ -0,0 +1,2 @@ +### Autogenerated by tftp_server.py ### +DAEMON_ARGS="--listen --user tftp --address {% for a in listen-%}{{ a }}{% endfor %}{% if allow_upload %} --create --umask 000{% endif %} --secure {{ directory }}" diff --git a/data/templates/vrf/vrf.conf.tmpl b/data/templates/vrf/vrf.conf.tmpl new file mode 100644 index 000000000..761b0bb6f --- /dev/null +++ b/data/templates/vrf/vrf.conf.tmpl @@ -0,0 +1,8 @@ +### Autogenerated by vrf.py ### +# +# Routing table ID to name mapping reference + +# id vrf name comment +{% for vrf in vrf_add -%} +{{ "%-10s" | format(vrf.table) }} {{ "%-16s" | format(vrf.name) }} # {{ vrf.description }} +{% endfor -%} diff --git a/data/templates/vrrp/daemon.tmpl b/data/templates/vrrp/daemon.tmpl new file mode 100644 index 000000000..c9dbea72d --- /dev/null +++ b/data/templates/vrrp/daemon.tmpl @@ -0,0 +1,5 @@ +# Autogenerated by VyOS +# Options to pass to keepalived + +# DAEMON_ARGS are appended to the keepalived command-line +DAEMON_ARGS="--snmp" diff --git a/data/templates/vrrp/keepalived.conf.tmpl b/data/templates/vrrp/keepalived.conf.tmpl new file mode 100644 index 000000000..08b821f70 --- /dev/null +++ b/data/templates/vrrp/keepalived.conf.tmpl @@ -0,0 +1,97 @@ +# Autogenerated by VyOS +# Do not edit this file, all your changes will be lost +# on next commit or reboot + +global_defs { + dynamic_interfaces + script_user root + notify_fifo /run/keepalived_notify_fifo + notify_fifo_script /usr/libexec/vyos/system/keepalived-fifo.py +} + +{% for group in groups -%} + +{% if group.health_check_script -%} +vrrp_script healthcheck_{{ group.name }} { + script "{{ group.health_check_script }}" + interval {{ group.health_check_interval }} + fall {{ group.health_check_count }} + rise 1 + +} +{% endif %} + +vrrp_instance {{ group.name }} { + {% if group.description -%} + # {{ group.description }} + {% endif -%} + + state BACKUP + interface {{ group.interface }} + virtual_router_id {{ group.vrid }} + priority {{ group.priority }} + advert_int {{ group.advertise_interval }} + + {% if group.preempt -%} + preempt_delay {{ group.preempt_delay }} + {% else -%} + nopreempt + {% endif -%} + + {% if group.peer_address -%} + unicast_peer { {{ group.peer_address }} } + {% endif -%} + + {% if group.hello_source -%} + {%- if group.peer_address -%} + unicast_src_ip {{ group.hello_source }} + {%- else -%} + mcast_src_ip {{ group.hello_source }} + {%- endif %} + {% endif -%} + + {% if group.use_vmac and group.peer_address -%} + use_vmac {{group.interface}}v{{group.vrid}} + vmac_xmit_base + {% elif group.use_vmac -%} + use_vmac {{group.interface}}v{{group.vrid}} + {% endif -%} + + {% if group.auth_password -%} + authentication { + auth_pass "{{ group.auth_password }}" + auth_type {{ group.auth_type }} + } + {% endif -%} + + virtual_ipaddress { + {% for addr in group.virtual_addresses -%} + {{ addr }} + {% endfor -%} + } + + {% if group.health_check_script -%} + track_script { + healthcheck_{{ group.name }} + } + {% endif -%} +} + +{% endfor -%} + +{% for sync_group in sync_groups -%} +vrrp_sync_group {{ sync_group.name }} { + group { + {% for member in sync_group.members -%} + {{ member }} + {% endfor -%} + } + + {% if sync_group.conntrack_sync -%} + notify_master "/opt/vyatta/sbin/vyatta-vrrp-conntracksync.sh master {{ sync_group.name }}" + notify_backup "/opt/vyatta/sbin/vyatta-vrrp-conntracksync.sh backup {{ sync_group.name }}" + notify_fault "/opt/vyatta/sbin/vyatta-vrrp-conntracksync.sh fault {{ sync_group.name }}" + {% endif -%} +} + +{% endfor -%} diff --git a/data/templates/vyos-hostsd/hosts.tmpl b/data/templates/vyos-hostsd/hosts.tmpl new file mode 100644 index 000000000..566f9a5dd --- /dev/null +++ b/data/templates/vyos-hostsd/hosts.tmpl @@ -0,0 +1,26 @@ +### Autogenerated by VyOS ### +### Do not edit, your changes will get overwritten ### + +# Local host +127.0.0.1 localhost +127.0.1.1 {{ host_name }}{% if domain_name %}.{{ domain_name }} {{ host_name }}{% endif %} + +# The following lines are desirable for IPv6 capable hosts +::1 localhost ip6-localhost ip6-loopback +fe00::0 ip6-localnet +ff00::0 ip6-mcastprefix +ff02::1 ip6-allnodes +ff02::2 ip6-allrouters + +{% if hosts -%} +# From 'system static-host-mapping' and DHCP server +{%- for tag, taghosts in hosts.items() %} +# {{ tag }} +{%- for host, hostprops in taghosts.items() %} +{%- if hostprops['address'] %} +{{ hostprops['address'] }} {{ host }}{% for a in hostprops['aliases'] %} {{ a }}{% endfor %} +{%- endif %} +{%- endfor %} +{%- endfor %} +{%- endif %} + diff --git a/data/templates/vyos-hostsd/resolv.conf.tmpl b/data/templates/vyos-hostsd/resolv.conf.tmpl new file mode 100644 index 000000000..b920b2e5f --- /dev/null +++ b/data/templates/vyos-hostsd/resolv.conf.tmpl @@ -0,0 +1,26 @@ +### Autogenerated by VyOS ### +### Do not edit, your changes will get overwritten ### + +{#- the code below ensures the order of nameservers is determined first by #} +{# the order of tags, then by the order of nameservers within that tag #} + +{%- for tag in name_server_tags_system %} +{%- if tag in name_servers %} +# {{ tag }} +{%- for ns in name_servers[tag] %} +nameserver {{ ns }} +{%- endfor %} +{%- endif %} +{%- endfor %} + +{%- if domain_name %} +domain {{ domain_name }} +{%- endif %} + +{% for tag in name_server_tags_system %} +{%- if tag in search_domains %} +# {{ tag }} +search {{ search_domains[tag]|join(' ') }} +{%- endif %} +{%- endfor %} + diff --git a/data/templates/wifi/cfg80211.conf.tmpl b/data/templates/wifi/cfg80211.conf.tmpl new file mode 100644 index 000000000..91df57aab --- /dev/null +++ b/data/templates/wifi/cfg80211.conf.tmpl @@ -0,0 +1 @@ +{{ 'options cfg80211 ieee80211_regdom=' + regdom if regdom is defined }} diff --git a/data/templates/wifi/crda.tmpl b/data/templates/wifi/crda.tmpl new file mode 100644 index 000000000..6cd125e37 --- /dev/null +++ b/data/templates/wifi/crda.tmpl @@ -0,0 +1 @@ +{{ 'REGDOMAIN=' + regdom if regdom is defined }} diff --git a/data/templates/wifi/hostapd.conf.tmpl b/data/templates/wifi/hostapd.conf.tmpl new file mode 100644 index 000000000..765668c57 --- /dev/null +++ b/data/templates/wifi/hostapd.conf.tmpl @@ -0,0 +1,687 @@ +### Autogenerated by interfaces-wireless.py ### +{% if description %} +# Description: {{ description }} +# User-friendly description of device; up to 32 octets encoded in UTF-8 +device_name={{ description | truncate(32, True) }} +{% endif %} + +# AP netdevice name (without 'ap' postfix, i.e., wlan0 uses wlan0ap for +# management frames with the Host AP driver); wlan0 with many nl80211 drivers +# Note: This attribute can be overridden by the values supplied with the '-i' +# command line parameter. +interface={{ ifname }} + +# Driver interface type (hostap/wired/none/nl80211/bsd); +# default: hostap). nl80211 is used with all Linux mac80211 drivers. +# Use driver=none if building hostapd as a standalone RADIUS server that does +# not control any wireless/wired driver. +driver=nl80211 + +# Levels (minimum value for logged events): +# 0 = verbose debugging +# 1 = debugging +# 2 = informational messages +# 3 = notification +# 4 = warning +logger_syslog=-1 +logger_syslog_level=0 +logger_stdout=-1 +logger_stdout_level=0 + +{% if country_code %} +# Country code (ISO/IEC 3166-1). Used to set regulatory domain. +# Set as needed to indicate country in which device is operating. +# This can limit available channels and transmit power. +country_code={{ country_code }} + +# Enable IEEE 802.11d. This advertises the country_code and the set of allowed +# channels and transmit power levels based on the regulatory limits. The +# country_code setting must be configured with the correct country for +# IEEE 802.11d functions. +ieee80211d=1 +{% endif %} + +{% if ssid %} +# SSID to be used in IEEE 802.11 management frames +ssid={{ ssid }} +{% endif %} + +{% if channel %} +# Channel number (IEEE 802.11) +# (default: 0, i.e., not set) +# Please note that some drivers do not use this value from hostapd and the +# channel will need to be configured separately with iwconfig. +# +# If CONFIG_ACS build option is enabled, the channel can be selected +# automatically at run time by setting channel=acs_survey or channel=0, both of +# which will enable the ACS survey based algorithm. +channel={{ channel }} +{% endif %} + +{% if mode %} +# Operation mode (a = IEEE 802.11a (5 GHz), b = IEEE 802.11b (2.4 GHz), +# g = IEEE 802.11g (2.4 GHz), ad = IEEE 802.11ad (60 GHz); a/g options are used +# with IEEE 802.11n (HT), too, to specify band). For IEEE 802.11ac (VHT), this +# needs to be set to hw_mode=a. For IEEE 802.11ax (HE) on 6 GHz this needs +# to be set to hw_mode=a. When using ACS (see channel parameter), a +# special value "any" can be used to indicate that any support band can be used. +# This special case is currently supported only with drivers with which +# offloaded ACS is used. +{% if 'n' in mode %} +hw_mode=g +{% elif 'ac' in mode %} +hw_mode=a +ieee80211h=1 +ieee80211ac=1 +{% else %} +hw_mode={{ mode }} +{% endif %} +{% endif %} + +# ieee80211w: Whether management frame protection (MFP) is enabled +# 0 = disabled (default) +# 1 = optional +# 2 = required +{% if 'disabled' in mgmt_frame_protection %} +ieee80211w=0 +{% elif 'optional' in mgmt_frame_protection %} +ieee80211w=1 +{% elif 'required' in mgmt_frame_protection %} +ieee80211w=2 +{% endif %} + +{% if capabilities is defined and capabilities.ht is defined %} +# ht_capab: HT capabilities (list of flags) +# LDPC coding capability: [LDPC] = supported +# Supported channel width set: [HT40-] = both 20 MHz and 40 MHz with secondary +# channel below the primary channel; [HT40+] = both 20 MHz and 40 MHz +# with secondary channel above the primary channel +# (20 MHz only if neither is set) +# Note: There are limits on which channels can be used with HT40- and +# HT40+. Following table shows the channels that may be available for +# HT40- and HT40+ use per IEEE 802.11n Annex J: +# freq HT40- HT40+ +# 2.4 GHz 5-13 1-7 (1-9 in Europe/Japan) +# 5 GHz 40,48,56,64 36,44,52,60 +# (depending on the location, not all of these channels may be available +# for use) +# Please note that 40 MHz channels may switch their primary and secondary +# channels if needed or creation of 40 MHz channel maybe rejected based +# on overlapping BSSes. These changes are done automatically when hostapd +# is setting up the 40 MHz channel. +# Spatial Multiplexing (SM) Power Save: [SMPS-STATIC] or [SMPS-DYNAMIC] +# (SMPS disabled if neither is set) +# HT-greenfield: [GF] (disabled if not set) +# Short GI for 20 MHz: [SHORT-GI-20] (disabled if not set) +# Short GI for 40 MHz: [SHORT-GI-40] (disabled if not set) +# Tx STBC: [TX-STBC] (disabled if not set) +# Rx STBC: [RX-STBC1] (one spatial stream), [RX-STBC12] (one or two spatial +# streams), or [RX-STBC123] (one, two, or three spatial streams); Rx STBC +# disabled if none of these set +# HT-delayed Block Ack: [DELAYED-BA] (disabled if not set) +# Maximum A-MSDU length: [MAX-AMSDU-7935] for 7935 octets (3839 octets if not +# set) +# DSSS/CCK Mode in 40 MHz: [DSSS_CCK-40] = allowed (not allowed if not set) +# 40 MHz intolerant [40-INTOLERANT] (not advertised if not set) +# L-SIG TXOP protection support: [LSIG-TXOP-PROT] (disabled if not set) +{% set output = '' %} +{% set output = output + '[40-INTOLERANT]' if capabilities.ht.fourtymhz_incapable is defined else '' %} +{% set output = output + '[DELAYED-BA]' if capabilities.ht.delayed_block_ack is defined else '' %} +{% set output = output + '[DSSS_CCK-40]' if capabilities.ht.dsss_cck_40 is defined else '' %} +{% set output = output + '[GF]' if capabilities.ht.greenfield is defined else '' %} +{% set output = output + '[LDPC]' if capabilities.ht.ldpc is defined else '' %} +{% set output = output + '[LSIG-TXOP-PROT]' if capabilities.ht.lsig_protection is defined else '' %} +{% set output = output + '[TX-STBC]' if capabilities.ht.stbc.tx is defined else '' %} +{% set output = output + '[RX-STBC-' + capabilities.ht.stbc.rx | upper + ']' if capabilities.ht.stbc.tx is defined else '' %} +{% set output = output + '[MAX-AMSDU-' + capabilities.ht.max_amsdu + ']' if capabilities.ht.max_amsdu is defined else '' %} +{% set output = output + '[SMPS-' + capabilities.ht.smps | upper + ']' if capabilities.ht.smps is defined else '' %} + +{% if capabilities.ht.channel_set_width is defined %} +{% for csw in capabilities.ht.channel_set_width %} +{% set output = output + '[' + csw | upper + ']' %} +{% endfor %} +{% endif %} + +{% if capabilities.ht.short_gi is defined %} +{% for short_gi in capabilities.ht.short_gi %} +{% set output = output + '[SHORT-GI-' + short_gi | upper + ']' %} +{% endfor %} +{% endif %} + +ht_capab={{ output }} + +{% if capabilities.ht.auto_powersave is defined %} +# WMM-PS Unscheduled Automatic Power Save Delivery [U-APSD] +# Enable this flag if U-APSD supported outside hostapd (eg., Firmware/driver) +uapsd_advertisement_enabled=1 +{% endif %} + +{% endif %} + +# Required for full HT and VHT functionality +wme_enabled=1 + + +{% if capabilities is defined and capabilities.require_ht is defined %} +# Require stations to support HT PHY (reject association if they do not) +require_ht=1 +{% endif %} + +{% if capabilities is defined and capabilities.vht is defined %} +# vht_capab: VHT capabilities (list of flags) +# +# vht_max_mpdu_len: [MAX-MPDU-7991] [MAX-MPDU-11454] +# Indicates maximum MPDU length +# 0 = 3895 octets (default) +# 1 = 7991 octets +# 2 = 11454 octets +# 3 = reserved +# +# supported_chan_width: [VHT160] [VHT160-80PLUS80] +# Indicates supported Channel widths +# 0 = 160 MHz & 80+80 channel widths are not supported (default) +# 1 = 160 MHz channel width is supported +# 2 = 160 MHz & 80+80 channel widths are supported +# 3 = reserved +# +# Rx LDPC coding capability: [RXLDPC] +# Indicates support for receiving LDPC coded pkts +# 0 = Not supported (default) +# 1 = Supported +# +# Short GI for 80 MHz: [SHORT-GI-80] +# Indicates short GI support for reception of packets transmitted with TXVECTOR +# params format equal to VHT and CBW = 80Mhz +# 0 = Not supported (default) +# 1 = Supported +# +# Short GI for 160 MHz: [SHORT-GI-160] +# Indicates short GI support for reception of packets transmitted with TXVECTOR +# params format equal to VHT and CBW = 160Mhz +# 0 = Not supported (default) +# 1 = Supported +# +# Tx STBC: [TX-STBC-2BY1] +# Indicates support for the transmission of at least 2x1 STBC +# 0 = Not supported (default) +# 1 = Supported +# +# Rx STBC: [RX-STBC-1] [RX-STBC-12] [RX-STBC-123] [RX-STBC-1234] +# Indicates support for the reception of PPDUs using STBC +# 0 = Not supported (default) +# 1 = support of one spatial stream +# 2 = support of one and two spatial streams +# 3 = support of one, two and three spatial streams +# 4 = support of one, two, three and four spatial streams +# 5,6,7 = reserved +# +# SU Beamformer Capable: [SU-BEAMFORMER] +# Indicates support for operation as a single user beamformer +# 0 = Not supported (default) +# 1 = Supported +# +# SU Beamformee Capable: [SU-BEAMFORMEE] +# Indicates support for operation as a single user beamformee +# 0 = Not supported (default) +# 1 = Supported +# +# Compressed Steering Number of Beamformer Antennas Supported: +# [BF-ANTENNA-2] [BF-ANTENNA-3] [BF-ANTENNA-4] +# Beamformee's capability indicating the maximum number of beamformer +# antennas the beamformee can support when sending compressed beamforming +# feedback +# If SU beamformer capable, set to maximum value minus 1 +# else reserved (default) +# +# Number of Sounding Dimensions: +# [SOUNDING-DIMENSION-2] [SOUNDING-DIMENSION-3] [SOUNDING-DIMENSION-4] +# Beamformer's capability indicating the maximum value of the NUM_STS parameter +# in the TXVECTOR of a VHT NDP +# If SU beamformer capable, set to maximum value minus 1 +# else reserved (default) +# +# MU Beamformer Capable: [MU-BEAMFORMER] +# Indicates support for operation as an MU beamformer +# 0 = Not supported or sent by Non-AP STA (default) +# 1 = Supported +# +# VHT TXOP PS: [VHT-TXOP-PS] +# Indicates whether or not the AP supports VHT TXOP Power Save Mode +# or whether or not the STA is in VHT TXOP Power Save mode +# 0 = VHT AP doesn't support VHT TXOP PS mode (OR) VHT STA not in VHT TXOP PS +# mode +# 1 = VHT AP supports VHT TXOP PS mode (OR) VHT STA is in VHT TXOP power save +# mode +# +# +HTC-VHT Capable: [HTC-VHT] +# Indicates whether or not the STA supports receiving a VHT variant HT Control +# field. +# 0 = Not supported (default) +# 1 = supported +# +# Maximum A-MPDU Length Exponent: [MAX-A-MPDU-LEN-EXP0]..[MAX-A-MPDU-LEN-EXP7] +# Indicates the maximum length of A-MPDU pre-EOF padding that the STA can recv +# This field is an integer in the range of 0 to 7. +# The length defined by this field is equal to +# 2 pow(13 + Maximum A-MPDU Length Exponent) -1 octets +# +# VHT Link Adaptation Capable: [VHT-LINK-ADAPT2] [VHT-LINK-ADAPT3] +# Indicates whether or not the STA supports link adaptation using VHT variant +# HT Control field +# If +HTC-VHTcapable is 1 +# 0 = (no feedback) if the STA does not provide VHT MFB (default) +# 1 = reserved +# 2 = (Unsolicited) if the STA provides only unsolicited VHT MFB +# 3 = (Both) if the STA can provide VHT MFB in response to VHT MRQ and if the +# STA provides unsolicited VHT MFB +# Reserved if +HTC-VHTcapable is 0 +# +# Rx Antenna Pattern Consistency: [RX-ANTENNA-PATTERN] +# Indicates the possibility of Rx antenna pattern change +# 0 = Rx antenna pattern might change during the lifetime of an association +# 1 = Rx antenna pattern does not change during the lifetime of an association +# +# Tx Antenna Pattern Consistency: [TX-ANTENNA-PATTERN] +# Indicates the possibility of Tx antenna pattern change +# 0 = Tx antenna pattern might change during the lifetime of an association +# 1 = Tx antenna pattern does not change during the lifetime of an + +{% if capabilities.vht.center_channel_freq.freq_1 is defined %} +# center freq = 5 GHz + (5 * index) +# So index 42 gives center freq 5.210 GHz +# which is channel 42 in 5G band +vht_oper_centr_freq_seg0_idx={{ capabilities.vht.center_channel_freq.freq_1 }} +{% endif %} + +{% if capabilities.vht.center_channel_freq.freq_2 is defined %} +# center freq = 5 GHz + (5 * index) +# So index 159 gives center freq 5.795 GHz +# which is channel 159 in 5G band +vht_oper_centr_freq_seg1_idx={{ capabilities.vht.center_channel_freq.freq_2 }} +{% endif %} + +{% if capabilities.vht.channel_set_width is defined %} +vht_oper_chwidth={{ capabilities.vht.channel_set_width }} +{% endif %} + +{% set output = '' %} +{% set output = output + '[TX-STBC-2BY1]' if capabilities.vht.stbc.tx is defined else '' %} +{% set output = output + '[RXLDPC]' if capabilities.vht.ldpc is defined else '' %} +{% set output = output + '[VHT-TXOP-PS]' if capabilities.vht.tx_powersave is defined else '' %} +{% set output = output + '[HTC-VHT]' if capabilities.vht.vht_cf is defined else '' %} +{% set output = output + '[RX-ANTENNA-PATTERN]' if capabilities.vht.antenna_pattern_fixed is defined else '' %} +{% set output = output + '[TX-ANTENNA-PATTERN]' if capabilities.vht.antenna_pattern_fixed is defined else '' %} + +{% set output = output + '[RX-STBC-' + capabilities.vht.stbc.rx + ']' if capabilities.vht.stbc.rx is defined else '' %} +{% set output = output + '[MAX-MPDU-' + capabilities.vht.max_mpdu + ']' if capabilities.vht.max_mpdu is defined else '' %} +{% set output = output + '[MAX-A-MPDU-LEN-EXP-' + capabilities.vht.max_mpdu_exp + ']' if capabilities.vht.max_mpdu_exp is defined else '' %} +{% set output = output + '[MAX-A-MPDU-LEN-EXP-' + capabilities.vht.max_mpdu_exp + ']' if capabilities.vht.max_mpdu_exp is defined else '' %} + +{% set output = output + '[VHT160]' if capabilities.vht.max_mpdu_exp is defined and capabilities.vht.max_mpdu_exp == '2' else '' %} +{% set output = output + '[VHT160-80PLUS80]' if capabilities.vht.max_mpdu_exp is defined and capabilities.vht.max_mpdu_exp == '3' else '' %} +{% set output = output + '[VHT-LINK-ADAPT2]' if capabilities.vht.link_adaptation is defined and capabilities.vht.link_adaptation == 'unsolicited' else '' %} +{% set output = output + '[VHT-LINK-ADAPT3]' if capabilities.vht.link_adaptation is defined and capabilities.vht.link_adaptation == 'both' else '' %} + +{% if capabilities.vht.short_gi is defined %} +{% for short_gi in capabilities.vht.short_gi %} +{% set output = output + '[SHORT-GI-' + short_gi | upper + ']' %} +{% endfor %} +{% endif %} + +{% if capabilities.vht.beamform %} +{% for beamform in capabilities.vht.beamform %} +{% set output = output + '[SU-BEAMFORMER]' if beamform == 'single-user-beamformer' else '' %} +{% set output = output + '[SU-BEAMFORMEE]' if beamform == 'single-user-beamformee' else '' %} +{% set output = output + '[MU-BEAMFORMER]' if beamform == 'multi-user-beamformer' else '' %} +{% set output = output + '[MU-BEAMFORMEE]' if beamform == 'multi-user-beamformee' else '' %} +{% endfor %} +{% endif %} + +{% if capabilities.vht.antenna_count is defined and capabilities.vht.antenna_count|int > 1 %} +{% if capabilities.vht.beamform %} +{% if beamform == 'single-user-beamformer' %} +{% if capabilities.vht.antenna_count is defined and capabilities.vht.antenna_count|int > 1 and capabilities.vht.antenna_count|int < 6 %} +{% set output = output + '[BF-ANTENNA-' + capabilities.vht.antenna_count|int -1 + ']' %} +{% set output = output + '[SOUNDING-DIMENSION-' + capabilities.vht.antenna_count|int -1 + ']' %} +{% endif %} +{% endif %} +{% if capabilities.vht.antenna_count is defined and capabilities.vht.antenna_count|int > 1 and capabilities.vht.antenna_count|int < 5 %} +{% set output = output + '[BF-ANTENNA-' + capabilities.vht.antenna_count + ']' %} +{% set output = output + '[SOUNDING-DIMENSION-' + capabilities.vht.antenna_count+ ']' %} +{% endif %} +{% endif %} +{% endif %} + +vht_capab={{ output }} +{% endif %} + +# ieee80211n: Whether IEEE 802.11n (HT) is enabled +# 0 = disabled (default) +# 1 = enabled +# Note: You will also need to enable WMM for full HT functionality. +# Note: hw_mode=g (2.4 GHz) and hw_mode=a (5 GHz) is used to specify the band. +{% if capabilities is defined and capabilities.require_vht is defined %} +ieee80211n=0 +# Require stations to support VHT PHY (reject association if they do not) +require_vht=1 +{% else %} +{% if 'n' in mode or 'ac' in mode %} +ieee80211n=1 +{% else %} +ieee80211n=0 +{% endif %} +{% endif %} + +{% if disable_broadcast_ssid is defined %} +# Send empty SSID in beacons and ignore probe request frames that do not +# specify full SSID, i.e., require stations to know SSID. +# default: disabled (0) +# 1 = send empty (length=0) SSID in beacon and ignore probe request for +# broadcast SSID +# 2 = clear SSID (ASCII 0), but keep the original length (this may be required +# with some clients that do not support empty SSID) and ignore probe +# requests for broadcast SSID +ignore_broadcast_ssid=1 +{% endif %} + +# Station MAC address -based authentication +# Please note that this kind of access control requires a driver that uses +# hostapd to take care of management frame processing and as such, this can be +# used with driver=hostap or driver=nl80211, but not with driver=atheros. +# 0 = accept unless in deny list +# 1 = deny unless in accept list +# 2 = use external RADIUS server (accept/deny lists are searched first) +macaddr_acl=0 + +{% if max_stations is defined %} +# Maximum number of stations allowed in station table. New stations will be +# rejected after the station table is full. IEEE 802.11 has a limit of 2007 +# different association IDs, so this number should not be larger than that. +# (default: 2007) +max_num_sta={{ max_stations }} +{% endif %} + +{% if isolate_stations is defined %} +# Client isolation can be used to prevent low-level bridging of frames between +# associated stations in the BSS. By default, this bridging is allowed. +ap_isolate=1 +{% endif %} + +{% if reduce_transmit_power is defined %} +# Add Power Constraint element to Beacon and Probe Response frames +# This config option adds Power Constraint element when applicable and Country +# element is added. Power Constraint element is required by Transmit Power +# Control. This can be used only with ieee80211d=1. +# Valid values are 0..255. +local_pwr_constraint={{ reduce_transmit_power }} +{% endif %} + +{% if expunge_failing_stations is defined %} +# Disassociate stations based on excessive transmission failures or other +# indications of connection loss. This depends on the driver capabilities and +# may not be available with all drivers. +disassoc_low_ack=1 +{% endif %} + + +{% if security is defined and security.wep is defined %} +# IEEE 802.11 specifies two authentication algorithms. hostapd can be +# configured to allow both of these or only one. Open system authentication +# should be used with IEEE 802.1X. +# Bit fields of allowed authentication algorithms: +# bit 0 = Open System Authentication +# bit 1 = Shared Key Authentication (requires WEP) +auth_algs=2 + +# WEP rekeying (disabled if key lengths are not set or are set to 0) +# Key lengths for default/broadcast and individual/unicast keys: +# 5 = 40-bit WEP (also known as 64-bit WEP with 40 secret bits) +# 13 = 104-bit WEP (also known as 128-bit WEP with 104 secret bits) +wep_key_len_broadcast=5 +wep_key_len_unicast=5 + +# Static WEP key configuration +# +# The key number to use when transmitting. +# It must be between 0 and 3, and the corresponding key must be set. +# default: not set +wep_default_key=0 + +# The WEP keys to use. +# A key may be a quoted string or unquoted hexadecimal digits. +# The key length should be 5, 13, or 16 characters, or 10, 26, or 32 +# digits, depending on whether 40-bit (64-bit), 104-bit (128-bit), or +# 128-bit (152-bit) WEP is used. +# Only the default key must be supplied; the others are optional. +{% if security.wep.key is defined %} +{% for key in sec_wep_key %} +wep_key{{ loop.index -1 }}={{ security.wep.key }} +{% endfor %} +{% endif %} + + +{% elif security is defined and security.wpa is defined %} +##### WPA/IEEE 802.11i configuration ########################################## + +# Enable WPA. Setting this variable configures the AP to require WPA (either +# WPA-PSK or WPA-RADIUS/EAP based on other configuration). For WPA-PSK, either +# wpa_psk or wpa_passphrase must be set and wpa_key_mgmt must include WPA-PSK. +# Instead of wpa_psk / wpa_passphrase, wpa_psk_radius might suffice. +# For WPA-RADIUS/EAP, ieee8021x must be set (but without dynamic WEP keys), +# RADIUS authentication server must be configured, and WPA-EAP must be included +# in wpa_key_mgmt. +# This field is a bit field that can be used to enable WPA (IEEE 802.11i/D3.0) +# and/or WPA2 (full IEEE 802.11i/RSN): +# bit0 = WPA +# bit1 = IEEE 802.11i/RSN (WPA2) (dot11RSNAEnabled) +{% if security.wpa.mode is defined %} +{% if security.wpa.mode == 'both' %} +wpa=3 +{% elif security.wpa.mode == 'wpa2' %} +wpa=2 +{% elif security.wpa.mode == 'wpa' %} +wpa=1 +{% endif %} +{% endif %} + +{% if security.wpa.cipher is defined %} +# Set of accepted cipher suites (encryption algorithms) for pairwise keys +# (unicast packets). This is a space separated list of algorithms: +# CCMP = AES in Counter mode with CBC-MAC (CCMP-128) +# TKIP = Temporal Key Integrity Protocol +# CCMP-256 = AES in Counter mode with CBC-MAC with 256-bit key +# GCMP = Galois/counter mode protocol (GCMP-128) +# GCMP-256 = Galois/counter mode protocol with 256-bit key +# Group cipher suite (encryption algorithm for broadcast and multicast frames) +# is automatically selected based on this configuration. If only CCMP is +# allowed as the pairwise cipher, group cipher will also be CCMP. Otherwise, +# TKIP will be used as the group cipher. The optional group_cipher parameter can +# be used to override this automatic selection. + +{% if security.wpa.mode is defined and security.wpa.mode == 'wpa2' %} +# Pairwise cipher for RSN/WPA2 (default: use wpa_pairwise value) +{% if security.wpa.cipher is string %} +rsn_pairwise={{ security.wpa.cipher }} +{% else %} +rsn_pairwise={{ security.wpa.cipher | join(" ") }} +{% endif %} +{% else %} +# Pairwise cipher for WPA (v1) (default: TKIP) +{% if security.wpa.cipher is string %} +wpa_pairwise={{ security.wpa.cipher }} +{% else %} +wpa_pairwise={{ security.wpa.cipher | join(" ") }} +{% endif %} +{% endif %} +{% endif %} + +{% if security.wpa.group_cipher is defined %} +# Optional override for automatic group cipher selection +# This can be used to select a specific group cipher regardless of which +# pairwise ciphers were enabled for WPA and RSN. It should be noted that +# overriding the group cipher with an unexpected value can result in +# interoperability issues and in general, this parameter is mainly used for +# testing purposes. +{% if security.wpa.group_cipher is string %} +group_cipher={{ security.wpa.group_cipher }} +{% else %} +group_cipher={{ security.wpa.group_cipher | join(" ") }} +{% endif %} +{% endif %} + +{% if security.wpa.passphrase is defined %} +# IEEE 802.11 specifies two authentication algorithms. hostapd can be +# configured to allow both of these or only one. Open system authentication +# should be used with IEEE 802.1X. +# Bit fields of allowed authentication algorithms: +# bit 0 = Open System Authentication +# bit 1 = Shared Key Authentication (requires WEP) +auth_algs=1 + +# WPA pre-shared keys for WPA-PSK. This can be either entered as a 256-bit +# secret in hex format (64 hex digits), wpa_psk, or as an ASCII passphrase +# (8..63 characters) that will be converted to PSK. This conversion uses SSID +# so the PSK changes when ASCII passphrase is used and the SSID is changed. +wpa_passphrase={{ security.wpa.passphrase }} + +# Set of accepted key management algorithms (WPA-PSK, WPA-EAP, or both). The +# entries are separated with a space. WPA-PSK-SHA256 and WPA-EAP-SHA256 can be +# added to enable SHA256-based stronger algorithms. +# WPA-PSK = WPA-Personal / WPA2-Personal +# WPA-PSK-SHA256 = WPA2-Personal using SHA256 +wpa_key_mgmt=WPA-PSK + +{% elif security.wpa.radius is defined %} +##### IEEE 802.1X-2004 related configuration ################################## +# Require IEEE 802.1X authorization +ieee8021x=1 + +# Set of accepted key management algorithms (WPA-PSK, WPA-EAP, or both). The +# entries are separated with a space. WPA-PSK-SHA256 and WPA-EAP-SHA256 can be +# added to enable SHA256-based stronger algorithms. +# WPA-EAP = WPA-Enterprise / WPA2-Enterprise +# WPA-EAP-SHA256 = WPA2-Enterprise using SHA256 +wpa_key_mgmt=WPA-EAP + +{% if security.wpa.radius.server is defined %} +# RADIUS client forced local IP address for the access point +# Normally the local IP address is determined automatically based on configured +# IP addresses, but this field can be used to force a specific address to be +# used, e.g., when the device has multiple IP addresses. +# The own IP address of the access point (used as NAS-IP-Address) +{% if security.wpa.radius.source_address is defined %} +radius_client_addr={{ security.wpa.radius.source_address }} +own_ip_addr={{ security.wpa.radius.source_address }} +{% else %} +own_ip_addr=127.0.0.1 +{% endif %} + +{% for radius in security.wpa.radius.server if not radius.disabled %} +# RADIUS authentication server +auth_server_addr={{ radius.server }} +auth_server_port={{ radius.port }} +auth_server_shared_secret={{ radius.key }} + +{% if radius.acc_port %} +# RADIUS accounting server +acct_server_addr={{ radius.server }} +acct_server_port={{ radius.acc_port }} +acct_server_shared_secret={{ radius.key }} +{% endif %} +{% endfor %} +{% else %} +# Open system +auth_algs=1 +{% endif %} +{% endif %} +{% endif %} + +# TX queue parameters (EDCF / bursting) +# tx_queue_<queue name>_<param> +# queues: data0, data1, data2, data3 +# (data0 is the highest priority queue) +# parameters: +# aifs: AIFS (default 2) +# cwmin: cwMin (1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, +# 16383, 32767) +# cwmax: cwMax (same values as cwMin, cwMax >= cwMin) +# burst: maximum length (in milliseconds with precision of up to 0.1 ms) for +# bursting +# +# Default WMM parameters (IEEE 802.11 draft; 11-03-0504-03-000e): +# These parameters are used by the access point when transmitting frames +# to the clients. +# +# Low priority / AC_BK = background +tx_queue_data3_aifs=7 +tx_queue_data3_cwmin=15 +tx_queue_data3_cwmax=1023 +tx_queue_data3_burst=0 +# Note: for IEEE 802.11b mode: cWmin=31 cWmax=1023 burst=0 +# +# Normal priority / AC_BE = best effort +tx_queue_data2_aifs=3 +tx_queue_data2_cwmin=15 +tx_queue_data2_cwmax=63 +tx_queue_data2_burst=0 +# Note: for IEEE 802.11b mode: cWmin=31 cWmax=127 burst=0 +# +# High priority / AC_VI = video +tx_queue_data1_aifs=1 +tx_queue_data1_cwmin=7 +tx_queue_data1_cwmax=15 +tx_queue_data1_burst=3.0 +# Note: for IEEE 802.11b mode: cWmin=15 cWmax=31 burst=6.0 +# +# Highest priority / AC_VO = voice +tx_queue_data0_aifs=1 +tx_queue_data0_cwmin=3 +tx_queue_data0_cwmax=7 +tx_queue_data0_burst=1.5 + +# Default WMM parameters (IEEE 802.11 draft; 11-03-0504-03-000e): +# for 802.11a or 802.11g networks +# These parameters are sent to WMM clients when they associate. +# The parameters will be used by WMM clients for frames transmitted to the +# access point. +# +# note - txop_limit is in units of 32microseconds +# note - acm is admission control mandatory flag. 0 = admission control not +# required, 1 = mandatory +# note - Here cwMin and cmMax are in exponent form. The actual cw value used +# will be (2^n)-1 where n is the value given here. The allowed range for these +# wmm_ac_??_{cwmin,cwmax} is 0..15 with cwmax >= cwmin. +# +wmm_enabled=1 + +# Low priority / AC_BK = background +wmm_ac_bk_cwmin=4 +wmm_ac_bk_cwmax=10 +wmm_ac_bk_aifs=7 +wmm_ac_bk_txop_limit=0 +wmm_ac_bk_acm=0 +# Note: for IEEE 802.11b mode: cWmin=5 cWmax=10 +# +# Normal priority / AC_BE = best effort +wmm_ac_be_aifs=3 +wmm_ac_be_cwmin=4 +wmm_ac_be_cwmax=10 +wmm_ac_be_txop_limit=0 +wmm_ac_be_acm=0 +# Note: for IEEE 802.11b mode: cWmin=5 cWmax=7 +# +# High priority / AC_VI = video +wmm_ac_vi_aifs=2 +wmm_ac_vi_cwmin=3 +wmm_ac_vi_cwmax=4 +wmm_ac_vi_txop_limit=94 +wmm_ac_vi_acm=0 +# Note: for IEEE 802.11b mode: cWmin=4 cWmax=5 txop_limit=188 +# +# Highest priority / AC_VO = voice +wmm_ac_vo_aifs=2 +wmm_ac_vo_cwmin=2 +wmm_ac_vo_cwmax=3 +wmm_ac_vo_txop_limit=47 +wmm_ac_vo_acm=0 + diff --git a/data/templates/wifi/wpa_supplicant.conf.tmpl b/data/templates/wifi/wpa_supplicant.conf.tmpl new file mode 100644 index 000000000..9ddad35fd --- /dev/null +++ b/data/templates/wifi/wpa_supplicant.conf.tmpl @@ -0,0 +1,9 @@ +# WPA supplicant config +network={ + ssid="{{ ssid }}" +{% if security is defined and security.wpa is defined and security.wpa.passphrase is defined %} + psk="{{ security.wpa.passphrase }}" +{% else %} + key_mgmt=NONE +{% endif %} +} diff --git a/data/templates/wwan/chat.tmpl b/data/templates/wwan/chat.tmpl new file mode 100644 index 000000000..a3395c057 --- /dev/null +++ b/data/templates/wwan/chat.tmpl @@ -0,0 +1,6 @@ +ABORT 'NO DIAL TONE' ABORT 'NO ANSWER' ABORT 'NO CARRIER' ABORT DELAYED +'' AT +OK ATZ +OK 'AT+CGDCONT=1,"IP","{{ apn }}"' +OK ATD*99# +CONNECT '' diff --git a/data/templates/wwan/ip-down.script.tmpl b/data/templates/wwan/ip-down.script.tmpl new file mode 100644 index 000000000..9dc15ea99 --- /dev/null +++ b/data/templates/wwan/ip-down.script.tmpl @@ -0,0 +1,27 @@ +#!/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 new file mode 100644 index 000000000..efc065bad --- /dev/null +++ b/data/templates/wwan/ip-pre-up.script.tmpl @@ -0,0 +1,23 @@ +#!/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 new file mode 100644 index 000000000..2603a0286 --- /dev/null +++ b/data/templates/wwan/ip-up.script.tmpl @@ -0,0 +1,25 @@ +#!/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 new file mode 100644 index 000000000..aa759f741 --- /dev/null +++ b/data/templates/wwan/peer.tmpl @@ -0,0 +1,27 @@ +### 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 +debug +mtu {{ mtu }} +mru {{ mtu }} +nodefaultroute +ipcp-max-failure 4 +ipcp-accept-local +ipcp-accept-remote +noauth +crtscts +lock +persist +{{ "demand" if ondemand is defined }} + +connect '/usr/sbin/chat -v -t6 -f /etc/ppp/peers/chat.{{ ifname }}' + |