Unbound: addition to advanced rework (#6053)

Small addition to https://github.com/opnsense/core/pull/6050:

- Move private/insecure domains to advanced as its intended use has a larger scope than DNSBLs only. Fixes https://github.com/opnsense/core/issues/5256
- Extends the migration to also include these domains.
- leftover cleanup of legacy settings in migration.
- Adds the `serve-expired-reply-ttl`, `serve-expired-ttl`, `serve-expired-ttl-reset`, `serve-expired-client-timeout` options. These options are hidden until the `serve-expired` checkbox is checked, and indented to signify a relationship.
- Removes all dropdowns and instead provides numeric fields to input raw values for more control and less "guessing" of what is acceptable.
- Removes default settings to prevent mismatches with upstream in the future. It's probably best to refer to the Unbound documentation in our own documentation.
- Previously, `rrset-cache-size` and `outgoing-range` were implicitly set. These are now input fields. The migration code will take care of legacy setting assumptions.

Fixes https://github.com/opnsense/core/issues/5978
Fixes https://github.com/opnsense/core/issues/5795
This commit is contained in:
Stephan de Wit 2022-09-30 17:08:34 +02:00 committed by GitHub
parent 9cf0b30348
commit 346cc08c99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 236 additions and 178 deletions

2
plist
View File

@ -150,6 +150,7 @@
/usr/local/etc/ssl/opnsense.cnf
/usr/local/etc/strongswan.opnsense.d/README
/usr/local/etc/unbound.opnsense.d/README
/usr/local/etc/unbound.opnsense.d/miscellaneous.conf
/usr/local/libexec/opnsense-auth
/usr/local/opnsense/contrib/IXR/IXR_Library.php
/usr/local/opnsense/contrib/base32/Base32.php
@ -1064,7 +1065,6 @@
/usr/local/opnsense/service/templates/OPNsense/Unbound/core/blocklists.conf
/usr/local/opnsense/service/templates/OPNsense/Unbound/core/domainoverrides.conf
/usr/local/opnsense/service/templates/OPNsense/Unbound/core/dot.conf
/usr/local/opnsense/service/templates/OPNsense/Unbound/core/miscellaneous.conf
/usr/local/opnsense/service/templates/OPNsense/Unbound/core/private_domains.conf
/usr/local/opnsense/service/templates/OPNsense/Unbound/core/root.min.hints
/usr/local/opnsense/service/templates/OPNsense/Unbound/core/unbound_dhcpd.conf

View File

@ -0,0 +1 @@
# obsolete include file, last used in 22.7

View File

@ -43,8 +43,52 @@
<id>unbound.advanced.serveexpired</id>
<label>Serve Expired Responses</label>
<type>checkbox</type>
<style>serveexpired_parent</style>
<help>
Serve expired responses from the cache with a TTL of 0 without waiting for the actual resolution to finish.
The TTL can be modified with "Expired Record Reply TTL value"
</help>
</field>
<field>
<id>unbound.advanced.serveexpiredreplyttl</id>
<label>Expired Record Reply TTL value</label>
<type>text</type>
<style>serveexpired_child</style>
<help>
TTL value to use when replying with expired data. If "Client Expired Response Timeout" is also used
then it is recommended to use 30 as the value as per RFC 8767.
</help>
</field>
<field>
<id>unbound.advanced.serveexpiredttl</id>
<label>TTL for Expired Responses</label>
<type>text</type>
<style>serveexpired_child</style>
<help>
Limits the serving of expired responses to the configured amount of seconds after expiration.
A value of 0 disables the limit. A suggested value per RFC 8767 is between 86400 (1 day) and 259200 (3 days).
</help>
</field>
<field>
<id>unbound.advanced.serveexpiredttlreset</id>
<label>Reset Expired Record TTL</label>
<type>checkbox</type>
<style>serveexpired_child</style>
<help>
Set the TTL of expired records to the "TTL for Expired Responses" value after a failed attempt to
retrieve the record from an upstream server. This makes sure that the expired records will be served as long
as there are queries for it.
</help>
</field>
<field>
<id>unbound.advanced.serveexpiredclienttimeout</id>
<label>Client Expired Response Timeout</label>
<type>text</type>
<style>serveexpired_child</style>
<help>
Time in milliseconds before replying to the client with expired data. This essentially enables the serve-
stable behavior as specified in RFC 8767 that first tries to resolve before immediately responding with expired
data. A recommended value per RF 8767 is 1800. Setting this to 0 will disable this behavior.
</help>
</field>
<field>
@ -71,7 +115,7 @@
<help>
If enabled, prints one line per query to the log, with the log timestamp and IP address, name, type and class.
Note that it takes time to print these lines, which makes the server (significantly) slower. Odd
(nonprintable) characters in names are printed as '?'.
(non-printable) characters in names are printed as '?'.
</help>
</field>
<field>
@ -82,7 +126,7 @@
If enabled, prints one line per reply to the log, with the log timestamp and IP address, name, type,
class, return code, time to resolve, whether the reply is from the cache and the response size.
Note that it takes time to print these lines, which makes the server (significantly) slower. Odd
(nonprintable) characters in names are printed as '?'.
(non-printable) characters in names are printed as '?'.
</help>
</field>
<field>
@ -104,19 +148,49 @@
Level 4 gives algorithm level information. Level 5 logs client identification for cache misses.
</help>
</field>
<field>
<id>unbound.advanced.privatedomain</id>
<label>Private Domains</label>
<type>select_multiple</type>
<style>tokenize</style>
<allownew>true</allownew>
<help>
List of domains to mark as private. These domains and all its subdomains are allowed to contain
private addresses.
</help>
</field>
<field>
<id>unbound.advanced.insecuredomain</id>
<label>Insecure Domains</label>
<type>select_multiple</type>
<style>tokenize</style>
<allownew>true</allownew>
<help>List of domains to mark as insecure. DNSSEC chain of trust is ignored towards the domain name.</help>
</field>
<field>
<id>unbound.advanced.msgcachesize</id>
<label>Message Cache Size</label>
<type>dropdown</type>
<type>text</type>
<help>
Size of the message cache. The message cache stores DNS rcodes and validation statuses.
The RRSet cache will automatically be set to twice this amount. The RRSet cache contains the actual RR data.
Valid input is plain bytes, optionally appended with 'k', 'm', or 'g' for kilobytes, megabytes
or gigabytes respectively.
</help>
</field>
<field>
<id>unbound.advanced.rrsetcachesize</id>
<label>RRset Cache Size</label>
<type>text</type>
<help>
Size of the RRset cache. Contains the actual RR data. Valid input is plain bytes, optionally appended
with 'k', 'm', or 'g' for kilobytes, megabytes or gigabytes respectively.
</help>
</field>
<field>
<id>unbound.advanced.outgoingnumtcp</id>
<label>Outgoing TCP Buffers</label>
<type>dropdown</type>
<type>text</type>
<help>
The number of outgoing TCP buffers to allocate per thread.
If 0 is selected then no TCP queries, to authoritative servers, are done.
@ -125,7 +199,7 @@
<field>
<id>unbound.advanced.incomingnumtcp</id>
<label>Incoming TCP Buffers</label>
<type>dropdown</type>
<type>text</type>
<help>
The number of incoming TCP buffers to allocate per thread.
If 0 is selected then no TCP queries, from clients, are accepted.
@ -134,18 +208,33 @@
<field>
<id>unbound.advanced.numqueriesperthread</id>
<label>Number of queries per thread</label>
<type>dropdown</type>
<type>text</type>
<help>
The number of queries that every thread will service simultaneously. If more queries arrive that
need to be serviced, and no queries can be jostled, then these queries are dropped.
need to be serviced, and no queries can be jostled out (see "Jostle Timeout"),
then these queries are dropped. This forces the client to resend after a timeout, allowing the
server time to work on the existing queries.
</help>
</field>
<field>
<id>unbound.advanced.outgoingrange</id>
<label>Outgoing Range</label>
<type>text</type>
<help>
The number of ports to open. This number of file descriptors can be opened per thread. Larger numbers
need extra resources from the operating system. For performance a very large value is best.
For reference, usually double the amount of queries per thread is used.
</help>
</field>
<field>
<id>unbound.advanced.jostletimeout</id>
<label>Jostle Timeout</label>
<type>dropdown</type>
<type>text</type>
<help>
This timeout is used for when the server is very busy. This protects against denial of service by
This timeout is used for when the server is very busy. Set to a value that usually results in one
round-trip to the authority servers. If too many queries arrive, then 50% of the queries are allowed
to run to completion, and the other 50% are replaced with the new incoming query if they have
already spent more than their allowed time. This protects against denial of service by
slow queries or high query rates.
</help>
</field>
@ -154,8 +243,8 @@
<label>Maximum TTL for RRsets and messages</label>
<type>text</type>
<help>
Configure a maximum Time to live for RRsets and messages in the cache.
The default is 86400 seconds (1 day). When the internal TTL expires the cache item is expired.
Configure a maximum Time to live in seconds for RRsets and messages in the cache.
When the internal TTL expires the cache item is expired.
This can be configured to force the resolver to query for data more often and
not trust (very large) TTL values.
</help>
@ -165,9 +254,9 @@
<label>Minimum TTL for RRsets and messages</label>
<type>text</type>
<help>
Configure a minimum Time to live for RRsets and messages in the cache.
The default is 0 seconds. If the minimum value kicks in, the data is cached for longer than
the domain owner intended, and thus less queries are made to look up the data.
Configure a minimum Time to live in seconds for RRsets and messages in the cache.
If the minimum value kicks in, the data is cached for longer than
the domain owner intended, and thus fewer queries are made to look up the data.
The 0 value ensures the data in the cache is as the domain owner intended.
High values can lead to trouble as the data in the cache might not match up with the actual data anymore.
</help>
@ -175,16 +264,16 @@
<field>
<id>unbound.advanced.infrahostttl</id>
<label>TTL for Host Cache entries</label>
<type>dropdown</type>
<type>text</type>
<help>
Time to live for entries in the host cache. The host cache contains roundtrip timing and EDNS
support information.
Time to live in seconds for entries in the host cache. The host cache contains round-trip timing, lameness
and EDNS support information.
</help>
</field>
<field>
<id>unbound.advanced.infracachenumhosts</id>
<label>Number of Hosts to cache</label>
<type>dropdown</type>
<type>text</type>
<help>
Number of hosts for which information is cached.
</help>
@ -192,12 +281,11 @@
<field>
<id>unbound.advanced.unwantedreplythreshold</id>
<label>Unwanted Reply Threshold</label>
<type>dropdown</type>
<type>text</type>
<help>
If enabled, a total number of unwanted replies is kept track of in every thread.
When it reaches the threshold, a defensive action is taken and a warning is printed to the log file.
This defensive action is to clear the RRSet and message caches, hopefully flushing away any poison.
The default is disabled, but if enabled a value of 10 million is suggested.
</help>
</field>
</form>

View File

@ -35,20 +35,4 @@
<advanced>true</advanced>
<help>Destination ip address for entries in the blocklist (leave empty to use default: 0.0.0.0)</help>
</field>
<field>
<id>unbound.miscellaneous.privatedomain</id>
<label>Private Domains</label>
<type>select_multiple</type>
<style>tokenize</style>
<allownew>true</allownew>
<help>List of domains to mark as private. You only need this for some DNSBL lists which resolve to private addresses.</help>
</field>
<field>
<id>unbound.miscellaneous.insecuredomain</id>
<label>Insecure Domains</label>
<type>select_multiple</type>
<style>tokenize</style>
<allownew>true</allownew>
<help>List of domains to mark as insecure. DNSSEC chain of trust is ignored towards the domain name.</help>
</field>
</form>

View File

@ -33,6 +33,29 @@ use OPNsense\Core\Config;
class M1_0_3 extends BaseModelMigration
{
private $legacy_format = array(
'outgoing_num_tcp',
'incoming_num_tcp',
'num_queries_per_thread',
'jostle_timeout',
'cache_max_ttl',
'cache_min_ttl',
'infra_host_ttl',
'infra_cache_numhosts',
'unwanted_reply_threshold',
'log_verbosity',
'extended_statistics',
'log_queries',
'hideidentity',
'hideversion',
'prefetch',
'prefetchkey',
'dnssecstripped',
'serveexpired',
'qnameminstrict',
'msgcachesize'
);
/**
* Migrate older models into shared model
* @param $model
@ -41,34 +64,44 @@ class M1_0_3 extends BaseModelMigration
{
$config = Config::getInstance()->object();
$legacy_format = array(
'outgoing_num_tcp',
'incoming_num_tcp',
'num_queries_per_thread',
'jostle_timeout',
'cache_max_ttl',
'cache_min_ttl',
'infra_host_ttl',
'infra_cache_numhosts',
'unwanted_reply_threshold',
'log_verbosity',
'extended_statistics',
'log_queries'
);
$legacy_config = array();
foreach ($config->unbound->children() as $key => $value) {
if (in_array($key, $legacy_format) && !empty((string)$value)) {
/* handle differing keys */
if (in_array($key, $this->legacy_format) && !empty((string)$value)) {
if ($key == 'msgcachesize') {
$legacy_config[$key] = (string)$value . 'm';
/* Mimic legacy behaviour for the msg cache size value (if applied) */
$legacy_config['rrsetcachesize'] = ($value * 2) . 'm';
continue;
}
if ($key == 'num_queries_per_thread') {
$legacy_config['outgoingrange'] = $value * 2;
}
/* handle differing keys, underscore got removed in model transition */
$legacy_config[str_replace('_', '', $key)] = (string)$value;
}
}
if (array_key_exists($key, $model->advanced->getNodes()) && !empty((string)$value)) {
/* handle matching keys */
$legacy_config[$key] = (string)$value;
foreach (['privatedomain', 'insecuredomain'] as $misc_node) {
$node_value = (string)$config->OPNsense->unboundplus->miscellaneous->$misc_node;
if (!empty($node_value)) {
$legacy_config[$misc_node] = $node_value;
}
}
$model->advanced->setNodes($legacy_config);
}
/**
* cleanup old config after config save
* @param $model
*/
public function post($model)
{
$config = Config::getInstance()->object();
foreach ($this->legacy_format as $node) {
unset($config->unbound->$node);
}
}
}

