diff --git a/dns/bind/pkg-descr b/dns/bind/pkg-descr index 284434dc92..24421ef893 100644 --- a/dns/bind/pkg-descr +++ b/dns/bind/pkg-descr @@ -7,6 +7,12 @@ necessary for asking and answering name service questions. Plugin Changelog ================ +1.35 + +* Add per-forwarder destination port for plain DNS forwarders +* Add DNS-over-TLS (DoT) forwarders with TLS hostname verification +* Migrate legacy DNS Forwarders list to the new DNS Forwarders tab + 1.34 * Add custom configuration include directory /usr/local/etc/namedb/named.conf.d (contributed by Nicholas Card) diff --git a/dns/bind/src/opnsense/mvc/app/controllers/OPNsense/Bind/Api/ForwarderController.php b/dns/bind/src/opnsense/mvc/app/controllers/OPNsense/Bind/Api/ForwarderController.php new file mode 100644 index 0000000000..00e438d3e4 --- /dev/null +++ b/dns/bind/src/opnsense/mvc/app/controllers/OPNsense/Bind/Api/ForwarderController.php @@ -0,0 +1,99 @@ + + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +namespace OPNsense\Bind\Api; + +use OPNsense\Base\ApiMutableModelControllerBase; + +class ForwarderController extends ApiMutableModelControllerBase +{ + protected static $internalModelName = 'forwarder'; + protected static $internalModelClass = '\OPNsense\Bind\Forwarder'; + + public function searchDnsForwarderAction() + { + return $this->searchBase('forwarders.dns', ['enabled', 'ip', 'port']); + } + + public function getDnsForwarderAction($uuid = null) + { + return $this->getBase('dns', 'forwarders.dns', $uuid); + } + + public function addDnsForwarderAction() + { + return $this->addBase('dns', 'forwarders.dns'); + } + + public function delDnsForwarderAction($uuid) + { + return $this->delBase('forwarders.dns', $uuid); + } + + public function setDnsForwarderAction($uuid) + { + return $this->setBase('dns', 'forwarders.dns', $uuid); + } + + public function toggleDnsForwarderAction($uuid) + { + return $this->toggleBase('forwarders.dns', $uuid); + } + + public function searchDotForwarderAction() + { + return $this->searchBase('forwarders.dot', ['enabled', 'ip', 'port', 'tlshostname']); + } + + public function getDotForwarderAction($uuid = null) + { + return $this->getBase('dot', 'forwarders.dot', $uuid); + } + + public function addDotForwarderAction() + { + return $this->addBase('dot', 'forwarders.dot'); + } + + public function delDotForwarderAction($uuid) + { + return $this->delBase('forwarders.dot', $uuid); + } + + public function setDotForwarderAction($uuid) + { + return $this->setBase('dot', 'forwarders.dot', $uuid); + } + + public function toggleDotForwarderAction($uuid) + { + return $this->toggleBase('forwarders.dot', $uuid); + } +} diff --git a/dns/bind/src/opnsense/mvc/app/controllers/OPNsense/Bind/ForwardingController.php b/dns/bind/src/opnsense/mvc/app/controllers/OPNsense/Bind/ForwardingController.php new file mode 100644 index 0000000000..015327b7a4 --- /dev/null +++ b/dns/bind/src/opnsense/mvc/app/controllers/OPNsense/Bind/ForwardingController.php @@ -0,0 +1,39 @@ + + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +namespace OPNsense\Bind; + +class ForwardingController extends \OPNsense\Base\IndexController +{ + public function indexAction() + { + $this->view->formDialogEditBindDnsForwarder = $this->getForm("dialogEditBindDnsForwarder"); + $this->view->formDialogEditBindDotForwarder = $this->getForm("dialogEditBindDotForwarder"); + $this->view->pick('OPNsense/Bind/forwarding'); + } +} diff --git a/dns/bind/src/opnsense/mvc/app/controllers/OPNsense/Bind/forms/dialogEditBindDnsForwarder.xml b/dns/bind/src/opnsense/mvc/app/controllers/OPNsense/Bind/forms/dialogEditBindDnsForwarder.xml new file mode 100644 index 0000000000..506350c75e --- /dev/null +++ b/dns/bind/src/opnsense/mvc/app/controllers/OPNsense/Bind/forms/dialogEditBindDnsForwarder.xml @@ -0,0 +1,46 @@ + + +
+ + dns.enabled + + checkbox + This will enable or disable this forwarder. + + + dns.ip + + text + Set the IPv4 or IPv6 address of the upstream DNS server. For a local encryption proxy such as contrld, use 127.0.0.1. + + + dns.port + + text + Set the destination port. Defaults to 53; use a custom port for a local proxy (e.g. 5300). + +
diff --git a/dns/bind/src/opnsense/mvc/app/controllers/OPNsense/Bind/forms/dialogEditBindDotForwarder.xml b/dns/bind/src/opnsense/mvc/app/controllers/OPNsense/Bind/forms/dialogEditBindDotForwarder.xml new file mode 100644 index 0000000000..794fb0f2f3 --- /dev/null +++ b/dns/bind/src/opnsense/mvc/app/controllers/OPNsense/Bind/forms/dialogEditBindDotForwarder.xml @@ -0,0 +1,52 @@ + + +
+ + dot.enabled + + checkbox + This will enable or disable this DNS-over-TLS forwarder. + + + dot.ip + + text + Set the IPv4 or IPv6 address of the upstream DoT server (e.g. 1.1.1.1 for Cloudflare). + + + dot.port + + text + Set the destination port. Defaults to 853 (the standard DNS-over-TLS port). + + + dot.tlshostname + + text + Set the TLS hostname for certificate verification (e.g. cloudflare-dns.com). If set, the upstream certificate must match this hostname and is verified against the system CA bundle. If left empty, BIND verifies the certificate against the forwarder's IP address; that IP address must be present in the certificate Subject Alternative Name. + +
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..73ae992496 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 @@ -61,14 +61,6 @@ true 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. - general.filteraaaav4 @@ -126,6 +118,12 @@ select_multiple Define the ACLs where you allow which client are allowed to query this server. + + general.forwarding + + dropdown + Set to "Forward Only" to prevent BIND from falling back to its own recursive resolution when forwarders are unreachable. If set to "Forward Only", configure forwarders on the DNS Forwarders tab. + general.dnssecvalidation diff --git a/dns/bind/src/opnsense/mvc/app/models/OPNsense/Bind/Forwarder.php b/dns/bind/src/opnsense/mvc/app/models/OPNsense/Bind/Forwarder.php new file mode 100644 index 0000000000..54616d2652 --- /dev/null +++ b/dns/bind/src/opnsense/mvc/app/models/OPNsense/Bind/Forwarder.php @@ -0,0 +1,31 @@ + + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +namespace OPNsense\Bind; + +use OPNsense\Base\BaseModel; + +class Forwarder extends BaseModel +{ +} diff --git a/dns/bind/src/opnsense/mvc/app/models/OPNsense/Bind/Forwarder.xml b/dns/bind/src/opnsense/mvc/app/models/OPNsense/Bind/Forwarder.xml new file mode 100644 index 0000000000..ce433e405e --- /dev/null +++ b/dns/bind/src/opnsense/mvc/app/models/OPNsense/Bind/Forwarder.xml @@ -0,0 +1,78 @@ + + + + //OPNsense/bind/forwarder + BIND DNS and DNS-over-TLS forwarders + 1.0.1 + + + + + 1 + Y + + + Y + N + + + A plain forwarder with this IP already exists. + UniqueConstraint + + + + + 53 + Y + + + + + 1 + Y + + + Y + N + + + A DoT forwarder with this IP already exists. + UniqueConstraint + + + + + 853 + Y + + + N + + + + + 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..69fc744e9e 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 @@ -45,9 +45,14 @@ 53530 Y - - Y - + + first + Y + + Forward First + Forward Only + + 0 Y diff --git a/dns/bind/src/opnsense/mvc/app/models/OPNsense/Bind/Menu/Menu.xml b/dns/bind/src/opnsense/mvc/app/models/OPNsense/Bind/Menu/Menu.xml index 06ed53ca81..a5adcf179b 100644 --- a/dns/bind/src/opnsense/mvc/app/models/OPNsense/Bind/Menu/Menu.xml +++ b/dns/bind/src/opnsense/mvc/app/models/OPNsense/Bind/Menu/Menu.xml @@ -1,8 +1,9 @@ - - + + + diff --git a/dns/bind/src/opnsense/mvc/app/models/OPNsense/Bind/Migrations/M1_0_1.php b/dns/bind/src/opnsense/mvc/app/models/OPNsense/Bind/Migrations/M1_0_1.php new file mode 100644 index 0000000000..9f4adde6bf --- /dev/null +++ b/dns/bind/src/opnsense/mvc/app/models/OPNsense/Bind/Migrations/M1_0_1.php @@ -0,0 +1,90 @@ + + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +namespace OPNsense\Bind\Migrations; + +use OPNsense\Base\BaseModelMigration; +use OPNsense\Bind\Forwarder; +use OPNsense\Core\Config; + +class M1_0_1 extends BaseModelMigration +{ + /** + * Migrate the legacy General model forwarders CSV into this model's DNS + * forwarder grid. + * @param $model + */ + public function run($model) + { + if (!($model instanceof Forwarder)) { + return; + } + + $config = Config::getInstance()->object(); + if (empty($config->OPNsense->bind->general->forwarders)) { + return; + } + + $legacy = trim((string)$config->OPNsense->bind->general->forwarders); + if ($legacy === '') { + return; + } + + if (count(iterator_to_array($model->forwarders->dns->iterateItems())) > 0) { + return; + } + + foreach (explode(',', $legacy) as $token) { + $token = trim($token); + if ($token === '') { + continue; + } + + $ip = $token; + $port = '53'; + + if (filter_var($token, FILTER_VALIDATE_IP) === false && strpos($token, ':') !== false) { + [$candidateIp, $candidatePort] = explode(':', $token, 2); + if (filter_var($candidateIp, FILTER_VALIDATE_IP) !== false && + ctype_digit($candidatePort) && $candidatePort >= 1 && $candidatePort <= 65535 + ) { + $ip = $candidateIp; + $port = $candidatePort; + } else { + syslog(LOG_WARNING, sprintf('BIND migration: no valid port found in "%s", defaulting to 53.', $token)); + } + } + + $forwarder = $model->forwarders->dns->add(); + $forwarder->ip = $ip; + $forwarder->port = $port; + } + + $config->OPNsense->bind->general->forwarders = ''; + } +} diff --git a/dns/bind/src/opnsense/mvc/app/views/OPNsense/Bind/forwarding.volt b/dns/bind/src/opnsense/mvc/app/views/OPNsense/Bind/forwarding.volt new file mode 100644 index 0000000000..df99a49ca7 --- /dev/null +++ b/dns/bind/src/opnsense/mvc/app/views/OPNsense/Bind/forwarding.volt @@ -0,0 +1,153 @@ +{# + # Copyright (C) 2026 Bryan Wiegand + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions are met: + # + # 1. Redistributions of source code must retain the above copyright notice, + # this list of conditions and the following disclaimer. + # + # 2. Redistributions in binary form must reproduce the above copyright notice, + # this list of conditions and the following disclaimer in the documentation + # and/or other materials provided with the distribution. + # + # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND ANY + # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + # DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY + # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#} + + + + +
+
+
+ +
+
+

