diff --git a/dns/ddclient/src/opnsense/mvc/app/models/OPNsense/DynDNS/DynDNS.xml b/dns/ddclient/src/opnsense/mvc/app/models/OPNsense/DynDNS/DynDNS.xml
index 6eac4cd24..75c390ce1 100644
--- a/dns/ddclient/src/opnsense/mvc/app/models/OPNsense/DynDNS/DynDNS.xml
+++ b/dns/ddclient/src/opnsense/mvc/app/models/OPNsense/DynDNS/DynDNS.xml
@@ -146,6 +146,7 @@
cloudflare
cloudflare-ipv4
cloudflare-ipv6
+ cloudflare-dns
dynu-ipv4
dynu-ipv6
freedns
diff --git a/dns/ddclient/src/opnsense/scripts/ddclient/checkip b/dns/ddclient/src/opnsense/scripts/ddclient/checkip
index 0f5126552..08d9edc6f 100755
--- a/dns/ddclient/src/opnsense/scripts/ddclient/checkip
+++ b/dns/ddclient/src/opnsense/scripts/ddclient/checkip
@@ -26,13 +26,13 @@
POSSIBILITY OF SUCH DAMAGE.
"""
import argparse
-from lib import checkip_service_list, checkip
+from lib import registered_services, checkip
if __name__ == '__main__':
# handle parameters
parser = argparse.ArgumentParser()
- parser.add_argument('-s', '--service', help='service name', choices=checkip_service_list.keys(), required=True)
+ parser.add_argument('-s', '--service', help='service name', choices=registered_services(), required=True)
parser.add_argument('-i', '--interface', help='interface', type=str, default='')
parser.add_argument('-t', '--tls', help='enforce tls', choices=['0', '1'], default='1')
parser.add_argument('--timeout', help='timeout', type=str, default='10')
diff --git a/dns/ddclient/src/opnsense/scripts/ddclient/lib/__init__.py b/dns/ddclient/src/opnsense/scripts/ddclient/lib/__init__.py
index 025fbe05a..762f022d1 100755
--- a/dns/ddclient/src/opnsense/scripts/ddclient/lib/__init__.py
+++ b/dns/ddclient/src/opnsense/scripts/ddclient/lib/__init__.py
@@ -57,5 +57,5 @@
changed (return status of `execute()`) the state is flushed to disk.
"""
-from .address import checkip_service_list, checkip
+from .address import registered_services, checkip
from .poller import AccountFactory, Poller
diff --git a/dns/ddclient/src/opnsense/scripts/ddclient/lib/address.py b/dns/ddclient/src/opnsense/scripts/ddclient/lib/address.py
index 44ad79299..396b4720b 100755
--- a/dns/ddclient/src/opnsense/scripts/ddclient/lib/address.py
+++ b/dns/ddclient/src/opnsense/scripts/ddclient/lib/address.py
@@ -26,6 +26,8 @@
import subprocess
import re
import ipaddress
+import dns.resolver
+import dns.rdataclass
from urllib.parse import urlparse
checkip_service_list = {
@@ -51,6 +53,19 @@ checkip_service_list = {
'zoneedit': '%s://dynamic.zoneedit.com/checkip.html'
}
+checkip_dns_list = {
+ 'cloudflare-dns': {
+ 'nameservers': ['1.1.1.1','1.0.0.1'],
+ 'resolve_params': {
+ 'qname': 'whoami.cloudflare',
+ 'rdtype': 'TXT',
+ 'rdclass': dns.rdataclass.from_text('CH')
+ }
+ }
+}
+
+def registered_services():
+ return list(checkip_service_list.keys()) + list(checkip_dns_list.keys())
def extract_address(host, txt):
""" Extract first IPv4 or IPv6 address from provided string
@@ -87,17 +102,17 @@ def transform_ip(ip, ipv6host=None):
def checkip(service, proto='https', timeout='10', interface=None, dynipv6host=None):
- """ find ip address using external services defined in checkip_service_list
+ """ find ip address using external web services defined in checkip_service_list
+ or dns services defined in checkip_dns_list
:param proto: protocol
:param timeout: timeout in seconds
:param interface: bind to interface
:param dynipv6host: optional partial ipv6 address
:return: str
"""
- if service.startswith('web_'):
+ if service.lstrip('web_') in checkip_service_list:
# configuration name, strip web_ part
- service = service[4:]
- if service in checkip_service_list:
+ service = service.lstrip('web_')
params = ['/usr/local/bin/curl', '-m', timeout]
if interface is not None:
params.append("--interface")
@@ -124,5 +139,15 @@ def checkip(service, proto='https', timeout='10', interface=None, dynipv6host=No
return str(address)
except ValueError:
continue
+ elif service.lstrip('dns_') in checkip_dns_list:
+ svc_info = checkip_dns_list[service.lstrip('dns_')]
+ resolve_params = svc_info['resolve_params']
+ dns_resolver = dns.resolver.Resolver()
+ dns_resolver.nameservers = svc_info['nameservers']
+ try:
+ dns_response = dns_resolver.resolve(**resolve_params)
+ return dns_response[0].to_text().strip('"')
+ except:
+ return ""
else:
return ""