View File

@ -25,6 +25,15 @@
<serveexpired type="BooleanField">
<default>0</default>
</serveexpired>
<serveexpiredreplyttl type="NumericField">
</serveexpiredreplyttl>
<serveexpiredttl type="NumericField">
</serveexpiredttl>
<serveexpiredttlreset type="BooleanField">
<default>0</default>
</serveexpiredttlreset>
<serveexpiredclienttimeout type="NumericField">
</serveexpiredclienttimeout>
<qnameminstrict type="BooleanField">
<default>0</default>
</qnameminstrict>
@ -52,103 +61,39 @@
<opt6 value="5">Level 5</opt6>
</OptionValues>
</logverbosity>
<msgcachesize type="OptionField">
<default>4</default>
<Required>Y</Required>
<OptionValues>
<opt1 value="4">4 MB (Default)</opt1>
<opt2 value="10">10 MB</opt2>
<opt3 value="20">20 MB</opt3>
<opt4 value="50">50 MB</opt4>
<opt5 value="100">100 MB</opt5>
<opt6 value="250">250 MB</opt6>
<opt7 value="512">512 MB</opt7>
</OptionValues>
<privatedomain type="CSVListField">
<Required>N</Required>
</privatedomain>
<insecuredomain type="CSVListField">
<Required>N</Required>
</insecuredomain>
<msgcachesize type="TextField">
<Mask>/[0-9]+[kmg]?/i</Mask>
<ValidationMessage>The cache size should be numeric, optionally appended with 'k', 'm', or 'g'</ValidationMessage>
</msgcachesize>
<outgoingnumtcp type="OptionField">
<default>10</default>
<Required>Y</Required>
<OptionValues>
<opt1 value="0">0</opt1>
<opt2 value="10">10 (Default)</opt2>
<opt3 value="20">20</opt3>
<opt4 value="30">30</opt4>
<opt5 value="40">40</opt5>
<opt6 value="50">50</opt6>
</OptionValues>
<rrsetcachesize type="TextField">
<Mask>/[0-9]+[kmg]?/i</Mask>
<ValidationMessage>The cache size should be numeric, optionally appended with 'k', 'm', or 'g'</ValidationMessage>
</rrsetcachesize>
<outgoingnumtcp type="NumericField">
</outgoingnumtcp>
<incomingnumtcp type="OptionField">
<default>10</default>
<Required>Y</Required>
<OptionValues>
<opt1 value="0">0</opt1>
<opt2 value="10">10 (Default)</opt2>
<opt3 value="20">20</opt3>
<opt4 value="30">30</opt4>
<opt5 value="40">40</opt5>
<opt6 value="50">50</opt6>
</OptionValues>
<incomingnumtcp type="NumericField">
</incomingnumtcp>
<numqueriesperthread type="OptionField">
<default>4096</default>
<Required>Y</Required>
<OptionValues>
<opt1 value="512">512</opt1>
<opt2 value="1024">1024</opt2>
<opt3 value="2048">2048</opt3>
<opt4 value="4096">4096 (Default)</opt4>
<opt5 value="8192">8192</opt5>
</OptionValues>
<numqueriesperthread type="NumericField">
</numqueriesperthread>
<jostletimeout type="OptionField">
<default>200</default>
<Required>Y</Required>
<OptionValues>
<opt1 value="100">100</opt1>
<opt2 value="200">200 (Default)</opt2>
<opt3 value="500">500</opt3>
<opt4 value="1000">1000</opt4>
</OptionValues>
<outgoingrange type="NumericField">
</outgoingrange>
<jostletimeout type="NumericField">
</jostletimeout>
<cachemaxttl type="NumericField">
<default>86400</default>
</cachemaxttl>
<cacheminttl type="NumericField">
<default>0</default>
</cacheminttl>
<infrahostttl type="OptionField">
<default>900</default>
<Required>Y</Required>
<OptionValues>
<opt1 value="60">1 minute</opt1>
<opt2 value="120">2 minutes</opt2>
<opt3 value="300">5 minutes</opt3>
<opt4 value="600">10 minutes</opt4>
<opt5 value="900">15 minutes (Default)</opt5>
</OptionValues>
<infrahostttl type="NumericField">
</infrahostttl>
<infracachenumhosts type="OptionField">
<default>10000</default>
<Required>Y</Required>
<OptionValues>
<opt1 value="1000">1000</opt1>
<opt2 value="5000">5000</opt2>
<opt3 value="10000">10000 (Default)</opt3>
<opt4 value="20000">20000</opt4>
<opt5 value="50000">50000</opt5>
</OptionValues>
<infracachenumhosts type="NumericField">
</infracachenumhosts>
<unwantedreplythreshold type="OptionField">
<default>0</default>
<Required>Y</Required>
<OptionValues>
<opt1 value="0">Disabled (Default)</opt1>
<opt1 value="5000000">5 million</opt1>
<opt2 value="10000000">10 million</opt2>
<opt3 value="20000000">20 million</opt3>
<opt4 value="40000000">40 million</opt4>
<opt5 value="50000000">50 million</opt5>
</OptionValues>
<unwantedreplythreshold type="NumericField">
</unwantedreplythreshold>
</advanced>
<dnsbl>
@ -391,13 +336,5 @@
</description>
</domain>
</domains>
<miscellaneous>
<privatedomain type="CSVListField">
<Required>N</Required>
</privatedomain>
<insecuredomain type="CSVListField">
<Required>N</Required>
</insecuredomain>
</miscellaneous>
</items>
</model>

