dns/dnscrypt-proxy: fix listening madness, why do DNS services reinvent wheels?

Also fix validation against other DNS services using the port already.

See: https://github.com/DNSCrypt/dnscrypt-proxy/issues/1217
This commit is contained in:
Franco Fichtner
2023-05-08 10:24:11 +02:00
parent afec26dc6b
commit 470a4ba995
6 changed files with 115 additions and 74 deletions
+1
View File
@@ -1,5 +1,6 @@
PLUGIN_NAME= dnscrypt-proxy
PLUGIN_VERSION= 1.13
PLUGIN_REVISION= 1
PLUGIN_COMMENT= Flexible DNS proxy supporting DNSCrypt and DoH
PLUGIN_DEPENDS= dnscrypt-proxy2
PLUGIN_MAINTAINER= m.muenz@gmail.com
+2 -1
View File
@@ -8,7 +8,8 @@ Plugin Changelog
1.13
* Add necessary hooks to allow the plugin to be used as a standalone core DNS server
* Changed default listening addresses to 0.0.0.0/:: for new users
* Changed default listening addresses to 0.0.0.0 for new users
* Prevent using a port being used by another DNS service
1.12
@@ -51,25 +51,18 @@ function dnscryptproxy_services()
$model = new \OPNsense\Dnscryptproxy\General();
$ports = [];
/*
* DNS service is eligable for core use when both 0.0.0.0 and :: are set.
* In order to provide dual stack ports we need to intersect the resulting
* ports for each address family.
*/
$localhost4 = [];
$localhost6 = [];
/* DNS service is eligable for core use when either 0.0.0.0 or :: are set */
foreach (explode(',', (string)$model->listen_addresses) as $addrport) {
if (preg_match('/^0\.0\.0\.0:([\d]+)$/', $addrport, $matches)) {
$localhost4[$matches[1]] = 1;
$ports[$matches[1]] = 1;
} elseif (preg_match('/^\[::\]:([\d]+)$/', $addrport, $matches)) {
$localhost6[$matches[1]] = 1;
$ports[$matches[1]] = 1;
}
}
$services[] = [
/* the port may still be something other than 53, but it's safe to register a conflict for it */
'dns_ports' => array_keys(array_intersect_key($localhost4, $localhost6)),
'dns_ports' => array_keys($ports),
'description' => gettext('DNSCrypt-Proxy'),
'configd' => [
'restart' => ['dnscryptproxy restart'],
@@ -1,35 +1,85 @@
<?php
/*
Copyright (C) 2018 Michael Muenz <m.muenz@gmail.com>
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.
*/
* Copyright (C) 2018 Michael Muenz <m.muenz@gmail.com>
* Copyright (C) 2023 Deciso B.V.
* 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\Dnscryptproxy;
use OPNsense\Base\BaseModel;
use OPNsense\Core\Backend;
use Phalcon\Messages\Message;
class General extends BaseModel
{
public function performValidation($validateFullModel = false)
{
$messages = parent::performValidation($validateFullModel);
if (
($validateFullModel || $this->enabled->isFieldChanged() || $this->listen_addresses->isFieldChanged()) &&
!empty((string)$this->enabled)
) {
$any4 = [];
$any6 = [];
$ports = [];
/* grab ALL ports to run a validation against, safer for user in the long run */
foreach (explode(',', (string)$this->listen_addresses) as $addrport) {
if (preg_match('/(.*):([\d]+)$/', $addrport, $matches)) {
$ports[$matches[2]] = 1;
if ($matches[1] == '0.0.0.0') {
$any4[$matches[2]] = 1;
} elseif ($matches[1] == '[::]') {
$any6[$matches[2]] = 1;
}
}
}
foreach (json_decode((new Backend())->configdpRun('service list'), true) as $service) {
if (empty($service['dns_ports'])) {
continue;
}
if ($service['name'] != 'dnscrypt-proxy' && count(array_intersect(array_keys($ports), $service['dns_ports']))) {
$messages->appendMessage(new Message(
sprintf(gettext('%s is currently using one of these ports.'), $service['description']),
$this->listen_addresses->getInternalXMLTagName()
));
break;
}
}
if (count(array_keys(array_intersect_key($any4, $any6)))) {
$messages->appendMessage(new Message(
gettext('Cannot configure on both "0.0.0.0" and "::" as the first occurence will be treated as dual-stack.'),
$this->listen_addresses->getInternalXMLTagName()
));
}
}
return $messages;
}
}
@@ -8,11 +8,11 @@
<Required>Y</Required>
</enabled>
<listen_addresses type="CSVListField">
<default>0.0.0.0:5353,[::]:5353</default>
<default>0.0.0.0:5353</default>
<Required>Y</Required>
</listen_addresses>
<allowprivileged type="BooleanField">
<default>0</default>
<default>1</default>
<Required>Y</Required>
</allowprivileged>
<max_clients type="IntegerField">
@@ -1,31 +1,29 @@
{#
OPNsense® is Copyright © 2014 2018 by Deciso B.V.
This file is Copyright © 2018 by Michael Muenz <m.muenz@gmail.com>
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.
#}
# Copyright (c) 2014-2018 Deciso B.V.
# Copyright (c) 2018 Michael Muenz <m.muenz@gmail.com>
# 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.
#}
<!-- Navigation bar -->
<ul class="nav nav-tabs" data-tabs="tabs" id="maintabs">
@@ -41,9 +39,8 @@ POSSIBILITY OF SUCH DAMAGE.
<div id="general" class="tab-pane fade in active">
<div class="content-box" style="padding-bottom: 1.5em;">
{{ partial("layout_partials/base_form",['fields':generalForm,'id':'frm_general_settings'])}}
<div class="col-md-12">
<hr />
<button class="btn btn-primary" id="saveAct" type="button"><b>{{ lang._('Save') }}</b><i id="saveAct_progress"></i></button>
<div class="col-md-12 __mt">
<button class="btn btn-primary" id="saveAct" type="button"><b>{{ lang._('Save') }}</b> <i id="saveAct_progress"></i></button>
</div>
</div>
</div>
@@ -71,7 +68,7 @@ POSSIBILITY OF SUCH DAMAGE.
</table>
<div class="col-md-12">
<hr />
<button class="btn btn-primary" id="saveAct_forward" type="button"><b>{{ lang._('Save') }}</b><i id="saveAct_forward_progress"></i></button>
<button class="btn btn-primary" id="saveAct_forward" type="button"><b>{{ lang._('Save') }}</b> <i id="saveAct_forward_progress"></i></button>
<br /><br />
</div>
</div>
@@ -99,7 +96,7 @@ POSSIBILITY OF SUCH DAMAGE.
</table>
<div class="col-md-12">
<hr />
<button class="btn btn-primary" id="saveAct_cloak" type="button"><b>{{ lang._('Save') }}</b><i id="saveAct_cloak_progress"></i></button>
<button class="btn btn-primary" id="saveAct_cloak" type="button"><b>{{ lang._('Save') }}</b> <i id="saveAct_cloak_progress"></i></button>
<br /><br />
</div>
</div>
@@ -126,7 +123,7 @@ POSSIBILITY OF SUCH DAMAGE.
</table>
<div class="col-md-12">
<hr />
<button class="btn btn-primary" id="saveAct_whitelist" type="button"><b>{{ lang._('Save') }}</b><i id="saveAct_whitelist_progress"></i></button>
<button class="btn btn-primary" id="saveAct_whitelist" type="button"><b>{{ lang._('Save') }}</b> <i id="saveAct_whitelist_progress"></i></button>
<br /><br />
</div>
</div>
@@ -154,15 +151,14 @@ POSSIBILITY OF SUCH DAMAGE.
</table>
<div class="col-md-12">
<hr />
<button class="btn btn-primary" id="saveAct_server" type="button"><b>{{ lang._('Save') }}</b><i id="saveAct_server_progress"></i></button>
<button class="btn btn-primary" id="saveAct_server" type="button"><b>{{ lang._('Save') }}</b> <i id="saveAct_server_progress"></i></button>
<br /><br />
</div>
</div>
<div id="dnsbl" class="tab-pane fade in">
<div class="content-box" style="padding-bottom: 1.5em;">
{{ partial("layout_partials/base_form",['fields':dnsblForm,'id':'frm_dnsbl_settings'])}}
<div class="col-md-12">
<hr />
<div class="col-md-12 __mt">
<button class="btn btn-primary" id="saveAct_dnsbl" type="button"><b>{{ lang._('Save') }}</b> <i id="saveAct_dnsbl_progress"></i></button>
</div>
</div>