{{ lang._('DNS') }}

+
+
+ + + + + + + + + + + + + + + + + + +
{{ lang._('Enabled') }}{{ lang._('IP Address') }}{{ lang._('Port') }}{{ lang._('ID') }}{{ lang._('Commands') }}
+ + +
+
+
+
+

{{ lang._('DNS over TLS') }}

+
+
+ + + + + + + + + + + + + + + + + + + +
{{ lang._('Enabled') }}{{ lang._('IP Address') }}{{ lang._('Port') }}{{ lang._('TLS Hostname') }}{{ lang._('ID') }}{{ lang._('Commands') }}
+ + +
+
+
+
+ + +

+
+
+
+ +{{ partial("layout_partials/base_dialog",['fields':formDialogEditBindDnsForwarder,'id':'dialogEditBindDnsForwarder','label':lang._('Edit DNS Forwarder')])}} +{{ partial("layout_partials/base_dialog",['fields':formDialogEditBindDotForwarder,'id':'dialogEditBindDotForwarder','label':lang._('Edit DNS over TLS Forwarder')])}} + + + 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..e827ce7cc6 100644 --- a/dns/bind/src/opnsense/service/templates/OPNsense/Bind/named.conf +++ b/dns/bind/src/opnsense/service/templates/OPNsense/Bind/named.conf @@ -38,9 +38,34 @@ options { transfer-source-v6 {{ OPNsense.bind.general.transfersourcev6 }}; {% endif -%} -{% if helpers.exists('OPNsense.bind.general.forwarders') and OPNsense.bind.general.forwarders != '' %} - forwarders { {{ OPNsense.bind.general.forwarders.replace(',', '; ') }}; }; -{% endif -%} +{% set forwarder_present = [] %} +{% if helpers.exists('OPNsense.bind.forwarder.forwarders.dns') %} +{% for f in helpers.toList('OPNsense.bind.forwarder.forwarders.dns') %} +{% if f.enabled == '1' %}{% do forwarder_present.append(1) %}{% endif %} +{% endfor %} +{% endif %} +{% if helpers.exists('OPNsense.bind.forwarder.forwarders.dot') %} +{% for f in helpers.toList('OPNsense.bind.forwarder.forwarders.dot') %} +{% if f.enabled == '1' %}{% do forwarder_present.append(1) %}{% endif %} +{% endfor %} +{% endif %} +{% if forwarder_present|length > 0 %} + forwarders { +{% if helpers.exists('OPNsense.bind.forwarder.forwarders.dns') %} +{% for f in helpers.toList('OPNsense.bind.forwarder.forwarders.dns') if f.enabled == '1' %} + {{ f.ip }} port {{ f.port }}; +{% endfor %} +{% endif %} +{% if helpers.exists('OPNsense.bind.forwarder.forwarders.dot') %} +{% for f in helpers.toList('OPNsense.bind.forwarder.forwarders.dot') if f.enabled == '1' %} + {{ f.ip }} port {{ f.port }} tls "dot-{{ f['@uuid'] }}"; +{% endfor %} +{% endif %} + }; +{% if helpers.exists('OPNsense.bind.general.forwarding') %} + forward {{ OPNsense.bind.general.forwarding }}; +{% endif %} +{% 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 %} }; @@ -101,6 +126,17 @@ options { {% endif %} }; +{% if helpers.exists('OPNsense.bind.forwarder.forwarders.dot') %} +{% for f in helpers.toList('OPNsense.bind.forwarder.forwarders.dot') if f.enabled == '1' %} +tls "dot-{{ f['@uuid'] }}" { +{% if f.tlshostname is defined and f.tlshostname != '' %} + remote-hostname "{{ f.tlshostname }}"; +{% endif %} + ca-file "/usr/local/etc/ssl/cert.pem"; +}; +{% endfor %} +{% endif %} + {% if helpers.exists('OPNsense.bind.general.rndcalgo') and helpers.exists('OPNsense.bind.general.rndcsecret') %} key "rndc-key" { algorithm "{{ OPNsense.bind.general.rndcalgo }}";