View File

@ -26,10 +26,18 @@
<script>
$( document ).ready(function() {
function row_toggle() {
$parent_row = $('.serveexpired_child').closest('tr');
$parent_row.find('div:first').css('padding-left', '20px');
$('.serveexpired_parent').is(':checked') ? $parent_row.removeClass("hidden") : $parent_row.addClass("hidden");
}
var data_get_map = {'frm_AdvancedSettings':"/api/unbound/settings/get"};
mapDataToFormUI(data_get_map).done(function(data) {
formatTokenizersUI();
$('.selectpicker').selectpicker('refresh');
formatTokenizersUI();
$('.selectpicker').selectpicker('refresh');
row_toggle();
});
$("#reconfigureAct").SimpleActionButton({
@ -42,6 +50,10 @@
}
});
$('.serveexpired_parent').click(function(){
row_toggle();
});
updateServiceControlUI('unbound');
});
</script>

View File

@ -3,6 +3,5 @@ blocklists.conf:/tmp/unbound-blocklists.conf
dot.conf:/usr/local/etc/unbound.opnsense.d/dot.conf
private_domains.conf:/var/unbound/private_domains.conf
domainoverrides.conf:/usr/local/etc/unbound.opnsense.d/domainoverrides.conf
miscellaneous.conf:/usr/local/etc/unbound.opnsense.d/miscellaneous.conf
root.min.hints:/var/unbound/root.hints
unbound_dhcpd.conf:/usr/local/etc/unbound_dhcpd.conf

