From 7331fa9475a7427addc179b91613d4386f0b5b63 Mon Sep 17 00:00:00 2001
From: benyamin-codez <115509179+benyamin-codez@users.noreply.github.com>
Date: Thu, 14 Aug 2025 05:28:41 +1000
Subject: [PATCH] dns/bind: Fixup and feature expansion
a) Fixes zone_test
b) Fixes command truncation in grid-primary-domains
c) General tab help expansion and reformatting
d) General tab option grouping
e) Converts NetworkType to ACLs where BIND uses Address Match Lists
f) Reformats named.conf (spacing and layout)
g) Adds listen-on-v6 { none; } when IPv6 is disabled (likely superflous)
h) Adds other rate-limiting options
i) Adds recursion no; option for authoritative servers
j) Adds allow-query-cache option as this also controls recursion
k) Adds global forward only option to forwarders
l) Adds forward only option to forward zones
m) Edit Forward zone dialog help expansion and reformatting
Signed-off-by: benyamin-codez <115509179+benyamin-codez@users.noreply.github.com>
---
.../forms/dialogEditBindForwardDomain.xml | 31 +-
.../OPNsense/Bind/forms/general.xml | 338 ++++++++++++++----
.../mvc/app/models/OPNsense/Bind/Domain.xml | 4 +
.../mvc/app/models/OPNsense/Bind/General.xml | 244 +++++++++----
.../mvc/app/views/OPNsense/Bind/general.volt | 7 +-
.../templates/OPNsense/Bind/named.conf | 149 ++++++--
6 files changed, 605 insertions(+), 168 deletions(-)
diff --git a/dns/bind/src/opnsense/mvc/app/controllers/OPNsense/Bind/forms/dialogEditBindForwardDomain.xml b/dns/bind/src/opnsense/mvc/app/controllers/OPNsense/Bind/forms/dialogEditBindForwardDomain.xml
index 4ca30f87c6..18a114dfb3 100644
--- a/dns/bind/src/opnsense/mvc/app/controllers/OPNsense/Bind/forms/dialogEditBindForwardDomain.xml
+++ b/dns/bind/src/opnsense/mvc/app/controllers/OPNsense/Bind/forms/dialogEditBindForwardDomain.xml
@@ -9,14 +9,39 @@
domain.domainnametext
- Set the name for this zone. Both forward and reverse zones may be specified, i.e. example.com or 0.168.192.in-addr.arpa.
+ Both forward and reverse zones may be specified.
+ Examples include:
+ example.com
+ 0.168.192.in-addr.arpa
+ ]]>
+
+
+ domain.forwardonly
+
+ checkbox
+ The default is to attempt forwarders first and only perform
+ recursive lookups if forwarding fails. This setting is only
+ meaningful if the list of forwarders is not empty.
+ Can be used to override global forwarding behaviour for this
+ domain by specifying the same servers below.
+ This directive is explictily set to either forward only; or
+ forward first; to avoid any furtherance of doubt.
+ ]]>domain.forwardserver
-
+
select_multipletrue
- Set the IP address of server to forward requests to.
+ forward queries to for this domain.
+ Used to override global forwarders for this domain.
+ ]]>
diff --git a/dns/bind/src/opnsense/mvc/app/controllers/OPNsense/Bind/forms/general.xml b/dns/bind/src/opnsense/mvc/app/controllers/OPNsense/Bind/forms/general.xml
index 23e9c92026..cf3d33089c 100644
--- a/dns/bind/src/opnsense/mvc/app/controllers/OPNsense/Bind/forms/general.xml
+++ b/dns/bind/src/opnsense/mvc/app/controllers/OPNsense/Bind/forms/general.xml
@@ -5,33 +5,52 @@
checkboxThis will activate the BIND daemon.
+
+ header
+
+ general.disablev6checkbox
- This will run BIND in IPv4-only mode.
+ This will cause BIND to run in IPv4-only mode.general.listenv4
-
-
+
select_multiple
- true
- Set the IPv4 addresses the service should listen to.
+ The default is all IPv4 addresses on the host, i.e. { any; }.
+ ]]>general.listenv6
-
-
+
select_multiple
- true
- Set the IPv6 addresses the service should listen to.
+ The default is all IPv6 addresses on the host, i.e. { any; } except when IPv6 is disabled which uses { none; }.
+ ]]>general.port
-
+
text
- Set the port the service should listen to.
+ Set the port the BIND service should listen on.
+
+
+ header
+
+
+
+ general.allowquery
+
+ select_multiple
+ The default is { any; }.
+ ]]>general.querysource
@@ -47,6 +66,74 @@
trueSpecify the IPv6 address used as a source for outbound queries.
+
+ header
+
+
+
+ general.enablerecursion
+
+ checkbox
+ This will enable recursive resolution (default). Disable for public authoritative DNS servers.
+
+
+ general.recursionallowedacls
+
+ select_multiple
+ For public authoritative DNS servers, recursion should be disabled and this field left empty.
+ For private recursive DNS servers, this is usually an ACL representing your local LAN.
+ When recursion is enabled and no ACL is defined here or for allow-query-cache or allow-query, the
+ builtin { localnets; localhost; } address list is used. Otherwise this field will default to the value
+ found in allow-query-cache, or failing that, allow-query.
+ ]]>
+
+
+ general.allowcachequeries
+
+ true
+ select_multiple
+ For public authoritative DNS servers, recursion should be disabled, and this field defaults to using {none;}.
+ For private recursive DNS servers, use this field to override the defaults.
+ When recursion is enabled and allow-recursion has an ACL set, the default will be the same ACL.
+ Otherwise if allow-recursion has no ACL set, the default will be the { localnets; localhost; } address list.
+ ]]>
+
+
+ general.forwardonly
+
+ checkbox
+ true
+ The default is to attempt forwarders first and perform recursive lookups if forwarding fails.
+ Only meaningful if the list of forwarders is not empty.
+ ]]>
+
+
+ general.forwarders
+
+
+ select_multiple
+ true
+ Set any combination of IPv4 and IPv6 addresses to forward queries to when the answer is unknown.
+
+
+ header
+
+
+
+ general.allowtransfer
+
+ select_multiple
+ The default is { any; }.
+ ]]>
+ general.transfersource
@@ -62,75 +149,73 @@
Specify the IPv6 address used as a source for zone transfers.
- general.forwarders
-
-
- select_multiple
- true
- Set one or more hosts to send your DNS queries if the request is unknown.
+ header
+
+
+
+ general.dnssecvalidation
+
+ dropdown
+ Set to "Auto" to use the default trust anchor for the DNS root zone.
+ The "yes" and "trust-anchors" options are not supported.
+ Consider legacy AAAA record filtering needs before enabling this feature as
+ signed responses will not have AAAA records filtered when this is set to "Auto".
+ ]]>
+
+
+ header
+
general.filteraaaav4checkbox
- This will filter AAAA records on IPv4 Clients. Set "DNSSEC Validation" to "No" and AAAA records will be omitted even if they are signed.
+ Set "DNSSEC Validation" to "No" and AAAA records will be omitted even if they are signed.
+ ]]>general.filteraaaav6checkbox
- This will filter AAAA records on IPv6 Clients. Set "DNSSEC Validation" to "No" and AAAA records will be omitted even if they are signed.
+ Set "DNSSEC Validation" to "No" and AAAA records will be omitted even if they are signed.
+ ]]>general.filteraaaaacl
-
-
+
select_multiple
- true
- Specifies a list of client addresses for which AAAA filtering is to be applied.
+ Set ACLs for which AAAA filtering is to be applied. The default is { any; }.
+
+
+ header
+
general.logsizetext
- Set the amount how big a logfile can growth. For Query and Blocked logs.
+ Set the maximum logfile size. For Query and Blocked logs.general.general_log_leveldropdown
- Select General Log level. Log levels are listed in the order of increasing verbosity. Setting a certain log level will cause all messages of the specified and more severe log levels to be logged.
-
-
- general.maxcachesize
-
- text
- How much memory in percent the cache can use from the system. Default is 80%.
+ Setting a certain log level will cause all messages of the specified and more severe log levels to be logged.
+ ]]>
- general.recursion
-
- select_multiple
- Define an ACL where you allow which clients can resolve via this service. Usually use your local LAN.
-
-
- general.allowtransfer
-
- select_multiple
- Define the ACLs where you allow which server can retrieve zones.
-
-
- general.allowquery
-
- select_multiple
- Define the ACLs where you allow which client are allowed to query this server.
-
-
- general.dnssecvalidation
-
- dropdown
- Default is "No". Set to "Auto" to use the static trust anchor configuration by the system.
+ header
+
+ truegeneral.hidehostname
@@ -146,6 +231,18 @@
trueThis will hide the local BIND version in DNS queries.
+
+ header
+
+ true
+
+
+ general.maxcachesize
+
+ text
+ true
+ How much memory in percent the cache can use from the system. The default is 80%.
+ general.disableprefetch
@@ -153,32 +250,147 @@
trueThis will disable prefetching of domains before they time out.
+
+ header
+
+ true
+ general.enableratelimitingcheckboxtrue
- This will enable rate-limiting for DNS replies.
+ This will enable rate-limiting for DNS responses.
- general.ratelimitcount
-
+ general.ratelimitrespps
+
texttrue
- Set how many replies per second are allowed.
+ The default is 0 or no limit.
+ ]]>
- general.ratelimitexcept
-
-
+ general.ratelimitwindow
+
+ text
+ true
+ Set the number of second during which responses are tracked. The default is 15 seconds.
+
+
+ general.ratelimitexempt
+
select_multiple
- truetrue
- Except a list of IPs from rate-limiting like ::1
+ Set ACLs where rate-limiting should not apply.
+
+
+ general.ratelimitipv4prefixlength
+
+ text
+ true
+ Set the number of bits of the address block. Used to distinquish clients into a rate-limited group. The default is 24.
+
+
+ general.ratelimitipv6prefixlength
+
+ text
+ true
+ Set the number of bits of the address block. Used to distinquish clients into a rate-limited group. The default is 56.
+
+
+ general.ratelimitnodataps
+
+ text
+ true
+ The default is equal to the Responses Per Second value.
+ ]]>
+
+
+ general.ratelimitnxdomsps
+
+ text
+ true
+ The default is equal to the Responses Per Second value.
+ ]]>
+
+
+ general.ratelimitrefsps
+
+ text
+ true
+ The default is equal to the Responses Per Second value.
+ ]]>
+
+
+ general.ratelimiterrsps
+
+ text
+ true
+ The default is equal to the Responses Per Second value.
+ ]]>
+
+
+ general.ratelimitallps
+
+ text
+ true
+ If used, this should be set to 4 times the size of other per second limits.
+ ]]>
+
+
+ general.ratelimitslip
+
+ text
+ true
+ Set how many responses to "slip", reducing the use of forged source addresses in attacks. The default is 2.
+
+
+ general.ratelimitscale
+
+ text
+ true
+ The formula is (qps-scale/total-query-rate)*responses-per-second to produce the new value.
+ ]]>
+
+
+ general.ratelimitmaxtbl
+
+ text
+ true
+ Set the maximum number of table entries used to track requests and rate-limit responses. The default is 20,000.
+
+
+ general.ratelimitmintbl
+
+ text
+ true
+ Set the minimum number of table entries used to track requests and rate-limit responses. The default is 500.
+
+
+ general.ratelimittry
+
+ checkbox
+ true
+ Enable to test rate-limiting parameters without actually dropping any requests.header
-
+
true
diff --git a/dns/bind/src/opnsense/mvc/app/models/OPNsense/Bind/Domain.xml b/dns/bind/src/opnsense/mvc/app/models/OPNsense/Bind/Domain.xml
index 6743b66ae4..13d3c9af44 100644
--- a/dns/bind/src/opnsense/mvc/app/models/OPNsense/Bind/Domain.xml
+++ b/dns/bind/src/opnsense/mvc/app/models/OPNsense/Bind/Domain.xml
@@ -21,6 +21,10 @@
Y
+
+ 0
+ Y
+ Y
diff --git a/dns/bind/src/opnsense/mvc/app/models/OPNsense/Bind/General.xml b/dns/bind/src/opnsense/mvc/app/models/OPNsense/Bind/General.xml
index 238c9dc248..08e6945eb4 100644
--- a/dns/bind/src/opnsense/mvc/app/models/OPNsense/Bind/General.xml
+++ b/dns/bind/src/opnsense/mvc/app/models/OPNsense/Bind/General.xml
@@ -15,16 +15,40 @@
1Y
-
- 0.0.0.0
- Y
- Y
+
+
+
+ OPNsense.Bind.Acl
+ acls.acl
+ name
+
+
+ Y
-
- ::
- Y
- Y
+
+
+
+ OPNsense.Bind.Acl
+ acls.acl
+ name
+
+
+ Y
+
+ 53530
+ Y
+
+
+
+
+ OPNsense.Bind.Acl
+ acls.acl
+ name
+
+
+ Y
+ ipv4N
@@ -33,6 +57,49 @@
ipv6N
+
+ 1
+ Y
+
+
+
+
+ OPNsense.Bind.Acl
+ acls.acl
+ name
+
+
+ Y
+ Choose an ACL.
+
+
+
+
+ OPNsense.Bind.Acl
+ acls.acl
+ name
+
+
+ Y
+ Choose an ACL.
+
+
+ 0
+ Y
+
+
+ Y
+
+
+
+
+ OPNsense.Bind.Acl
+ acls.acl
+ name
+
+
+ Y
+ ipv4N
@@ -41,13 +108,14 @@
ipv6N
-
- 53530
+
+
+ No
+ Auto
+
+ noY
-
-
- Y
-
+
0Y
@@ -56,8 +124,15 @@
0Y
-
- Y
+
+
+
+ OPNsense.Bind.Acl
+ acls.acl
+ name
+
+
+ Y5
@@ -79,52 +154,6 @@
Yinfo
-
- 80
- Y
- 1
- 99
- Choose a value between 1 and 99.
-
-
-
-
- OPNsense.Bind.Acl
- acls.acl
- name
-
-
- Y
- Choose an ACL.
-
-
-
-
- OPNsense.Bind.Acl
- acls.acl
- name
-
-
- Y
-
-
-
-
- OPNsense.Bind.Acl
- acls.acl
- name
-
-
- Y
-
-
-
- No
- Auto
-
- no
- Y
- 0Y
@@ -133,6 +162,13 @@
0Y
+
+ 80
+ Y
+ 1
+ 99
+ Choose a value between 1 and 99.
+ 0Y
@@ -141,16 +177,86 @@
0Y
-
+ 11000Choose a value between 1 and 1000.
-
-
- 0.0.0.0,::
- Y
- Y
-
+
+
+ 1
+ 3600
+ Choose a value between 1 and 3600.
+
+
+
+
+ OPNsense.Bind.Acl
+ acls.acl
+ name
+
+
+ Y
+ Choose an ACL.
+
+
+ 1
+ 32
+ Choose a value between 1 and 32.
+
+
+ 1
+ 128
+ Choose a value between 1 and 128.
+
+
+ 1
+ 1000
+ Choose a value between 1 and 1000.
+
+
+ 1
+ 1000
+ Choose a value between 1 and 1000.
+
+
+ 1
+ 1000
+ Choose a value between 1 and 1000.
+
+
+ 1
+ 1000
+ Choose a value between 1 and 1000.
+
+
+ 1
+ 1000
+ Choose a value between 1 and 1000.
+
+
+ 0
+ 10
+ Choose a value between 0 and 10.
+
+
+ 1
+ 1000
+ Choose a value between 1 and 1000.
+
+
+ 1
+ 100000
+ Choose a value between 1 and 100,000.
+
+
+ 1
+ 100000
+ Choose a value between 1 and 100,000.
+
+
+ 0
+ N
+ Yhmac-sha256
diff --git a/dns/bind/src/opnsense/mvc/app/views/OPNsense/Bind/general.volt b/dns/bind/src/opnsense/mvc/app/views/OPNsense/Bind/general.volt
index 30d3fcc1d3..4f52452f9c 100644
--- a/dns/bind/src/opnsense/mvc/app/views/OPNsense/Bind/general.volt
+++ b/dns/bind/src/opnsense/mvc/app/views/OPNsense/Bind/general.volt
@@ -99,8 +99,8 @@
{{ lang._('Retry') }}
{{ lang._('Expire') }}
{{ lang._('Negative TTL') }}
+
{{ lang._('Commands') }}
{{ lang._('ID') }}
-
{{ lang._('Commands') }}
@@ -200,6 +200,7 @@
{{ lang._('Enabled') }}
{{ lang._('Zone') }}
+
{{ lang._('Forward Only') }}
{{ lang._('Forwarder IPs') }}
{{ lang._('ID') }}
{{ lang._('Commands') }}
@@ -427,8 +428,8 @@ $(document).ready(function() {
}).on("loaded.rs.jquery.bootgrid", function(e) {
// Checkzone button
$("#grid-primary-domains").find(".command-bind-checkzone").off("click").on("click", function(ev) {
- if (!$(this).closest("tr").hasClass("text-muted")) {
- let zonename = $(this).closest('tr').find('td.zonename').text();
+ if (!$(this).closest(".tabulator-row").hasClass("text-muted")) {
+ let zonename = $(this).closest(".tabulator-row").find("[tabulator-field='domainname']").text();
zone_test(zonename);
} else {
BootstrapDialog.show({
diff --git a/dns/bind/src/opnsense/service/templates/OPNsense/Bind/named.conf b/dns/bind/src/opnsense/service/templates/OPNsense/Bind/named.conf
index 9196b5de3e..83399f9389 100644
--- a/dns/bind/src/opnsense/service/templates/OPNsense/Bind/named.conf
+++ b/dns/bind/src/opnsense/service/templates/OPNsense/Bind/named.conf
@@ -10,28 +10,47 @@ acl "{{ acl_list.name }}" { {{ acl_list.networks.replace(',', '; ') }}; };
options {
- directory "/usr/local/etc/namedb/working";
- pid-file "/var/run/named/pid";
- dump-file "/var/dump/named_dump.db";
- statistics-file "/var/stats/named.stats";
+ directory "/usr/local/etc/namedb/working";
+ pid-file "/var/run/named/pid";
+ dump-file "/var/dump/named_dump.db";
+ statistics-file "/var/stats/named.stats";
-{% for listenv4 in OPNsense.bind.general.listenv4.split(',') %}
- listen-on port {{ OPNsense.bind.general.port }} { {% if listenv4 == '0.0.0.0' %}any{% else %}{{ listenv4 }}{% endif %}; };
-{% endfor %}
-{% for listenv6 in OPNsense.bind.general.listenv6.split(',') %}
- listen-on-v6 port {{ OPNsense.bind.general.port }} { {% if listenv6 == '::' %}any{% else %}{{ listenv6 }}{% endif %}; };
-{% endfor %}
+{% if helpers.exists('OPNsense.bind.general.listenv4') and OPNsense.bind.general.listenv4 != '' %}
+ listen-on port {{ OPNsense.bind.general.port }} {
+{% for acl in OPNsense.bind.general.listenv4.split(',') %}
+{% set listenv4_acl = helpers.getUUID(acl) %}
+ {{ listenv4_acl.name }};
+{% endfor %}
+ };
+{% else %}
+ listen-on port {{ OPNsense.bind.general.port }} { any; }
+{% endif %}
+
+{% if helpers.exists('OPNsense.bind.general.disablev6') and OPNsense.bind.general.disablev6 != '1' %}
+{% if helpers.exists('OPNsense.bind.general.listenv6') and OPNsense.bind.general.listenv6 != '' %}
+ listen-on-v6 port {{ OPNsense.bind.general.port }} {
+{% for acl in OPNsense.bind.general.listenv6.split(',') %}
+{% set listenv6_acl = helpers.getUUID(acl) %}
+ {{ listenv6_acl.name }};
+{% endfor %}
+ };
+{% else %}
+ listen-on-v6 port {{ OPNsense.bind.general.port }} { any; }
+{% endif %}
+{% else %}
+ listen-on-v6 { none; };
+{% endif %}
{% if helpers.exists('OPNsense.bind.general.querysource') and OPNsense.bind.general.querysource != '' %}
- query-source {{ OPNsense.bind.general.querysource }};
+ query-source {{ OPNsense.bind.general.querysource }};
{% endif -%}
{% if helpers.exists('OPNsense.bind.general.querysourcev6') and OPNsense.bind.general.querysourcev6 != '' %}
- query-source-v6 {{ OPNsense.bind.general.querysourcev6 }};
+ query-source-v6 {{ OPNsense.bind.general.querysourcev6 }};
{% endif -%}
{% if helpers.exists('OPNsense.bind.general.transfersource') and OPNsense.bind.general.transfersource != '' %}
- transfer-source {{ OPNsense.bind.general.transfersource }};
+ transfer-source {{ OPNsense.bind.general.transfersource }};
{% endif -%}
{% if helpers.exists('OPNsense.bind.general.transfersourcev6') and OPNsense.bind.general.transfersourcev6 != '' %}
@@ -39,21 +58,36 @@ options {
{% endif -%}
{% if helpers.exists('OPNsense.bind.general.forwarders') and OPNsense.bind.general.forwarders != '' %}
- forwarders { {{ OPNsense.bind.general.forwarders.replace(',', '; ') }}; };
+{% if helpers.exists('OPNsense.bind.general.forwardonly') and OPNsense.bind.general.forwardonly == '1' %}
+ forward only
+{% endif -%}
+ forwarders { {{ OPNsense.bind.general.forwarders.replace(',', '; ') }}; };
{% endif -%}
{% if helpers.exists('OPNsense.bind.dnsbl.enabled') and OPNsense.bind.dnsbl.enabled == '1' %}
- response-policy { {% if helpers.exists('OPNsense.bind.dnsbl.type') and OPNsense.bind.dnsbl.type != '' %}zone "whitelist.localdomain"; zone "blacklist.localdomain";{% endif %}{% if helpers.exists('OPNsense.bind.dnsbl.forcesafegoogle') and OPNsense.bind.dnsbl.forcesafegoogle == '1' %}zone "rpzgoogle";{% endif %}{% if helpers.exists('OPNsense.bind.dnsbl.forcesafeduckduckgo') and OPNsense.bind.dnsbl.forcesafeduckduckgo == '1' %}zone "rpzduckduckgo";{% endif %}{% if helpers.exists('OPNsense.bind.dnsbl.forcesafeyoutube') and OPNsense.bind.dnsbl.forcesafeyoutube == '1' %}zone "rpzyoutube";{% endif %}{% if helpers.exists('OPNsense.bind.dnsbl.forcestrictbing') and OPNsense.bind.dnsbl.forcestrictbing == '1' %}zone "rpzbing";{% endif %} };
-{% endif %}
+ response-policy { {% if helpers.exists('OPNsense.bind.dnsbl.type') and OPNsense.bind.dnsbl.type != '' %}zone "whitelist.localdomain"; zone "blacklist.localdomain";{% endif %}{% if helpers.exists('OPNsense.bind.dnsbl.forcesafegoogle') and OPNsense.bind.dnsbl.forcesafegoogle == '1' %}zone "rpzgoogle";{% endif %}{% if helpers.exists('OPNsense.bind.dnsbl.forcesafeduckduckgo') and OPNsense.bind.dnsbl.forcesafeduckduckgo == '1' %}zone "rpzduckduckgo";{% endif %}{% if helpers.exists('OPNsense.bind.dnsbl.forcesafeyoutube') and OPNsense.bind.dnsbl.forcesafeyoutube == '1' %}zone "rpzyoutube";{% endif %}{% if helpers.exists('OPNsense.bind.dnsbl.forcestrictbing') and OPNsense.bind.dnsbl.forcestrictbing == '1' %}zone "rpzbing";{% endif %} };
+{% endif -%}
-{% if helpers.exists('OPNsense.bind.general.recursion') and OPNsense.bind.general.recursion != '' %}
+{% if helpers.exists('OPNsense.bind.general.enablerecursion') and OPNsense.bind.general.enablerecursion == '1' %}
recursion yes;
+{% if helpers.exists('OPNsense.bind.general.recursionallowedacls') and OPNsense.bind.general.recursionallowedacls != '' %}
allow-recursion {
-{% for acl in OPNsense.bind.general.recursion.split(',') %}
-{% set recursion_acl = helpers.getUUID(acl) %}
- {{ recursion_acl.name }};
+{% for acl in OPNsense.bind.general.recursionallowedacls.split(',') %}
+{% set recursionallowedacls_acl = helpers.getUUID(acl) %}
+ {{ recursionallowedacls_acl.name }};
+{% endfor %}
+ };
+{% endif %}
+{% if helpers.exists('OPNsense.bind.general.allowcachequeries') and OPNsense.bind.general.allowcachequeries != '' %}
+ allow-query-cache {
+{% for acl in OPNsense.bind.general.allowcachequeries.split(',') %}
+{% set allowcachequeries_acl = helpers.getUUID(acl) %}
+ {{ allowcachequeries_acl.name }};
{% endfor %}
};
+{% endif %}
+{% else %}
+ recursion no;
{% endif %}
{% if helpers.exists('OPNsense.bind.general.allowtransfer') and OPNsense.bind.general.allowtransfer != '' %}
@@ -75,26 +109,70 @@ options {
{% endif %}
{% if helpers.exists('OPNsense.bind.general.maxcachesize') and OPNsense.bind.general.maxcachesize != '' %}
- max-cache-size {{ OPNsense.bind.general.maxcachesize }}%;
+ max-cache-size {{ OPNsense.bind.general.maxcachesize }}%;
{% endif %}
{% if helpers.exists('OPNsense.bind.general.dnssecvalidation') and OPNsense.bind.general.dnssecvalidation != '' %}
- dnssec-validation {{ OPNsense.bind.general.dnssecvalidation }};
+ dnssec-validation {{ OPNsense.bind.general.dnssecvalidation }};
{% endif %}
{% if helpers.exists('OPNsense.bind.general.hidehostname') and OPNsense.bind.general.hidehostname == '1' %}
- hostname none;
+ hostname none;
{% endif %}
{% if helpers.exists('OPNsense.bind.general.hideversion') and OPNsense.bind.general.hideversion == '1' %}
- version none;
+ version none;
{% endif %}
{% if helpers.exists('OPNsense.bind.general.disableprefetch') and OPNsense.bind.general.disableprefetch == '1' %}
prefetch 0;
{% endif %}
{% if helpers.exists('OPNsense.bind.general.enableratelimiting') and OPNsense.bind.general.enableratelimiting == '1' %}
-{% if helpers.exists('OPNsense.bind.general.ratelimitcount') and OPNsense.bind.general.ratelimitcount != '' %}
+{% if helpers.exists('OPNsense.bind.general.ratelimitrespps') and OPNsense.bind.general.ratelimitrespps != '' %}
rate-limit {
- responses-per-second {{ OPNsense.bind.general.ratelimitcount }};
-{% if helpers.exists('OPNsense.bind.general.ratelimitexcept') and OPNsense.bind.general.ratelimitexcept != '' %}
- exempt-clients { {{ OPNsense.bind.general.ratelimitexcept.replace(',', '; ') }}; };
+ responses-per-second {{ OPNsense.bind.general.ratelimitrespps }};
+{% if helpers.exists('OPNsense.bind.general.ratelimitwindow') and OPNsense.bind.general.ratelimitwindow != '' %}
+ window {{ OPNsense.bind.general.ratelimitwindow }};
+{% endif %}
+{% if helpers.exists('OPNsense.bind.general.ratelimitipv4prefixlength') and OPNsense.bind.general.ratelimitipv4prefixlength != '' %}
+ ipv4-prefix-length {{ OPNsense.bind.general.ratelimitipv4prefixlength }};
+{% endif %}
+{% if helpers.exists('OPNsense.bind.general.ratelimitipv6prefixlength') and OPNsense.bind.general.ratelimitipv6prefixlength != '' %}
+ ipv6-prefix-length {{ OPNsense.bind.general.ratelimitipv6prefixlength }};
+{% endif %}
+{% if helpers.exists('OPNsense.bind.general.ratelimitnodataps') and OPNsense.bind.general.ratelimitnodataps != '' %}
+ nodata-per-second {{ OPNsense.bind.general.ratelimitnodataps }};
+{% endif %}
+{% if helpers.exists('OPNsense.bind.general.ratelimitnxdomsps') and OPNsense.bind.general.ratelimitnxdomsps != '' %}
+ nxdomains-per-second {{ OPNsense.bind.general.ratelimitnxdomsps }};
+{% endif %}
+{% if helpers.exists('OPNsense.bind.general.ratelimitrefsps') and OPNsense.bind.general.ratelimitrefsps != '' %}
+ referrals-per-second {{ OPNsense.bind.general.ratelimitrefsps }};
+{% endif %}
+{% if helpers.exists('OPNsense.bind.general.ratelimiterrsps') and OPNsense.bind.general.ratelimiterrsps != '' %}
+ errors-per-second {{ OPNsense.bind.general.ratelimiterrsps }};
+{% endif %}
+{% if helpers.exists('OPNsense.bind.general.ratelimitallps') and OPNsense.bind.general.ratelimitallps != '' %}
+ all-per-second {{ OPNsense.bind.general.ratelimitallps }};
+{% endif %}
+{% if helpers.exists('OPNsense.bind.general.ratelimitslip') and OPNsense.bind.general.ratelimitslip != '' %}
+ slip {{ OPNsense.bind.general.ratelimitslip }};
+{% endif %}
+{% if helpers.exists('OPNsense.bind.general.ratelimitscale') and OPNsense.bind.general.ratelimitscale != '' %}
+ qps-scale {{ OPNsense.bind.general.ratelimitscale }};
+{% endif %}
+{% if helpers.exists('OPNsense.bind.general.ratelimitmaxtbl') and OPNsense.bind.general.ratelimitmaxtbl != '' %}
+ max-table-size {{ OPNsense.bind.general.ratelimitmaxtbl }};
+{% endif %}
+{% if helpers.exists('OPNsense.bind.general.ratelimitmintbl') and OPNsense.bind.general.ratelimitmintbl != '' %}
+ min-table-size {{ OPNsense.bind.general.ratelimitmintbl }};
+{% endif %}
+{% if helpers.exists('OPNsense.bind.general.ratelimitexempt') and OPNsense.bind.general.ratelimitexempt != '' %}
+ exempt-clients {
+{% for acl in OPNsense.bind.general.ratelimitexempt.split(',') %}
+{% set ratelimitexempt_acl = helpers.getUUID(acl) %}
+ {{ ratelimitexempt_acl.name }};
+{% endfor %}
+ };
+{% endif %}
+{% if helpers.exists('OPNsense.bind.general.ratelimittry') and OPNsense.bind.general.ratelimittry != '' %}
+ log-only {{ OPNsense.bind.general.ratelimittry }};
{% endif %}
};
{% endif %}
@@ -104,8 +182,9 @@ options {
{% if helpers.exists('OPNsense.bind.general.rndcalgo') and helpers.exists('OPNsense.bind.general.rndcsecret') %}
key "rndc-key" {
algorithm "{{ OPNsense.bind.general.rndcalgo }}";
- secret "{{ OPNsense.bind.general.rndcsecret }}";
+ secret "{{ OPNsense.bind.general.rndcsecret }}";
};
+
controls {
inet 127.0.0.1 port 9530
allow { 127.0.0.1; } keys { "rndc-key"; };
@@ -154,6 +233,11 @@ zone "rpzbing" { type primary; file "/usr/local/etc/namedb/primary/bing.db"; not
zone "{{ domain.domainname }}" {
type {{ domain.type }};
{% if domain.type == 'forward' %}
+{% if domain.forwardonly == '1' %}
+ forward only;
+{% else %}
+ forward first;
+{% endif %}
forwarders { {{ domain.forwardserver.replace(',', '; ') }}; };
{% elif domain.type == 'secondary' %}
{% if domain.transferkey is defined %}
@@ -261,7 +345,12 @@ plugin query "/usr/local/lib/bind/filter-aaaa.so" {
{% endif %}
{% endif %}
{% if helpers.exists('OPNsense.bind.general.filteraaaaacl') and OPNsense.bind.general.filteraaaaacl != '' %}
- filter-aaaa { {{ OPNsense.bind.general.filteraaaaacl.replace(',', '; ') }}; };
+ filter-aaaa {
+{% for acl in OPNsense.bind.general.filteraaaaacl.split(',') %}
+{% set filteraaaa_acl = helpers.getUUID(acl) %}
+ {{ filteraaaa_acl.name }};
+{% endfor %}
+ };
{% endif %}
};
{% endif %}