summaryrefslogtreecommitdiff
path: root/data/templates
diff options
context:
space:
mode:
Diffstat (limited to 'data/templates')
-rw-r--r--data/templates/firewall/nftables-nat.tmpl4
-rw-r--r--data/templates/firewall/nftables-policy.tmpl53
-rw-r--r--data/templates/firewall/nftables.tmpl292
-rw-r--r--data/templates/ipsec/swanctl.conf.tmpl2
-rw-r--r--data/templates/ipsec/swanctl/peer.tmpl5
-rw-r--r--data/templates/snmp/etc.snmp.conf.tmpl2
-rw-r--r--data/templates/snmp/etc.snmpd.conf.tmpl151
-rw-r--r--data/templates/snmp/override.conf.tmpl2
-rw-r--r--data/templates/snmp/usr.snmpd.conf.tmpl8
-rw-r--r--data/templates/snmp/var.snmpd.conf.tmpl20
-rw-r--r--data/templates/squid/squid.conf.tmpl2
-rw-r--r--data/templates/zone_policy/nftables.tmpl97
12 files changed, 576 insertions, 62 deletions
diff --git a/data/templates/firewall/nftables-nat.tmpl b/data/templates/firewall/nftables-nat.tmpl
index 40ed1b916..9ea880697 100644
--- a/data/templates/firewall/nftables-nat.tmpl
+++ b/data/templates/firewall/nftables-nat.tmpl
@@ -157,8 +157,8 @@ delete chain ip raw NAT_CONNTRACK
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_ignore }} counter jump VYOS_CT_HELPER
+{{ base_command }} OUTPUT position {{ out_ct_ignore }} counter jump VYOS_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 %}
diff --git a/data/templates/firewall/nftables-policy.tmpl b/data/templates/firewall/nftables-policy.tmpl
new file mode 100644
index 000000000..aa6bb6fc1
--- /dev/null
+++ b/data/templates/firewall/nftables-policy.tmpl
@@ -0,0 +1,53 @@
+#!/usr/sbin/nft -f
+
+table ip mangle {
+{% if first_install is defined %}
+ chain VYOS_PBR_PREROUTING {
+ type filter hook prerouting priority -150; policy accept;
+ }
+ chain VYOS_PBR_POSTROUTING {
+ type filter hook postrouting priority -150; policy accept;
+ }
+{% endif %}
+{% if route is defined -%}
+{% for route_text, conf in route.items() %}
+ chain VYOS_PBR_{{ route_text }} {
+{% if conf.rule is defined %}
+{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not defined %}
+ {{ rule_conf | nft_rule(route_text, rule_id, 'ip') }}
+{% endfor %}
+{% endif %}
+{% if conf.default_action is defined %}
+ counter {{ conf.default_action | nft_action }} comment "{{ name_text }} default-action {{ conf.default_action }}"
+{% else %}
+ counter return
+{% endif %}
+ }
+{% endfor %}
+{%- endif %}
+}
+
+table ip6 mangle {
+{% if first_install is defined %}
+ chain VYOS_PBR6_PREROUTING {
+ type filter hook prerouting priority -150; policy accept;
+ }
+ chain VYOS_PBR6_POSTROUTING {
+ type filter hook postrouting priority -150; policy accept;
+ }
+{% endif %}
+{% if ipv6_route is defined %}
+{% for route_text, conf in ipv6_route.items() %}
+ chain VYOS_PBR6_{{ route_text }} {
+{% if conf.rule is defined %}
+{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not defined %}
+ {{ rule_conf | nft_rule(route_text, rule_id, 'ip6') }}
+{% endfor %}
+{% endif %}
+{% if conf.default_action is defined %}
+ counter {{ conf.default_action | nft_action }} comment "{{ name_text }} default-action {{ conf.default_action }}"
+{% endif %}
+ }
+{% endfor %}
+{% endif %}
+}
diff --git a/data/templates/firewall/nftables.tmpl b/data/templates/firewall/nftables.tmpl
new file mode 100644
index 000000000..34bd9b71e
--- /dev/null
+++ b/data/templates/firewall/nftables.tmpl
@@ -0,0 +1,292 @@
+#!/usr/sbin/nft -f
+
+{% if cleanup_commands is defined %}
+{% for command in cleanup_commands %}
+{{ command }}
+{% endfor %}
+{% endif %}
+
+{% if group is defined %}
+{% if group.address_group is defined %}
+{% for group_name, group_conf in group.address_group.items() %}
+define A_{{ group_name }} = {
+ {{ group_conf.address | join(",") }}
+}
+{% endfor %}
+{% endif %}
+{% if group.ipv6_address_group is defined %}
+{% for group_name, group_conf in group.ipv6_address_group.items() %}
+define A6_{{ group_name }} = {
+ {{ group_conf.address | join(",") }}
+}
+{% endfor %}
+{% endif %}
+{% if group.network_group is defined %}
+{% for group_name, group_conf in group.network_group.items() %}
+define N_{{ group_name }} = {
+ {{ group_conf.network | join(",") }}
+}
+{% endfor %}
+{% endif %}
+{% if group.ipv6_network_group is defined %}
+{% for group_name, group_conf in group.ipv6_network_group.items() %}
+define N6_{{ group_name }} = {
+ {{ group_conf.network | join(",") }}
+}
+{% endfor %}
+{% endif %}
+{% if group.port_group is defined %}
+{% for group_name, group_conf in group.port_group.items() %}
+define P_{{ group_name }} = {
+ {{ group_conf.port | join(",") }}
+}
+{% endfor %}
+{% endif %}
+{% endif %}
+
+table ip filter {
+{% if first_install is defined %}
+ chain VYOS_FW_IN {
+ type filter hook forward priority 0; policy accept;
+ }
+ chain VYOS_FW_OUT {
+ type filter hook forward priority 1; policy accept;
+ jump VYOS_POST_FW
+ }
+ chain VYOS_FW_LOCAL {
+ type filter hook input priority 0; policy accept;
+ jump VYOS_POST_FW
+ }
+ chain VYOS_FW_OUTPUT {
+ type filter hook output priority 0; policy accept;
+ jump VYOS_POST_FW
+ }
+ chain VYOS_POST_FW {
+ return
+ }
+ chain VYOS_FRAG_MARK {
+ type filter hook prerouting priority -450; policy accept;
+ ip frag-off & 0x3fff != 0 meta mark set 0xffff1 return
+ }
+{% endif %}
+{% if name is defined %}
+{% for name_text, conf in name.items() %}
+{% set default_log = 'log' if 'enable_default_log' in conf else '' %}
+ chain {{ name_text }} {
+{% if conf.rule is defined %}
+{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not defined %}
+ {{ rule_conf | nft_rule(name_text, rule_id) }}
+{% endfor %}
+{% endif %}
+{% if conf.default_action is defined %}
+ counter {{ default_log }} {{ conf.default_action | nft_action }} comment "{{ name_text }} default-action {{ conf.default_action }}"
+{% else %}
+ return
+{% endif %}
+ }
+{% endfor %}
+{% endif %}
+{% if state_policy is defined %}
+ chain VYOS_STATE_POLICY {
+{% if state_policy.established is defined %}
+ {{ state_policy.established | nft_state_policy('established') }}
+{% endif %}
+{% if state_policy.invalid is defined %}
+ {{ state_policy.invalid | nft_state_policy('invalid') }}
+{% endif %}
+{% if state_policy.related is defined %}
+ {{ state_policy.related | nft_state_policy('related') }}
+{% endif %}
+ return
+ }
+{% endif %}
+}
+
+table ip6 filter {
+{% if first_install is defined %}
+ chain VYOS_FW6_IN {
+ type filter hook forward priority 0; policy accept;
+ }
+ chain VYOS_FW6_OUT {
+ type filter hook forward priority 1; policy accept;
+ jump VYOS_POST_FW6
+ }
+ chain VYOS_FW6_LOCAL {
+ type filter hook input priority 0; policy accept;
+ jump VYOS_POST_FW6
+ }
+ chain VYOS_FW6_OUTPUT {
+ type filter hook output priority 0; policy accept;
+ jump VYOS_POST_FW6
+ }
+ chain VYOS_POST_FW6 {
+ return
+ }
+ chain VYOS_FRAG6_MARK {
+ type filter hook prerouting priority -450; policy accept;
+ exthdr frag exists meta mark set 0xffff1 return
+ }
+{% endif %}
+{% if ipv6_name is defined %}
+{% for name_text, conf in ipv6_name.items() %}
+{% set default_log = 'log' if 'enable_default_log' in conf else '' %}
+ chain {{ name_text }} {
+{% if conf.rule is defined %}
+{% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not defined %}
+ {{ rule_conf | nft_rule(name_text, rule_id, 'ip6') }}
+{% endfor %}
+{% endif %}
+{% if conf.default_action is defined %}
+ counter {{ default_log }} {{ conf.default_action | nft_action }} comment "{{ name_text }} default-action {{ conf.default_action }}"
+{% else %}
+ return
+{% endif %}
+ }
+{% endfor %}
+{% endif %}
+{% if state_policy is defined %}
+ chain VYOS_STATE_POLICY6 {
+{% if state_policy.established is defined %}
+ {{ state_policy.established | nft_state_policy('established') }}
+{% endif %}
+{% if state_policy.invalid is defined %}
+ {{ state_policy.invalid | nft_state_policy('invalid') }}
+{% endif %}
+{% if state_policy.related is defined %}
+ {{ state_policy.related | nft_state_policy('related') }}
+{% endif %}
+ return
+ }
+{% endif %}
+}
+
+{% if first_install is defined %}
+table ip nat {
+ chain PREROUTING {
+ type nat hook prerouting priority -100; policy accept;
+ counter jump VYOS_PRE_DNAT_HOOK
+ }
+
+ chain POSTROUTING {
+ type nat hook postrouting priority 100; policy accept;
+ counter jump VYOS_PRE_SNAT_HOOK
+ }
+
+ chain VYOS_PRE_DNAT_HOOK {
+ return
+ }
+
+ chain VYOS_PRE_SNAT_HOOK {
+ return
+ }
+}
+
+table ip6 nat {
+ chain PREROUTING {
+ type nat hook prerouting priority -100; policy accept;
+ counter jump VYOS_DNPT_HOOK
+ }
+
+ chain POSTROUTING {
+ type nat hook postrouting priority 100; policy accept;
+ counter jump VYOS_SNPT_HOOK
+ }
+
+ chain VYOS_DNPT_HOOK {
+ return
+ }
+
+ chain VYOS_SNPT_HOOK {
+ return
+ }
+}
+
+table inet mangle {
+ chain FORWARD {
+ type filter hook forward priority -150; policy accept;
+ }
+}
+
+table raw {
+ chain VYOS_TCP_MSS {
+ type filter hook forward priority -300; policy accept;
+ }
+
+ chain PREROUTING {
+ type filter hook prerouting priority -200; policy accept;
+ counter jump VYOS_CT_IGNORE
+ counter jump VYOS_CT_TIMEOUT
+ counter jump VYOS_CT_PREROUTING_HOOK
+ notrack
+ }
+
+ chain OUTPUT {
+ type filter hook output priority -200; policy accept;
+ counter jump VYOS_CT_IGNORE
+ counter jump VYOS_CT_TIMEOUT
+ counter jump VYOS_CT_OUTPUT_HOOK
+ notrack
+ }
+
+ ct helper rpc_tcp {
+ type "rpc" protocol tcp;
+ }
+
+ ct helper rpc_udp {
+ type "rpc" protocol udp;
+ }
+
+ ct helper tns_tcp {
+ type "tns" protocol tcp;
+ }
+
+ chain VYOS_CT_HELPER {
+ ct helper set "rpc_tcp" tcp dport {111} return
+ ct helper set "rpc_udp" udp dport {111} return
+ ct helper set "tns_tcp" tcp dport {1521,1525,1536} return
+ return
+ }
+
+ chain VYOS_CT_IGNORE {
+ return
+ }
+
+ chain VYOS_CT_TIMEOUT {
+ return
+ }
+
+ chain VYOS_CT_PREROUTING_HOOK {
+ return
+ }
+
+ chain VYOS_CT_OUTPUT_HOOK {
+ return
+ }
+}
+
+table ip6 raw {
+ chain VYOS_TCP_MSS {
+ type filter hook forward priority -300; policy accept;
+ }
+
+ chain PREROUTING {
+ type filter hook prerouting priority -300; policy accept;
+ counter jump VYOS_CT_PREROUTING_HOOK
+ notrack
+ }
+
+ chain OUTPUT {
+ type filter hook output priority -300; policy accept;
+ counter jump VYOS_CT_OUTPUT_HOOK
+ notrack
+ }
+
+ chain VYOS_CT_PREROUTING_HOOK {
+ return
+ }
+
+ chain VYOS_CT_OUTPUT_HOOK {
+ return
+ }
+}
+{% endif %}
diff --git a/data/templates/ipsec/swanctl.conf.tmpl b/data/templates/ipsec/swanctl.conf.tmpl
index 161f19f95..68b108365 100644
--- a/data/templates/ipsec/swanctl.conf.tmpl
+++ b/data/templates/ipsec/swanctl.conf.tmpl
@@ -57,7 +57,7 @@ secrets {
{% endif %}
{% if site_to_site is defined and site_to_site.peer is defined %}
{% for peer, peer_conf in site_to_site.peer.items() if peer not in dhcp_no_address and peer_conf.disable is not defined %}
-{% set peer_name = peer.replace(".", "-").replace("@", "") %}
+{% set peer_name = peer.replace("@", "") | dot_colon_to_dash %}
{% if peer_conf.authentication.mode == 'pre-shared-secret' %}
ike_{{ peer_name }} {
{% if peer_conf.local_address is defined %}
diff --git a/data/templates/ipsec/swanctl/peer.tmpl b/data/templates/ipsec/swanctl/peer.tmpl
index 8c3776bf1..c6b71f2a1 100644
--- a/data/templates/ipsec/swanctl/peer.tmpl
+++ b/data/templates/ipsec/swanctl/peer.tmpl
@@ -1,5 +1,5 @@
{% macro conn(peer, peer_conf, ike_group, esp_group) %}
-{% set name = peer.replace(".", "-").replace("@", "") %}
+{% set name = peer.replace("@", "") | dot_colon_to_dash %}
{# peer needs to reference the global IKE configuration for certain values #}
{% set ike = ike_group[peer_conf.ike_group] %}
peer_{{ name }} {
@@ -101,6 +101,9 @@
{% set remote_prefix = tunnel_conf.remote.prefix if 'any' not in tunnel_conf.remote.prefix else ['0.0.0.0/0', '::/0'] %}
remote_ts = {{ remote_prefix | join(remote_suffix + ",") }}{{ remote_suffix }}
{% endif %}
+{% if tunnel_conf.priority is defined and tunnel_conf.priority is not none %}
+ priority = {{ tunnel_conf.priority }}
+{% endif %}
{% elif tunnel_esp.mode == 'transport' %}
local_ts = {{ peer_conf.local_address }}{{ local_suffix }}
remote_ts = {{ peer }}{{ remote_suffix }}
diff --git a/data/templates/snmp/etc.snmp.conf.tmpl b/data/templates/snmp/etc.snmp.conf.tmpl
index 6e4c6f063..f7d9a3c17 100644
--- a/data/templates/snmp/etc.snmp.conf.tmpl
+++ b/data/templates/snmp/etc.snmp.conf.tmpl
@@ -1,4 +1,4 @@
### Autogenerated by snmp.py ###
-{% if trap_source %}
+{% if trap_source is defined and trap_source is not none %}
clientaddr {{ trap_source }}
{% endif %}
diff --git a/data/templates/snmp/etc.snmpd.conf.tmpl b/data/templates/snmp/etc.snmpd.conf.tmpl
index 30806ce8a..befea0122 100644
--- a/data/templates/snmp/etc.snmpd.conf.tmpl
+++ b/data/templates/snmp/etc.snmpd.conf.tmpl
@@ -33,87 +33,152 @@ interface_replace_old yes
# Default system description is VyOS version
sysDescr VyOS {{ version }}
-{% if description %}
+{% if description is defined and description is not none %}
# Description
SysDescr {{ description }}
{% endif %}
# Listen
-agentaddress unix:/run/snmpd.socket{% if listen_on %}{% for li in listen_on %},{{ li }}{% endfor %}{% else %},{{protocol}}:161{% if ipv6_enabled %},{{protocol}}6:161{% endif %}{% endif %}
+{% set options = [] %}
+{% if listen_address is defined and listen_address is not none %}
+{% for address, address_options in listen_address.items() %}
+{% if address | is_ipv6 %}
+{% set protocol = protocol ~ '6' %}
+{% endif %}
+{% set _ = options.append(protocol ~ ':' ~ address | bracketize_ipv6 ~ ':' ~ address_options.port) %}
+{% endfor %}
+{% else %}
+{% set _ = options.append(protocol ~ ':161') %}
+{% if ipv6_disabled is not defined %}
+{% set _ = options.append(protocol ~ '6:161') %}
+{% endif %}
+{% endif %}
+agentaddress unix:/run/snmpd.socket{{ ',' ~ options | join(',') if options is defined and options is not none }}
# 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 community is defined and community is not none %}
+{% for comm, comm_config in community.items() %}
+{% if comm_config.client is defined and comm_config.client is not none %}
+{% for client in comm_config.client %}
+{% if client | is_ipv4 %}
+{{ comm_config.authorization }}community {{ comm }} {{ client }}
+{% elif client | is_ipv6 %}
+{{ comm_config.authorization }}community6 {{ comm }} {{ client }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if comm_config.network is defined and comm_config.network is not none %}
+{% for network in comm_config.network %}
+{% if network | is_ipv4 %}
+{{ comm_config.authorization }}community {{ comm }} {{ network }}
+{% elif client | is_ipv6 %}
+{{ comm_config.authorization }}community6 {{ comm }} {{ network }}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if comm_config.client is not defined and comm_config.network is not defined %}
+{{ comm_config.authorization }}community {{ comm }}
+{% endif %}
+{% endfor %}
+{% endif %}
-{% if contact %}
+{% if contact is defined and contact is not none %}
# system contact information
SysContact {{ contact }}
{% endif %}
-{% if location %}
+{% if location is defined and location is not none %}
# system location information
SysLocation {{ location }}
{% endif %}
-{% if smux_peers %}
+{% if smux_peer is defined and smux_peer is not none %}
# additional smux peers
-{% for sp in smux_peers %}
-smuxpeer {{ sp }}
+{% for peer in smux_peer %}
+smuxpeer {{ peer }}
{% endfor %}
{% endif %}
-{% if trap_targets %}
+{% if trap_target is defined and trap_target is not none %}
# if there is a problem - tell someone!
-{% for trap in trap_targets %}
-trap2sink {{ trap.target }}{{ ":" + trap.port if trap.port is defined }} {{ trap.community }}
+{% for trap, trap_config in trap_target.items() %}
+trap2sink {{ trap }}:{{ trap_config.port }} {{ trap_config.community }}
{% endfor %}
{% endif %}
-{% if v3_enabled %}
+{% if v3 is defined and v3 is not none %}
#
# SNMPv3 stuff goes here
#
+{% if v3.view is defined and v3.view is not none %}
# views
-{% for view in v3_views %}
-{% for oid in view.oids %}
-view {{ view.name }} included .{{ oid.oid }}
+{% for view, view_config in v3.view.items() %}
+{% if view_config.oid is defined and view_config.oid is not none %}
+{% for oid in view_config.oid %}
+view {{ view }} included .{{ oid }}
+{% endfor %}
+{% endif %}
{% endfor %}
-{% endfor %}
+{% endif %}
# access
+{% if v3.group is defined and v3.group is not none %}
# 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 %}
+{% for group, group_config in v3.group.items() %}
+access {{ group }} "" usm {{ group_config.seclevel }} exact {{ group_config.view }} {% if group_config.mode == 'ro' %}none{% else %}{{ group_config.view }}{% endif %} none
+{% endfor %}
+{% endif %}
# 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 %}
+{% if v3.trap_target is defined and v3.trap_target is not none %}
+{% for trap, trap_config in v3.trap_target.items() %}
+{% set options = '' %}
+{% if trap_config.type == 'inform' %}
+{% set options = options ~ ' -Ci' %}
+{% endif %}
+{% if v3.engineid is defined and v3.engineid is not none %}
+{% set options = options ~ ' -e "' ~ v3.engineid ~ '"' %}
+{% endif %}
+{% if trap_config.user is defined and trap_config.user is not none %}
+{% set options = options ~ ' -u ' ~ trap_config.user %}
+{% endif %}
+{% if trap_config.auth is defined and trap_config.auth.plaintext_password is defined or trap_config.auth.encrypted_password is defined %}
+{% set options = options ~ ' -a ' ~ trap_config.auth.type %}
+{% if trap_config.auth.plaintext_password is defined and trap_config.auth.plaintext_password is not none %}
+{% set options = options ~ ' -A ' ~ trap_config.auth.plaintext_password %}
+{% elif trap_config.auth.encrypted_password is defined and trap_config.auth.encrypted_password is not none %}
+{% set options = options ~ ' -3m ' ~ trap_config.auth.encrypted_password %}
+{% endif %}
+{% if trap_config.privacy is defined and trap_config.privacy.plaintext_password is defined or trap_config.privacy.encrypted_password is defined %}
+{% set options = options ~ ' -x ' ~ trap_config.privacy.type %}
+{% if trap_config.privacy.plaintext_password is defined and trap_config.privacy.plaintext_password is not none %}
+{% set options = options ~ ' -X ' ~ trap_config.privacy.plaintext_password %}
+{% elif trap_config.privacy.encrypted_password is defined and trap_config.privacy.encrypted_password is not none %}
+{% set options = options ~ ' -3M ' ~ trap_config.privacy.encrypted_password %}
+{% endif %}
+{% set options = options ~ ' -l authPriv' %}
+{% else %}
+{% set options = options ~ ' -l authNoPriv' %}
+{% endif %}
+{% else %}
+{% set options = options ~ ' -l noAuthNoPriv' %}
+{% endif %}
+trapsess -v 3 {{ options }} {{ trap }}:{{ trap_config.protocol }}:{{ trap_config.port }}
+{% endfor %}
+{% endif %}
# group
-{% for u in v3_users %}
-group {{ u.group }} usm {{ u.name }}
-{% endfor %}
+{% if v3.user is defined and v3.user is not none %}
+{% for user, user_config in v3.user.items() %}
+group {{ user_config.group }} usm {{ user }}
+{% endfor %}
+{% endif %}
+{# SNMPv3 end #}
{% endif %}
-{% if script_ext %}
+{% if script_extensions is defined and script_extensions.extension_name is defined and script_extensions.extension_name is not none %}
# extension scripts
-{% for ext in script_ext|sort(attribute='name') %}
-extend {{ ext.name }} {{ ext.script }}
+{% for script, script_config in script_extensions.extension_name.items() | sort(attribute=script) %}
+extend {{ script }} {{ script_config.script }}
{% endfor %}
{% endif %}
diff --git a/data/templates/snmp/override.conf.tmpl b/data/templates/snmp/override.conf.tmpl
index 2ac45a89f..3b00aab83 100644
--- a/data/templates/snmp/override.conf.tmpl
+++ b/data/templates/snmp/override.conf.tmpl
@@ -1,5 +1,5 @@
{% set vrf_command = 'ip vrf exec ' + vrf + ' ' if vrf is defined else '' %}
-{% set oid_route_table = ' ' if route_table is sameas true else '-I -ipCidrRouteTable,inetCidrRouteTable' %}
+{% set oid_route_table = ' ' if oid_enable is defined and oid_enable == 'route-table' else '-I -ipCidrRouteTable,inetCidrRouteTable' %}
[Unit]
StartLimitIntervalSec=0
After=vyos-router.service
diff --git a/data/templates/snmp/usr.snmpd.conf.tmpl b/data/templates/snmp/usr.snmpd.conf.tmpl
index e2c5ec102..1c688a61e 100644
--- a/data/templates/snmp/usr.snmpd.conf.tmpl
+++ b/data/templates/snmp/usr.snmpd.conf.tmpl
@@ -1,6 +1,8 @@
### Autogenerated by snmp.py ###
-{% for u in v3_users %}
-{{ u.mode }}user {{ u.name }}
-{% endfor %}
+{% if v3 is defined and v3.user is defined and v3.user is not none %}
+{% for user, user_config in v3.user.items() %}
+{{ user_config.mode }}user {{ user }}
+{% endfor %}
+{% endif %}
rwuser {{ vyos_user }}
diff --git a/data/templates/snmp/var.snmpd.conf.tmpl b/data/templates/snmp/var.snmpd.conf.tmpl
index c779587df..5871a8234 100644
--- a/data/templates/snmp/var.snmpd.conf.tmpl
+++ b/data/templates/snmp/var.snmpd.conf.tmpl
@@ -1,14 +1,16 @@
### 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 %}
+{% if v3 is defined and v3 is not none %}
+{% if v3.user is defined and v3.user is not none %}
+{% for user, user_config in v3.user.items() %}
+usmUser 1 3 0x{{ v3.engineid }} "{{ user }}" "{{ user }}" NULL {{ user_config.auth.type | snmp_auth_oid }} 0x{{ user_config.auth.encrypted_password }} {{ user_config.privacy.type | snmp_auth_oid }} 0x{{ user_config.privacy.encrypted_password }} 0x
+{% endfor %}
+{% endif %}
+# VyOS default user
createUser {{ vyos_user }} MD5 "{{ vyos_user_pass }}" DES
-{% if v3_engineid %}
-oldEngineID 0x{{ v3_engineid }}
+
+{% if v3.engineid is defined and v3.engineid is not none %}
+oldEngineID 0x{{ v3.engineid }}
+{% endif %}
{% endif %}
diff --git a/data/templates/squid/squid.conf.tmpl b/data/templates/squid/squid.conf.tmpl
index 80826fc75..26aff90bf 100644
--- a/data/templates/squid/squid.conf.tmpl
+++ b/data/templates/squid/squid.conf.tmpl
@@ -88,7 +88,7 @@ tcp_outgoing_address {{ outgoing_address }}
{% if listen_address is defined and listen_address is not none %}
{% for address, config in listen_address.items() %}
-http_port {{ address }}:{{ config.port if config.port is defined else default_port }} {{ 'intercept' if config.disable_transparent is not defined }}
+http_port {{ address | bracketize_ipv6 }}:{{ config.port if config.port is defined else default_port }} {{ 'intercept' if config.disable_transparent is not defined }}
{% endfor %}
{% endif %}
http_port 127.0.0.1:{{ default_port }}
diff --git a/data/templates/zone_policy/nftables.tmpl b/data/templates/zone_policy/nftables.tmpl
new file mode 100644
index 000000000..21230c688
--- /dev/null
+++ b/data/templates/zone_policy/nftables.tmpl
@@ -0,0 +1,97 @@
+#!/usr/sbin/nft -f
+
+{% if cleanup_commands is defined %}
+{% for command in cleanup_commands %}
+{{ command }}
+{% endfor %}
+{% endif %}
+
+{% if zone is defined %}
+table ip filter {
+{% for zone_name, zone_conf in zone.items() if zone_conf.ipv4 %}
+{% if zone_conf.local_zone is defined %}
+ chain VZONE_{{ zone_name }}_IN {
+ iifname lo counter return
+{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall.name is defined %}
+ iifname { {{ zone[from_zone].interface | join(",") }} } counter jump {{ from_conf.firewall.name }}
+ iifname { {{ zone[from_zone].interface | join(",") }} } counter return
+{% endfor %}
+ counter {{ zone_conf.default_action if zone_conf.default_action is defined else 'drop' }}
+ }
+ chain VZONE_{{ zone_name }}_OUT {
+ oifname lo counter return
+{% for from_zone, from_conf in zone_conf.from_local.items() if from_conf.firewall.name is defined %}
+ oifname { {{ zone[from_zone].interface | join(",") }} } counter jump {{ from_conf.firewall.name }}
+ oifname { {{ zone[from_zone].interface | join(",") }} } counter return
+{% endfor %}
+ counter {{ zone_conf.default_action if zone_conf.default_action is defined else 'drop' }}
+ }
+{% else %}
+ chain VZONE_{{ zone_name }} {
+ iifname { {{ zone_conf.interface | join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6=False) }}
+{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall.name is defined %}
+{% if zone[from_zone].local_zone is not defined %}
+ iifname { {{ zone[from_zone].interface | join(",") }} } counter jump {{ from_conf.firewall.name }}
+ iifname { {{ zone[from_zone].interface | join(",") }} } counter return
+{% endif %}
+{% endfor %}
+ counter {{ zone_conf.default_action if zone_conf.default_action is defined else 'drop' }}
+ }
+{% endif %}
+{% endfor %}
+}
+
+table ip6 filter {
+{% for zone_name, zone_conf in zone.items() if zone_conf.ipv6 %}
+{% if zone_conf.local_zone is defined %}
+ chain VZONE6_{{ zone_name }}_IN {
+ iifname lo counter return
+{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall.ipv6_name is defined %}
+ iifname { {{ zone[from_zone].interface | join(",") }} } counter jump {{ from_conf.firewall.ipv6_name }}
+ iifname { {{ zone[from_zone].interface | join(",") }} } counter return
+{% endfor %}
+ counter {{ zone_conf.default_action if zone_conf.default_action is defined else 'drop' }}
+ }
+ chain VZONE6_{{ zone_name }}_OUT {
+ oifname lo counter return
+{% for from_zone, from_conf in zone_conf.from_local.items() if from_conf.firewall.ipv6_name is defined %}
+ oifname { {{ zone[from_zone].interface | join(",") }} } counter jump {{ from_conf.firewall.ipv6_name }}
+ oifname { {{ zone[from_zone].interface | join(",") }} } counter return
+{% endfor %}
+ counter {{ zone_conf.default_action if zone_conf.default_action is defined else 'drop' }}
+ }
+{% else %}
+ chain VZONE6_{{ zone_name }} {
+ iifname { {{ zone_conf.interface | join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6=True) }}
+{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall.ipv6_name is defined %}
+{% if zone[from_zone].local_zone is not defined %}
+ iifname { {{ zone[from_zone].interface | join(",") }} } counter jump {{ from_conf.firewall.ipv6_name }}
+ iifname { {{ zone[from_zone].interface | join(",") }} } counter return
+{% endif %}
+{% endfor %}
+ counter {{ zone_conf.default_action if zone_conf.default_action is defined else 'drop' }}
+ }
+{% endif %}
+{% endfor %}
+}
+
+{% for zone_name, zone_conf in zone.items() %}
+{% if zone_conf.ipv4 %}
+{% if 'local_zone' in zone_conf %}
+insert rule ip filter VYOS_FW_LOCAL counter jump VZONE_{{ zone_name }}_IN
+insert rule ip filter VYOS_FW_OUTPUT counter jump VZONE_{{ zone_name }}_OUT
+{% else %}
+insert rule ip filter VYOS_FW_OUT oifname { {{ zone_conf.interface | join(',') }} } counter jump VZONE_{{ zone_name }}
+{% endif %}
+{% endif %}
+{% if zone_conf.ipv6 %}
+{% if 'local_zone' in zone_conf %}
+insert rule ip6 filter VYOS_FW6_LOCAL counter jump VZONE6_{{ zone_name }}_IN
+insert rule ip6 filter VYOS_FW6_OUTPUT counter jump VZONE6_{{ zone_name }}_OUT
+{% else %}
+insert rule ip6 filter VYOS_FW6_OUT oifname { {{ zone_conf.interface | join(',') }} } counter jump VZONE6_{{ zone_name }}
+{% endif %}
+{% endif %}
+{% endfor %}
+
+{% endif %}