View File

@ -1,6 +1,11 @@
{% macro set_boolean(name) -%}
{% if name == '1' %}yes{%else%}no{%endif%}
{%- endmacro %}
{% macro set_numeric_value(key, value) -%}
{% if value is defined and not empty %}
{{ key }}: {{ value }}
{% endif %}
{%- endmacro %}
{% if helpers.exists('OPNsense.unboundplus.advanced') %}
hide-identity: {{ set_boolean(OPNsense.unboundplus.advanced.hideidentity) }}
hide-version: {{ set_boolean(OPNsense.unboundplus.advanced.hideversion) }}
@ -13,17 +18,27 @@ extended-statistics: {{ set_boolean(OPNsense.unboundplus.advanced.extendedstatis
log-queries: {{ set_boolean(OPNsense.unboundplus.advanced.logqueries) }}
log-replies: {{ set_boolean(OPNsense.unboundplus.advanced.logreplies) }}
log-tag-queryreply: {{ set_boolean(OPNsense.unboundplus.advanced.logtagqueryreply) }}
verbosity: {{ OPNsense.unboundplus.advanced.logverbosity }}
msg-cache-size: {{ OPNsense.unboundplus.advanced.msgcachesize }}m
rrset-cache-size: {{ OPNsense.unboundplus.advanced.msgcachesize|int() * 2 }}m
outgoing-num-tcp: {{ OPNsense.unboundplus.advanced.outgoingnumtcp }}
incoming-num-tcp: {{ OPNsense.unboundplus.advanced.incomingnumtcp }}
num-queries-per-thread: {{ OPNsense.unboundplus.advanced.numqueriesperthread }}
outgoing-range: {{ OPNsense.unboundplus.advanced.numqueriesperthread|int() * 2 }}
jostle-timeout: {{ OPNsense.unboundplus.advanced.jostletimeout }}
cache-max-ttl: {{ OPNsense.unboundplus.advanced.cachemaxttl }}
cache-min-ttl: {{ OPNsense.unboundplus.advanced.cacheminttl }}
infra-host-ttl: {{ OPNsense.unboundplus.advanced.infrahostttl }}
infra-cache-numhosts: {{ OPNsense.unboundplus.advanced.infracachenumhosts }}
unwanted-reply-threshold: {{ OPNsense.unboundplus.advanced.unwantedreplythreshold }}
{{ set_numeric_value('verbosity', OPNsense.unboundplus.advanced.logverbosity) }}
{{ set_numeric_value('msg-cache-size', OPNsense.unboundplus.advanced.msgcachesize) }}
{{ set_numeric_value('rrset-cache-size', OPNsense.unboundplus.advanced.rrsetcachesize) }}
{{ set_numeric_value('outgoing-num-tcp', OPNsense.unboundplus.advanced.outgoingnumtcp) }}
{{ set_numeric_value('incoming-num-tcp', OPNsense.unboundplus.advanced.incomingnumtcp) }}
{{ set_numeric_value('num-queries-per-thread', OPNsense.unboundplus.advanced.numqueriesperthread) }}
{{ set_numeric_value('outgoing-range', OPNsense.unboundplus.advanced.outgoingrange) }}
{{ set_numeric_value('jostle-timeout', OPNsense.unboundplus.advanced.jostletimeout) }}
{{ set_numeric_value('cache-max-ttl', OPNsense.unboundplus.advanced.cachemaxttl) }}
{{ set_numeric_value('cache-min-ttl', OPNsense.unboundplus.advanced.cacheminttl) }}
{{ set_numeric_value('infra-host-ttl', OPNsense.unboundplus.advanced.infrahostttl) }}
{{ set_numeric_value('infra-cache-numhosts', OPNsense.unboundplus.advanced.infracachenumhosts) }}
{{ set_numeric_value('unwanted-reply-threshold', OPNsense.unboundplus.advanced.unwantedreplythreshold) }}
{% if not helpers.empty('OPNsense.unboundplus.advanced.privatedomain') %}
{% for privatedomain in OPNsense.unboundplus.advanced.privatedomain.split(',') %}
private-domain: {{ privatedomain }}
{% endfor %}
{% endif %}
{% if not helpers.empty('OPNsense.unboundplus.advanced.insecuredomain') %}
{% for insecuredomain in OPNsense.unboundplus.advanced.insecuredomain.split(',') %}
domain-insecure: {{ insecuredomain }}
{% endfor %}
{% endif %}
{% endif %}

View File

@ -1,11 +0,0 @@
server:
{% if not helpers.empty('OPNsense.unboundplus.miscellaneous.privatedomain') %}
{% for privatedomain in OPNsense.unboundplus.miscellaneous.privatedomain.split(',') %}
private-domain: {{ privatedomain }}
{% endfor %}
{% endif %}
{% if not helpers.empty('OPNsense.unboundplus.miscellaneous.insecuredomain') %}
{% for insecuredomain in OPNsense.unboundplus.miscellaneous.insecuredomain.split(',') %}
domain-insecure: {{ insecuredomain }}
{% endfor %}
{% endif %}