diff options
Diffstat (limited to 'data/templates/firewall')
-rw-r--r-- | data/templates/firewall/nftables-bridge.j2 | 6 | ||||
-rw-r--r-- | data/templates/firewall/nftables-defines.j2 | 21 | ||||
-rw-r--r-- | data/templates/firewall/nftables-policy.j2 | 6 | ||||
-rw-r--r-- | data/templates/firewall/nftables-vrf-zones.j2 | 17 | ||||
-rw-r--r-- | data/templates/firewall/nftables-zone.j2 | 77 | ||||
-rw-r--r-- | data/templates/firewall/nftables.j2 | 88 | ||||
-rw-r--r-- | data/templates/firewall/upnpd.conf.j2 | 116 |
7 files changed, 262 insertions, 69 deletions
diff --git a/data/templates/firewall/nftables-bridge.j2 b/data/templates/firewall/nftables-bridge.j2 index 7f94e10d6..dec027bf9 100644 --- a/data/templates/firewall/nftables-bridge.j2 +++ b/data/templates/firewall/nftables-bridge.j2 @@ -2,9 +2,8 @@ {% set ns = namespace(sets=[]) %} {% if bridge.forward is vyos_defined %} {% for prior, conf in bridge.forward.items() %} -{% set def_action = conf.default_action %} chain VYOS_FORWARD_{{ prior }} { - type filter hook forward priority {{ prior }}; policy {{ def_action }}; + type filter hook forward priority {{ prior }}; policy accept; {% if conf.rule is vyos_defined %} {% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} {{ rule_conf | nft_rule('FWD', prior, rule_id, 'bri') }} @@ -13,6 +12,7 @@ {% endif %} {% endfor %} {% endif %} + {{ conf | nft_default_rule('FWD-filter', 'bri') }} } {% endfor %} {% endif %} @@ -28,7 +28,7 @@ {% endif %} {% endfor %} {% endif %} - {{ conf | nft_default_rule(name_text) }} + {{ conf | nft_default_rule(name_text, 'bri') }} } {% endfor %} {% endif %} diff --git a/data/templates/firewall/nftables-defines.j2 b/data/templates/firewall/nftables-defines.j2 index a20c399ae..8a75ab2d6 100644 --- a/data/templates/firewall/nftables-defines.j2 +++ b/data/templates/firewall/nftables-defines.j2 @@ -98,5 +98,26 @@ } {% endfor %} {% endif %} + +{% if group.dynamic_group is vyos_defined %} +{% if group.dynamic_group.address_group is vyos_defined and not is_ipv6 and is_l3 %} +{% for group_name, group_conf in group.dynamic_group.address_group.items() %} + set DA_{{ group_name }} { + type {{ ip_type }} + flags dynamic, timeout + } +{% endfor %} +{% endif %} + +{% if group.dynamic_group.ipv6_address_group is vyos_defined and is_ipv6 and is_l3 %} +{% for group_name, group_conf in group.dynamic_group.ipv6_address_group.items() %} + set DA6_{{ group_name }} { + type {{ ip_type }} + flags dynamic, timeout + } +{% endfor %} +{% endif %} +{% endif %} + {% endif %} {% endmacro %} diff --git a/data/templates/firewall/nftables-policy.j2 b/data/templates/firewall/nftables-policy.j2 index d77e3f6e9..9e28899b0 100644 --- a/data/templates/firewall/nftables-policy.j2 +++ b/data/templates/firewall/nftables-policy.j2 @@ -28,6 +28,9 @@ table ip vyos_mangle { {{ rule_conf | nft_rule('route', route_text, rule_id, 'ip') }} {% endfor %} {% endif %} +{% if conf.default_log is vyos_defined %} + counter log prefix "[ipv4-{{ (route_text)[:19] }}-default]" +{% endif %} } {% endfor %} {% endif %} @@ -57,6 +60,9 @@ table ip6 vyos_mangle { {{ rule_conf | nft_rule('route6', route_text, rule_id, 'ip6') }} {% endfor %} {% endif %} +{% if conf.default_log is vyos_defined %} + counter log prefix "[ipv6-{{ (route_text)[:19] }}-default]" +{% endif %} } {% endfor %} {% endif %} diff --git a/data/templates/firewall/nftables-vrf-zones.j2 b/data/templates/firewall/nftables-vrf-zones.j2 deleted file mode 100644 index 3bce7312d..000000000 --- a/data/templates/firewall/nftables-vrf-zones.j2 +++ /dev/null @@ -1,17 +0,0 @@ -table inet vrf_zones { - # Map of interfaces and connections tracking zones - map ct_iface_map { - typeof iifname : ct zone - } - # Assign unique zones for each VRF - # Chain for inbound traffic - chain vrf_zones_ct_in { - type filter hook prerouting priority raw; policy accept; - counter ct original zone set iifname map @ct_iface_map - } - # Chain for locally-generated traffic - chain vrf_zones_ct_out { - type filter hook output priority raw; policy accept; - counter ct original zone set oifname map @ct_iface_map - } -} diff --git a/data/templates/firewall/nftables-zone.j2 b/data/templates/firewall/nftables-zone.j2 new file mode 100644 index 000000000..e78725079 --- /dev/null +++ b/data/templates/firewall/nftables-zone.j2 @@ -0,0 +1,77 @@ +{% macro zone_chains(zone, ipv6=False, state_policy=False) %} +{% set fw_name = 'ipv6_name' if ipv6 else 'name' %} +{% set suffix = '6' if ipv6 else '' %} + chain VYOS_ZONE_FORWARD { + type filter hook forward priority 1; policy accept; +{% if state_policy %} + jump VYOS_STATE_POLICY{{ suffix }} +{% endif %} +{% for zone_name, zone_conf in zone.items() %} +{% if 'local_zone' not in zone_conf %} + oifname { {{ zone_conf.interface | join(',') }} } counter jump VZONE_{{ zone_name }} +{% endif %} +{% endfor %} + } + chain VYOS_ZONE_LOCAL { + type filter hook input priority 1; policy accept; +{% if state_policy %} + jump VYOS_STATE_POLICY{{ suffix }} +{% endif %} +{% for zone_name, zone_conf in zone.items() %} +{% if 'local_zone' in zone_conf %} + counter jump VZONE_{{ zone_name }}_IN +{% endif %} +{% endfor %} + } + chain VYOS_ZONE_OUTPUT { + type filter hook output priority 1; policy accept; +{% if state_policy %} + jump VYOS_STATE_POLICY{{ suffix }} +{% endif %} +{% for zone_name, zone_conf in zone.items() %} +{% if 'local_zone' in zone_conf %} + counter jump VZONE_{{ zone_name }}_OUT +{% endif %} +{% endfor %} + } +{% for zone_name, zone_conf in zone.items() %} +{% if zone_conf.local_zone is vyos_defined %} + chain VZONE_{{ zone_name }}_IN { + iifname lo counter return +{% if zone_conf.from is vyos_defined %} +{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall[fw_name] is vyos_defined %} + iifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }} + iifname { {{ zone[from_zone].interface | join(",") }} } counter return +{% endfor %} +{% endif %} + {{ zone_conf | nft_default_rule('zone_' + zone_name, family) }} + } + chain VZONE_{{ zone_name }}_OUT { + oifname lo counter return +{% if zone_conf.from_local is vyos_defined %} +{% for from_zone, from_conf in zone_conf.from_local.items() if from_conf.firewall[fw_name] is vyos_defined %} + oifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }} + oifname { {{ zone[from_zone].interface | join(",") }} } counter return +{% endfor %} +{% endif %} + {{ zone_conf | nft_default_rule('zone_' + zone_name, family) }} + } +{% else %} + chain VZONE_{{ zone_name }} { + iifname { {{ zone_conf.interface | join(",") }} } counter {{ zone_conf | nft_intra_zone_action(ipv6) }} +{% if zone_conf.intra_zone_filtering is vyos_defined %} + iifname { {{ zone_conf.interface | join(",") }} } counter return +{% endif %} +{% if zone_conf.from is vyos_defined %} +{% for from_zone, from_conf in zone_conf.from.items() if from_conf.firewall[fw_name] is vyos_defined %} +{% if zone[from_zone].local_zone is not defined %} + iifname { {{ zone[from_zone].interface | join(",") }} } counter jump NAME{{ suffix }}_{{ from_conf.firewall[fw_name] }} + iifname { {{ zone[from_zone].interface | join(",") }} } counter return +{% endif %} +{% endfor %} +{% endif %} + {{ zone_conf | nft_default_rule('zone_' + zone_name, family) }} + } +{% endif %} +{% endfor %} +{% endmacro %}
\ No newline at end of file diff --git a/data/templates/firewall/nftables.j2 b/data/templates/firewall/nftables.j2 index 75800ee3d..833df3a67 100644 --- a/data/templates/firewall/nftables.j2 +++ b/data/templates/firewall/nftables.j2 @@ -3,6 +3,7 @@ {% import 'firewall/nftables-defines.j2' as group_tmpl %} {% import 'firewall/nftables-bridge.j2' as bridge_tmpl %} {% import 'firewall/nftables-offload.j2' as offload_tmpl %} +{% import 'firewall/nftables-zone.j2' as zone_tmpl %} flush chain raw vyos_global_rpfilter flush chain ip6 raw vyos_global_rpfilter @@ -43,9 +44,11 @@ table ip vyos_filter { {% set ns = namespace(sets=[]) %} {% if ipv4.forward is vyos_defined %} {% for prior, conf in ipv4.forward.items() %} -{% set def_action = conf.default_action %} chain VYOS_FORWARD_{{ prior }} { - type filter hook forward priority {{ prior }}; policy {{ def_action }}; + type filter hook forward priority {{ prior }}; policy accept; +{% if global_options.state_policy is vyos_defined %} + jump VYOS_STATE_POLICY +{% endif %} {% if conf.rule is vyos_defined %} {% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} {{ rule_conf | nft_rule('FWD', prior, rule_id) }} @@ -54,15 +57,18 @@ table ip vyos_filter { {% endif %} {% endfor %} {% endif %} + {{ conf | nft_default_rule('FWD-filter', 'ipv4') }} } {% endfor %} {% endif %} {% if ipv4.input is vyos_defined %} {% for prior, conf in ipv4.input.items() %} -{% set def_action = conf.default_action %} chain VYOS_INPUT_{{ prior }} { - type filter hook input priority {{ prior }}; policy {{ def_action }}; + type filter hook input priority {{ prior }}; policy accept; +{% if global_options.state_policy is vyos_defined %} + jump VYOS_STATE_POLICY +{% endif %} {% if conf.rule is vyos_defined %} {% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} {{ rule_conf | nft_rule('INP',prior, rule_id) }} @@ -71,15 +77,18 @@ table ip vyos_filter { {% endif %} {% endfor %} {% endif %} + {{ conf | nft_default_rule('INP-filter', 'ipv4') }} } {% endfor %} {% endif %} {% if ipv4.output is vyos_defined %} {% for prior, conf in ipv4.output.items() %} -{% set def_action = conf.default_action %} chain VYOS_OUTPUT_{{ prior }} { - type filter hook output priority {{ prior }}; policy {{ def_action }}; + type filter hook output priority {{ prior }}; policy accept; +{% if global_options.state_policy is vyos_defined %} + jump VYOS_STATE_POLICY +{% endif %} {% if conf.rule is vyos_defined %} {% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} {{ rule_conf | nft_rule('OUT', prior, rule_id) }} @@ -88,6 +97,7 @@ table ip vyos_filter { {% endif %} {% endfor %} {% endif %} + {{ conf | nft_default_rule('OUT-filter', 'ipv4') }} } {% endfor %} {% endif %} @@ -97,9 +107,8 @@ table ip vyos_filter { } {% if ipv4.prerouting is vyos_defined %} {% for prior, conf in ipv4.prerouting.items() %} -{% set def_action = conf.default_action %} chain VYOS_PREROUTING_{{ prior }} { - type filter hook prerouting priority {{ prior }}; policy {{ def_action }}; + type filter hook prerouting priority {{ prior }}; policy accept; {% if conf.rule is vyos_defined %} {% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} {{ rule_conf | nft_rule('PRE', prior, rule_id) }} @@ -108,7 +117,7 @@ table ip vyos_filter { {% endif %} {% endfor %} {% endif %} - {{ conf | nft_default_rule(prior) }} + {{ conf | nft_default_rule('PRE-filter', 'ipv4') }} } {% endfor %} {% endif %} @@ -124,7 +133,7 @@ table ip vyos_filter { {% endif %} {% endfor %} {% endif %} - {{ conf | nft_default_rule(name_text) }} + {{ conf | nft_default_rule(name_text, 'ipv4') }} } {% endfor %} {% endif %} @@ -152,6 +161,24 @@ table ip vyos_filter { {% endif %} {% endif %} {{ group_tmpl.groups(group, False, True) }} + +{% if zone is vyos_defined %} +{{ zone_tmpl.zone_chains(zone, False, global_options.state_policy is vyos_defined) }} +{% endif %} +{% if global_options.state_policy is vyos_defined %} + chain VYOS_STATE_POLICY { +{% if global_options.state_policy.established is vyos_defined %} + {{ global_options.state_policy.established | nft_state_policy('established') }} +{% endif %} +{% if global_options.state_policy.invalid is vyos_defined %} + {{ global_options.state_policy.invalid | nft_state_policy('invalid') }} +{% endif %} +{% if global_options.state_policy.related is vyos_defined %} + {{ global_options.state_policy.related | nft_state_policy('related') }} +{% endif %} + return + } +{% endif %} } {% if first_install is not vyos_defined %} @@ -168,9 +195,11 @@ table ip6 vyos_filter { {% set ns = namespace(sets=[]) %} {% if ipv6.forward is vyos_defined %} {% for prior, conf in ipv6.forward.items() %} -{% set def_action = conf.default_action %} chain VYOS_IPV6_FORWARD_{{ prior }} { - type filter hook forward priority {{ prior }}; policy {{ def_action }}; + type filter hook forward priority {{ prior }}; policy accept; +{% if global_options.state_policy is vyos_defined %} + jump VYOS_STATE_POLICY6 +{% endif %} {% if conf.rule is vyos_defined %} {% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} {{ rule_conf | nft_rule('FWD', prior, rule_id ,'ip6') }} @@ -179,15 +208,18 @@ table ip6 vyos_filter { {% endif %} {% endfor %} {% endif %} + {{ conf | nft_default_rule('FWD-filter', 'ipv6') }} } {% endfor %} {% endif %} {% if ipv6.input is vyos_defined %} {% for prior, conf in ipv6.input.items() %} -{% set def_action = conf.default_action %} chain VYOS_IPV6_INPUT_{{ prior }} { - type filter hook input priority {{ prior }}; policy {{ def_action }}; + type filter hook input priority {{ prior }}; policy accept; +{% if global_options.state_policy is vyos_defined %} + jump VYOS_STATE_POLICY6 +{% endif %} {% if conf.rule is vyos_defined %} {% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} {{ rule_conf | nft_rule('INP', prior, rule_id ,'ip6') }} @@ -196,15 +228,18 @@ table ip6 vyos_filter { {% endif %} {% endfor %} {% endif %} + {{ conf | nft_default_rule('INP-filter', 'ipv6') }} } {% endfor %} {% endif %} {% if ipv6.output is vyos_defined %} {% for prior, conf in ipv6.output.items() %} -{% set def_action = conf.default_action %} chain VYOS_IPV6_OUTPUT_{{ prior }} { - type filter hook output priority {{ prior }}; policy {{ def_action }}; + type filter hook output priority {{ prior }}; policy accept; +{% if global_options.state_policy is vyos_defined %} + jump VYOS_STATE_POLICY6 +{% endif %} {% if conf.rule is vyos_defined %} {% for rule_id, rule_conf in conf.rule.items() if rule_conf.disable is not vyos_defined %} {{ rule_conf | nft_rule('OUT', prior, rule_id ,'ip6') }} @@ -213,6 +248,7 @@ table ip6 vyos_filter { {% endif %} {% endfor %} {% endif %} + {{ conf | nft_default_rule('OUT-filter', 'ipv6') }} } {% endfor %} {% endif %} @@ -233,7 +269,7 @@ table ip6 vyos_filter { {% endif %} {% endfor %} {% endif %} - {{ conf | nft_default_rule(name_text, ipv6=True) }} + {{ conf | nft_default_rule(name_text, 'ipv6') }} } {% endfor %} {% endif %} @@ -261,6 +297,23 @@ table ip6 vyos_filter { {% endif %} {% endif %} {{ group_tmpl.groups(group, True, True) }} +{% if zone is vyos_defined %} +{{ zone_tmpl.zone_chains(zone, True, global_options.state_policy is vyos_defined) }} +{% endif %} +{% if global_options.state_policy is vyos_defined %} + chain VYOS_STATE_POLICY6 { +{% if global_options.state_policy.established is vyos_defined %} + {{ global_options.state_policy.established | nft_state_policy('established') }} +{% endif %} +{% if global_options.state_policy.invalid is vyos_defined %} + {{ global_options.state_policy.invalid | nft_state_policy('invalid') }} +{% endif %} +{% if global_options.state_policy.related is vyos_defined %} + {{ global_options.state_policy.related | nft_state_policy('related') }} +{% endif %} + return + } +{% endif %} } ## Bridge Firewall @@ -270,4 +323,5 @@ delete table bridge vyos_filter table bridge vyos_filter { {{ bridge_tmpl.bridge(bridge) }} {{ group_tmpl.groups(group, False, False) }} + } diff --git a/data/templates/firewall/upnpd.conf.j2 b/data/templates/firewall/upnpd.conf.j2 index e964fc696..616e8869f 100644 --- a/data/templates/firewall/upnpd.conf.j2 +++ b/data/templates/firewall/upnpd.conf.j2 @@ -3,13 +3,42 @@ # WAN network interface ext_ifname={{ wan_interface }} {% if wan_ip is vyos_defined %} + +# if the WAN network interface for IPv6 is different than for IPv4, +# set ext_ifname6 +#ext_ifname6=eth2 + # If the WAN interface has several IP addresses, you -# can specify the one to use below +# can specify the one to use below. +# Setting ext_ip is also useful in double NAT setup, you can declare here +# the public IP address. {% for addr in wan_ip %} ext_ip={{ addr }} {% endfor %} {% endif %} +{% if stun is vyos_defined %} +# WAN interface must have public IP address. Otherwise it is behind NAT +# and port forwarding is impossible. In some cases WAN interface can be +# behind unrestricted full-cone NAT 1:1 when all incoming traffic is NAT-ed and +# routed to WAN interfaces without any filtering. In this cases miniupnpd +# needs to know public IP address and it can be learnt by asking external +# server via STUN protocol. Following option enable retrieving external +# public IP address from STUN server and detection of NAT type. You need +# to specify also external STUN server in stun_host option below. +# This option is disabled by default. +ext_perform_stun=yes +# Specify STUN server, either hostname or IP address +# Some public STUN servers: +# stun.stunprotocol.org +# stun.sipgate.net +# stun.xten.com +# stun.l.google.com (on non standard port 19302) +ext_stun_host={{ stun.host }} +# Specify STUN UDP port, by default it is standard port 3478. +ext_stun_port={{ stun.port }} +{% endif %} + # LAN network interfaces IPs / networks {% if listen is vyos_defined %} # There can be multiple listening IPs for SSDP traffic, in that case @@ -20,6 +49,9 @@ ext_ip={{ addr }} # When MULTIPLE_EXTERNAL_IP is enabled, the external IP # address associated with the subnet follows. For example: # listening_ip=192.168.0.1/24 88.22.44.13 +# When MULTIPLE_EXTERNAL_IP is disabled, you can list associated network +# interfaces (for bridges) +# listening_ip=bridge0 em0 wlan0 {% for addr in listen %} {% if addr | is_ipv4 %} listening_ip={{ addr }} @@ -65,6 +97,18 @@ min_lifetime={{ pcp_lifetime.min }} {% endif %} {% endif %} +# table names for netfilter nft. Default is "filter" for both +#upnp_table_name= +#upnp_nat_table_name= +# chain names for netfilter and netfilter nft +# netfilter : default are MINIUPNPD, MINIUPNPD, MINIUPNPD-POSTROUTING +# netfilter nft : default are miniupnpd, prerouting_miniupnpd, postrouting_miniupnpd +#upnp_forward_chain=forwardUPnP +#upnp_nat_chain=UPnP +#upnp_nat_postrouting_chain=UPnP-Postrouting + +# Lease file location +lease_file=/config/upnp.leases # To enable the next few runtime options, see compile time # ENABLE_MANUFACTURER_INFO_CONFIGURATION (config.h) @@ -89,6 +133,11 @@ model_description=Vyos open source enterprise router/firewall operating system # Model URL, default is URL of OS vendor model_url=https://vyos.io/ +# Bitrates reported by daemon in bits per second +# by default miniupnpd tries to get WAN interface speed +#bitrate_up=1000000 +#bitrate_down=10000000 + {% if secure_mode is vyos_defined %} # Secure Mode, UPnP clients can only add mappings to their own IP secure_mode=yes @@ -108,6 +157,10 @@ secure_mode=no # Report system uptime instead of daemon uptime system_uptime=yes +# Notify interval in seconds. default is 30 seconds. +#notify_interval=240 +notify_interval=60 + # Unused rules cleaning. # never remove any rule before this threshold for the number # of redirections is exceeded. default to 20 @@ -116,25 +169,46 @@ clean_ruleset_threshold=10 # a 600 seconds (10 minutes) interval makes sense clean_ruleset_interval=600 +############################################################################ +## The next 5 config parameters (packet_log, anchor, queue, tag, quickrules) +## are specific to BSD's pf(4) packet filter and hence cannot be enabled in +## VyOS. +# Log packets in pf (default is no) +#packet_log=no + # Anchor name in pf (default is miniupnpd) -# Something wrong with this option "anchor", comment it out -# vyos@r14# miniupnpd -vv -f /run/upnp/miniupnp.conf -# invalid option in file /run/upnp/miniupnp.conf line 74 : anchor=VyOS -#anchor=VyOS +#anchor=miniupnpd -uuid={{ uuid }} +# ALTQ queue in pf +# Filter rules must be used for this to be used. +# compile with PF_ENABLE_FILTER_RULES (see config.h file) +#queue=queue_name1 -# Lease file location -lease_file=/config/upnp.leases +# Tag name in pf +#tag=tag_name1 + +# Make filter rules in pf quick or not. default is yes +# active when compiled with PF_ENABLE_FILTER_RULES (see config.h file) +#quickrules=no +## +## End of pf(4)-specific configuration not to be set in VyOS. +############################################################################ + +# UUID, generate your own UUID with "make genuuid" +uuid={{ uuid }} # Daemon's serial and model number when reporting to clients # (in XML description) #serial=12345678 #model_number=1 +# If compiled with IGD_V2 defined, force reporting IGDv1 in rootDesc (default +# is no) +#force_igd_desc_v1=no + {% if rule is vyos_defined %} -# UPnP permission rules -# (allow|deny) (external port range) IP/mask (internal port range) +# UPnP permission rules (also enforced for NAT-PMP and PCP) +# (allow|deny) (external port range) IP/mask (internal port range) (optional regex filter) # A port range is <min port>-<max port> or <port> if there is only # one port in the range. # IP/mask format must be nnn.nnn.nnn.nnn/nn @@ -151,25 +225,3 @@ lease_file=/config/upnp.leases {% endif %} {% endfor %} {% endif %} - -{% if stun is vyos_defined %} -# WAN interface must have public IP address. Otherwise it is behind NAT -# and port forwarding is impossible. In some cases WAN interface can be -# behind unrestricted NAT 1:1 when all incoming traffic is NAT-ed and -# routed to WAN interfaces without any filtering. In this cases miniupnpd -# needs to know public IP address and it can be learnt by asking external -# server via STUN protocol. Following option enable retrieving external -# public IP address from STUN server and detection of NAT type. You need -# to specify also external STUN server in stun_host option below. -# This option is disabled by default. -ext_perform_stun=yes -# Specify STUN server, either hostname or IP address -# Some public STUN servers: -# stun.stunprotocol.org -# stun.sipgate.net -# stun.xten.com -# stun.l.google.com (on non standard port 19302) -ext_stun_host={{ stun.host }} -# Specify STUN UDP port, by default it is standard port 3478. -ext_stun_port={{ stun.port }} -{% endif %} |