mirror of
https://github.com/netbirdio/plugins.git
synced 2026-05-22 18:44:07 -07:00
Merge branch 'opnsense:master' into master
This commit is contained in:
@@ -19,8 +19,8 @@ Copyright (c) 2008-2010 Ermal Luçi
|
||||
Copyright (c) 2016-2019 EURO-LOG AG
|
||||
Copyright (c) 2017-2020 Fabian Franz
|
||||
Copyright (c) 2019 Felix Matouschek <felix@matouschek.org>
|
||||
Copyright (c) 2014-2022 Franco Fichtner <franco@opnsense.org>
|
||||
Copyright (c) 2016-2022 Frank Wall
|
||||
Copyright (c) 2014-2023 Franco Fichtner <franco@opnsense.org>
|
||||
Copyright (c) 2016-2023 Frank Wall
|
||||
Copyright (c) 2021 Github-jjw
|
||||
Copyright (c) 2016 IT-assistans Sverige AB
|
||||
Copyright (c) 2021-2023 Jan Winkler
|
||||
@@ -50,6 +50,7 @@ Copyright (c) 2008 Shrew Soft Inc. <mgrooms@shrew.net>
|
||||
Copyright (c) 2017-2019 Smart-Soft
|
||||
Copyright (c) 2013 Stanley P. Miller \ stan-qaz
|
||||
Copyright (c) 2020 Starkstromkonsument
|
||||
Copyright (c) 2023 Thomas Cekal <thomas@cekal.org>
|
||||
Copyright (c) 2020 Tobias Boehnert
|
||||
Copyright (c) 2022 Wouter Deurholt
|
||||
Copyright (c) 2010 Yehuda Katz
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2015-2020 Franco Fichtner <franco@opnsense.org>
|
||||
# Copyright (c) 2015-2023 Franco Fichtner <franco@opnsense.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
|
||||
+6
-3
@@ -132,6 +132,9 @@ manifest: check
|
||||
done
|
||||
@echo "}"
|
||||
.endif
|
||||
@if [ -f ${WRKSRC}/usr/local/opnsense/version/${PLUGIN_NAME} ]; then \
|
||||
echo "annotations $$(cat ${WRKSRC}/usr/local/opnsense/version/${PLUGIN_NAME})"; \
|
||||
fi
|
||||
|
||||
scripts: check scripts-pre scripts-auto scripts-manual scripts-post
|
||||
|
||||
@@ -256,14 +259,14 @@ package: check
|
||||
.for DEP in ${PLUGIN_DEPENDS}
|
||||
@if ! ${PKG} info ${DEP} > /dev/null; then ${PKG} install -yA ${DEP}; fi
|
||||
.endfor
|
||||
@echo -n ">>> Generating metadata for ${PLUGIN_PKGNAME}-${PLUGIN_PKGVERSION}..."
|
||||
@${MAKE} DESTDIR=${WRKSRC} metadata
|
||||
@echo " done"
|
||||
@echo -n ">>> Staging files for ${PLUGIN_PKGNAME}-${PLUGIN_PKGVERSION}..."
|
||||
@${MAKE} DESTDIR=${WRKSRC} install
|
||||
@echo " done"
|
||||
@echo ">>> Generated version info for ${PLUGIN_PKGNAME}-${PLUGIN_PKGVERSION}:"
|
||||
@cat ${WRKSRC}/usr/local/opnsense/version/${PLUGIN_NAME}
|
||||
@echo -n ">>> Generating metadata for ${PLUGIN_PKGNAME}-${PLUGIN_PKGVERSION}..."
|
||||
@${MAKE} DESTDIR=${WRKSRC} metadata
|
||||
@echo " done"
|
||||
@echo ">>> Packaging files for ${PLUGIN_PKGNAME}-${PLUGIN_PKGVERSION}:"
|
||||
@${PKG} create -v -m ${WRKSRC} -r ${WRKSRC} \
|
||||
-p ${WRKSRC}/plist -o ${PKGDIR}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
PLUGIN_NAME= bind
|
||||
PLUGIN_VERSION= 1.26
|
||||
PLUGIN_REVISION= 2
|
||||
PLUGIN_REVISION= 4
|
||||
PLUGIN_COMMENT= BIND domain name service
|
||||
PLUGIN_DEPENDS= bind918
|
||||
PLUGIN_MAINTAINER= m.muenz@gmail.com
|
||||
|
||||
@@ -14,6 +14,8 @@ Plugin Changelog
|
||||
|
||||
* Allow multiple ACLs to be selected for Transfers/Queries (contributed by Robbert Rijkse)
|
||||
* Rename Master/Slave to Primary/Secondary (contributed by Robbert Rijkse)
|
||||
* 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
|
||||
|
||||
1.25
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Michael Muenz <m.muenz@gmail.com>
|
||||
* Copyright (C) 2023 Franco Fichtner <franco@opnsense.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -49,9 +50,22 @@ function bind_services()
|
||||
|
||||
$model = new \OPNsense\Bind\General();
|
||||
|
||||
/* DNS service is eligable for core use when both 0.0.0.0 and :: are set */
|
||||
$any4 = false;
|
||||
$any6 = false;
|
||||
|
||||
foreach (explode(',', (string)$model->listenv4) as $addr) {
|
||||
$any4 |= $addr === '0.0.0.0';
|
||||
}
|
||||
|
||||
foreach (explode(',', (string)$model->listenv6) as $addr) {
|
||||
$any6 |= $addr === '::';
|
||||
}
|
||||
|
||||
$services[] = [
|
||||
/* the port may still be something other than 53, but it's safe to register a conflict for it */
|
||||
'dns_ports' => ($any4 && $any6 ? [(string)$model->port] : []),
|
||||
'description' => gettext('BIND Daemon'),
|
||||
'ports' => [(string)$model->port],
|
||||
'configd' => [
|
||||
'restart' => ['bind restart'],
|
||||
'start' => ['bind start'],
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
<Required>Y</Required>
|
||||
</enablerpz>
|
||||
<listenv4 type="NetworkField">
|
||||
<default>127.0.0.1</default>
|
||||
<default>0.0.0.0</default>
|
||||
<FieldSeparator>,</FieldSeparator>
|
||||
<Required>Y</Required>
|
||||
<asList>Y</asList>
|
||||
</listenv4>
|
||||
<listenv6 type="NetworkField">
|
||||
<default>::1</default>
|
||||
<default>::</default>
|
||||
<FieldSeparator>,</FieldSeparator>
|
||||
<Required>Y</Required>
|
||||
<asList>Y</asList>
|
||||
@@ -149,7 +149,7 @@
|
||||
<ValidationMessage>Choose a value between 1 and 1000.</ValidationMessage>
|
||||
</ratelimitcount>
|
||||
<ratelimitexcept type="NetworkField">
|
||||
<default>127.0.0.1,::1</default>
|
||||
<default>0.0.0.0,::</default>
|
||||
<FieldSeparator>,</FieldSeparator>
|
||||
<Required>Y</Required>
|
||||
<asList>Y</asList>
|
||||
|
||||
@@ -68,7 +68,7 @@ options {
|
||||
{% if helpers.exists('OPNsense.bind.general.allowquery') and OPNsense.bind.general.allowquery != '' %}
|
||||
allow-query {
|
||||
{% for acl in helpers.toList('OPNsense.bind.general.allowquery') %}
|
||||
{% set query_acl = helpers.getUUID(list) %}
|
||||
{% set query_acl = helpers.getUUID(acl) %}
|
||||
{{ query_acl.name }};
|
||||
{% endfor %}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
PLUGIN_NAME= ddclient
|
||||
PLUGIN_VERSION= 1.11
|
||||
PLUGIN_REVISION= 1
|
||||
PLUGIN_VERSION= 1.13
|
||||
PLUGIN_DEPENDS= ddclient-devel
|
||||
PLUGIN_COMMENT= Dynamic DNS client
|
||||
PLUGIN_MAINTAINER= ad@opnsense.org
|
||||
|
||||
@@ -6,6 +6,18 @@ WWW: https://github.com/ddclient/ddclient
|
||||
Plugin Changelog
|
||||
================
|
||||
|
||||
1.13
|
||||
|
||||
* Fix not returning IP address as a string in Python backend (contributed by Sean Kelly)
|
||||
* Fix PID file handling for Python backend
|
||||
|
||||
1.12
|
||||
|
||||
* Add cloudflare implementation for Python backend (contributed by Thomas Cekal)
|
||||
* Allow custom target hostname for dyndns2 protocol in Python backend
|
||||
* Adjust for missing ipv6= option including upstream patches for use=/usev4=/usev6=
|
||||
* Require a selected interface through validation when interface check method is used
|
||||
|
||||
1.11
|
||||
|
||||
* Add Python backend support for custom ddclient-like implementation using the same input
|
||||
|
||||
@@ -30,39 +30,46 @@
|
||||
function ddclient_services()
|
||||
{
|
||||
$services = [];
|
||||
|
||||
$mdl = new \OPNsense\DynDNS\DynDNS();
|
||||
if ($mdl->general->enabled == '1') {
|
||||
$services[] = [
|
||||
$service = [
|
||||
'description' => gettext('ddclient'),
|
||||
'configd' => [
|
||||
'restart' => array('ddclient restart'),
|
||||
'start' => array('ddclient start'),
|
||||
'stop' => array('ddclient stop'),
|
||||
'restart' => ['ddclient restart'],
|
||||
'start' => ['ddclient start'],
|
||||
'stop' => ['ddclient stop'],
|
||||
],
|
||||
'name' => 'ddclient',
|
||||
'pidfile' => '/var/run/ddclient.pid',
|
||||
];
|
||||
$service['pidfile'] = (string)$mdl->general->backend != 'opnsense' ? '/var/run/ddclient.pid' : '/var/run/ddclient_opn.pid';
|
||||
$services[] = $service;
|
||||
}
|
||||
|
||||
return $services;
|
||||
}
|
||||
|
||||
function ddclient_xmlrpc_sync()
|
||||
{
|
||||
$result = array();
|
||||
$result[] = array(
|
||||
$result = [];
|
||||
|
||||
$result[] = [
|
||||
'description' => gettext('ddclient'),
|
||||
'section' => 'OPNsense.DynDNS',
|
||||
'id' => 'ddclient',
|
||||
'services' => ['ddclient'],
|
||||
);
|
||||
'id' => 'ddclient',
|
||||
];
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function ddclient_syslog()
|
||||
{
|
||||
$logfacilities = array();
|
||||
$logfacilities['ddclient'] = array(
|
||||
'facility' => ['ddclient']
|
||||
);
|
||||
$logfacilities = [];
|
||||
|
||||
$logfacilities['ddclient'] = [
|
||||
'facility' => ['ddclient'],
|
||||
];
|
||||
|
||||
return $logfacilities;
|
||||
}
|
||||
|
||||
+10
-10
@@ -5,6 +5,11 @@
|
||||
<type>checkbox</type>
|
||||
<help>Enable this virtual server</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>account.description</id>
|
||||
<label>Description</label>
|
||||
<type>text</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>account.service</id>
|
||||
<label>Service</label>
|
||||
@@ -71,6 +76,11 @@
|
||||
<type>dropdown</type>
|
||||
<help>How to determine the address to use for this host</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>account.interface</id>
|
||||
<label>Interface to monitor</label>
|
||||
<type>dropdown</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>account.checkip_timeout</id>
|
||||
<label>Check ip timeout</label>
|
||||
@@ -84,14 +94,4 @@
|
||||
<help>Force update using HTTPS, please note setting this option will enforce https updates on all accounts
|
||||
as ddclient only supports SSL=yes on a global level (the check ip service may still use HTTP on other services)</help>
|
||||
</field>
|
||||
<field>
|
||||
<id>account.interface</id>
|
||||
<label>Interface to monitor</label>
|
||||
<type>dropdown</type>
|
||||
</field>
|
||||
<field>
|
||||
<id>account.description</id>
|
||||
<label>Description</label>
|
||||
<type>text</type>
|
||||
</field>
|
||||
</form>
|
||||
|
||||
@@ -153,6 +153,11 @@
|
||||
<web_zoneedit>zoneedit</web_zoneedit>
|
||||
<if>Interface</if>
|
||||
</OptionValues>
|
||||
<Constraints>
|
||||
<check001>
|
||||
<reference>interface.check001</reference>
|
||||
</check001>
|
||||
</Constraints>
|
||||
</checkip>
|
||||
<checkip_timeout type="IntegerField">
|
||||
<default>10</default>
|
||||
@@ -167,6 +172,14 @@
|
||||
<interface type="InterfaceField">
|
||||
<Required>N</Required>
|
||||
<multiple>N</multiple>
|
||||
<Constraints>
|
||||
<check001>
|
||||
<ValidationMessage>An interface is required for the selected check method</ValidationMessage>
|
||||
<type>SetIfConstraint</type>
|
||||
<field>checkip</field>
|
||||
<check>if</check>
|
||||
</check001>
|
||||
</Constraints>
|
||||
</interface>
|
||||
<description type="TextField">
|
||||
<Required>N</Required>
|
||||
|
||||
@@ -85,10 +85,7 @@ class Azure(BaseAccount):
|
||||
return Azure._services
|
||||
|
||||
def match(account):
|
||||
if account.get('service') in Azure._services:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
return account.get('service') in Azure._services
|
||||
|
||||
def execute(self):
|
||||
""" Azure DNS update, uses an oauth2 sequence to login, the following requests are being performed:
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
"""
|
||||
Copyright (c) 2023 Thomas Cekal <thomas@cekal.org>
|
||||
Copyright (c) 2023 Ad Schellevis <ad@opnsense.org>
|
||||
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.
|
||||
"""
|
||||
import json
|
||||
import syslog
|
||||
import requests
|
||||
from . import BaseAccount
|
||||
|
||||
|
||||
class Cloudflare(BaseAccount):
|
||||
_priority = 65535
|
||||
|
||||
_services = {
|
||||
'cloudflare': 'api.cloudflare.com'
|
||||
}
|
||||
|
||||
def __init__(self, account: dict):
|
||||
super().__init__(account)
|
||||
|
||||
@staticmethod
|
||||
def known_services():
|
||||
return Cloudflare._services.keys()
|
||||
|
||||
def match(account):
|
||||
return account.get('service') in Cloudflare._services
|
||||
|
||||
def execute(self):
|
||||
if super().execute():
|
||||
# IPv4/IPv6
|
||||
recordType = None
|
||||
if str(self.current_address).find(':') > 1:
|
||||
#IPv6
|
||||
recordType = "AAAA"
|
||||
else:
|
||||
#IPv4
|
||||
recordType = "A"
|
||||
|
||||
# get ZoneID
|
||||
url = "https://%s/client/v4/zones" % self._services[self.settings.get('service')]
|
||||
req_opts = {
|
||||
'url': url,
|
||||
'params': {
|
||||
'name': self.settings.get('zone')
|
||||
},
|
||||
'headers': {
|
||||
'User-Agent': 'OPNsense-dyndns',
|
||||
'X-Auth-Email': self.settings.get('username'),
|
||||
'X-Auth-Key': self.settings.get('password')
|
||||
}
|
||||
}
|
||||
response = requests.get(**req_opts)
|
||||
try:
|
||||
payload = response.json()
|
||||
except requests.exceptions.JSONDecodeError:
|
||||
payload = {}
|
||||
if 'success' not in payload:
|
||||
syslog.syslog(
|
||||
syslog.LOG_ERR,
|
||||
"Account %s error parsing JSON response [ZoneID] %s" % (self.description, response.text)
|
||||
)
|
||||
return
|
||||
if not payload.get('success', False):
|
||||
syslog.syslog(
|
||||
syslog.LOG_ERR,
|
||||
"Account %s error receiving ZoneID [%s]" % (self.description, json.dumps(payload.get('errors', {})))
|
||||
)
|
||||
return
|
||||
|
||||
zone_id = payload['result'][0]['id']
|
||||
if self.is_verbose:
|
||||
syslog.syslog(
|
||||
syslog.LOG_NOTICE,
|
||||
"Account %s ZoneID for %s %s" % (self.description, self.settings.get('zone'), zone_id)
|
||||
)
|
||||
|
||||
# Get record ID
|
||||
req_opts = {
|
||||
'url': f"{req_opts['url']}/{zone_id}/dns_records",
|
||||
'params': {
|
||||
'name': self.settings.get('hostnames'),
|
||||
'type': recordType
|
||||
},
|
||||
'headers': req_opts['headers']
|
||||
}
|
||||
response = requests.get(**req_opts)
|
||||
try:
|
||||
payload = response.json()
|
||||
except requests.exceptions.JSONDecodeError:
|
||||
payload = {}
|
||||
if 'success' not in payload:
|
||||
syslog.syslog(
|
||||
syslog.LOG_ERR,
|
||||
"Account %s error parsing JSON response [RecordID] %s" % (self.description, response.text)
|
||||
)
|
||||
return
|
||||
if not payload.get('success', False):
|
||||
syslog.syslog(
|
||||
syslog.LOG_ERR,
|
||||
"Account %s error receiving RecordID [%s]" % (
|
||||
self.description, json.dumps(payload.get('errors', {}))
|
||||
)
|
||||
)
|
||||
return
|
||||
|
||||
record_id = payload['result'][0]['id']
|
||||
if self.is_verbose:
|
||||
syslog.syslog(
|
||||
syslog.LOG_NOTICE,
|
||||
"Account %s RecordID for %s %s" % (self.description, self.settings.get('hostnames'), record_id)
|
||||
)
|
||||
|
||||
# Send IP address update
|
||||
req_opts = {
|
||||
'url': f"{req_opts['url']}/{record_id}",
|
||||
'json': {
|
||||
'type': recordType,
|
||||
'name': self.settings.get('hostnames'),
|
||||
'content': str(self.current_address)
|
||||
},
|
||||
'headers': req_opts['headers']
|
||||
}
|
||||
response = requests.put(**req_opts)
|
||||
try:
|
||||
payload = response.json()
|
||||
except requests.exceptions.JSONDecodeError:
|
||||
payload = {}
|
||||
if 'success' not in payload:
|
||||
syslog.syslog(
|
||||
syslog.LOG_ERR,
|
||||
"Account %s error parsing JSON response [UpdateIP] %s" % (self.description, response.text)
|
||||
)
|
||||
return
|
||||
if payload.get('success', False):
|
||||
syslog.syslog(
|
||||
syslog.LOG_NOTICE,
|
||||
"Account %s set new ip %s [%s]" % (
|
||||
self.description,
|
||||
self.current_address,
|
||||
payload.get('result', {}).get('content', '')
|
||||
)
|
||||
)
|
||||
|
||||
self.update_state(address=self.current_address)
|
||||
return True
|
||||
else:
|
||||
syslog.syslog(
|
||||
syslog.LOG_ERR,
|
||||
"Account %s failed to set new ip %s [%s]" % (self.description, self.current_address, response.text)
|
||||
)
|
||||
|
||||
|
||||
return False
|
||||
@@ -53,7 +53,7 @@ class DynDNS2(BaseAccount):
|
||||
|
||||
@staticmethod
|
||||
def known_services():
|
||||
return DynDNS2._services.keys()
|
||||
return list(DynDNS2._services.keys()) + ['custom']
|
||||
|
||||
def match(account):
|
||||
if account.get('service') in DynDNS2._services or (
|
||||
|
||||
@@ -91,7 +91,7 @@ def checkip(service, proto='https', timeout='10', interface=None):
|
||||
try:
|
||||
address = ipaddress.ip_address(parts[1])
|
||||
if address.is_global:
|
||||
return address
|
||||
return str(address)
|
||||
except ValueError:
|
||||
continue
|
||||
else:
|
||||
|
||||
@@ -12,10 +12,7 @@ type:script
|
||||
message:stopping ddclient
|
||||
|
||||
[status]
|
||||
command:
|
||||
pgrep -qF /var/run/ddclient.pid 2> /dev/null && echo "ddclient is running" ||
|
||||
pgrep -qF /var/run/ddclient_opn.pid 2> /dev/null && echo "ddclient is running" ||
|
||||
echo "ddclient is not running"
|
||||
command:/usr/local/sbin/pluginctl -s ddclient status
|
||||
type:script_output
|
||||
message:get ddclient status
|
||||
|
||||
|
||||
@@ -4,9 +4,7 @@ pid=/var/run/ddclient.pid # record PID in file.
|
||||
{% if not helpers.empty('OPNsense.DynDNS.general.verbose') %}
|
||||
verbose=yes
|
||||
{% endif %}
|
||||
{% if not helpers.empty('OPNsense.DynDNS.general.allowipv6') %}
|
||||
ipv6=yes
|
||||
{% endif %}
|
||||
|
||||
{% set accounts = [] %}
|
||||
{% set force_ssl = [] %}
|
||||
{% if helpers.exists('OPNsense.DynDNS.accounts.account') and OPNsense.DynDNS.general.backend|default('ddclient') == 'ddclient' %}
|
||||
@@ -23,10 +21,12 @@ ipv6=yes
|
||||
ssl=yes
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% for account in accounts %}
|
||||
{% if account.checkip == 'if' %}
|
||||
use=if, if={{physical_interface(account.interface)}}, \
|
||||
{% if account.checkip == 'if' %}
|
||||
{% if not helpers.empty('OPNsense.DynDNS.general.allowipv6') %}
|
||||
usev6=ifv6, \
|
||||
{% endif %}
|
||||
usev4=ifv4, if={{physical_interface(account.interface)}}, \
|
||||
{% elif account.checkip.startswith('web_') %}
|
||||
{% if account.interface %}
|
||||
use=cmd, cmd="/usr/local/opnsense/scripts/ddclient/checkip -i {{physical_interface(account.interface)}} -t {{account.force_ssl}} -s {{account.checkip[4:]}} --timeout {{account.checkip_timeout|default('10')}}",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
PLUGIN_NAME= dnscrypt-proxy
|
||||
PLUGIN_VERSION= 1.12
|
||||
PLUGIN_REVISION= 1
|
||||
PLUGIN_VERSION= 1.13
|
||||
PLUGIN_COMMENT= Flexible DNS proxy supporting DNSCrypt and DoH
|
||||
PLUGIN_DEPENDS= dnscrypt-proxy2
|
||||
PLUGIN_MAINTAINER= m.muenz@gmail.com
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user