From de633be28aef9cd1b4b4e3dbd8d93b8bf74e501c Mon Sep 17 00:00:00 2001 From: Charles Ulrich Date: Sun, 16 Dec 2018 19:11:13 -0500 Subject: [PATCH] dns/dyndns: Fix for using apex domains with cloudflare DDNS When refactoring the Cloudflare DDNS code, I removed a bunch of assumptions but inadvertently added one. The refactored code did not allow for "apex" domain records, records for which there is no hostname, just the bare domain. (Traditionally, these have been referred to as '@' records but with the Cloudflare API, you just hand it the name of the zone.) Ideally there would be a checkbox or something in the UI for this, or even better a way to specify the record and zone separately but in lieu of that, we first try to break the provided string down into hostname and domain portions and look up the zoneId from that. If that fails, we try to look up the zondId using the whole string. And then finally fail if neither return a zone from the API. Hopefully fixes #926 and possibly the issue reported in PR #861. (cherry picked from commit 2b4f2c8750e3fb7bf2648f90ad228dc4e087c120) (cherry picked from commit ddb72d981d34cdd2e624e594312229f14be2dd6b) --- dns/dyndns/Makefile | 3 +-- .../etc/inc/plugins.inc.d/dyndns/phpDynDNS.inc | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/dns/dyndns/Makefile b/dns/dyndns/Makefile index 0903a01b1..928e6c172 100644 --- a/dns/dyndns/Makefile +++ b/dns/dyndns/Makefile @@ -1,6 +1,5 @@ PLUGIN_NAME= dyndns -PLUGIN_VERSION= 1.10 -PLUGIN_REVISION= 1 +PLUGIN_VERSION= 1.11 PLUGIN_COMMENT= Dynamic DNS Support PLUGIN_MAINTAINER= franco@opnsense.org diff --git a/dns/dyndns/src/etc/inc/plugins.inc.d/dyndns/phpDynDNS.inc b/dns/dyndns/src/etc/inc/plugins.inc.d/dyndns/phpDynDNS.inc index 72e45d73b..556fe2166 100644 --- a/dns/dyndns/src/etc/inc/plugins.inc.d/dyndns/phpDynDNS.inc +++ b/dns/dyndns/src/etc/inc/plugins.inc.d/dyndns/phpDynDNS.inc @@ -713,9 +713,6 @@ class updatedns case 'cloudflare-v6': $baseUrl = 'https://api.cloudflare.com/client/v4'; $fqdn = str_replace(' ', '', $this->_dnsHost); - $fqdnParts = explode('.', $fqdn); - $hostName = array_shift($fqdnParts); - $domainName = implode('.', $fqdnParts); $recordType = ($this->_useIPv6) ? 'AAAA' : 'A'; $hostData = array( "content" => "{$this->_dnsIP}", @@ -732,10 +729,24 @@ class updatedns // Get zone ID $zonesUrl = "$baseUrl/zones"; + // First, try removing the first part of the FQDN, + // under the assumption that it is probably the hostname, + // and look up the zone from what's left + $fqdnParts = explode('.', $fqdn); + $hostName = array_shift($fqdnParts); + $domainName = implode('.', $fqdnParts); $getZoneId = "$zonesUrl/?name=$domainName"; curl_setopt($ch, CURLOPT_URL, $getZoneId); $output = json_decode(curl_exec($ch)); $zoneId = $output->result[0]->id; + if (empty($zoneId)) { + // now try the full "hostname" as provided by the UI + $getZoneId = "$zonesUrl/?name=$fqdn"; + curl_setopt($ch, CURLOPT_URL, $getZoneId); + $output = json_decode(curl_exec($ch)); + $zoneId = $output->result[0]->id; + } + if ($zoneId) { // If zone ID was found get host ID $dnsRecordsUrl = "$zonesUrl/$zoneId/dns_records"; $getHostId = "$dnsRecordsUrl?name=$fqdn&type=$recordType";