Merge pull request #3926 from martgras/azureddns

This commit is contained in:
Steve Beaver 2018-04-03 09:18:10 -04:00
commit 83a0899662
3 changed files with 120 additions and 4 deletions

View File

@ -64,6 +64,7 @@
* - DreamHost DNS (www.dreamhost.com)
* - ClouDNS (www.cloudns.net)
* - GoDaddy (www.godaddy.com)
* - Azure DNS (azure.microsoft.com)
* +----------------------------------------------------+
* Requirements:
* - PHP version 4.0.2 or higher with the CURL Library and the PCRE Library
@ -123,6 +124,7 @@
* ClouDNS - Last Tested: 22 August 2017
* GoDaddy - Last Tested: 22 November 2017
* GoDaddy IPv6 - Last Tested: 22 November 2017
* Azure DNS - Last Tested: 08 March 2018
* +====================================================+
*
* @author E.Kristensen
@ -241,6 +243,14 @@
if (!$dnsDomain) $this->_error(5);
if (!$dnsTTL) $this->_error(9);
break;
case azure:
case azurev6:
if (!$dnsUser) $this->_error(3);
if (!$dnsPass) $this->_error(4);
if (!$dnsHost) $this->_error(5);
if (!$dnsZoneID) $this->_error(8);
if (!$dnsTTL) $this->_error(9);
break;
case 'custom':
if (!$dnsUpdateURL) $this->_error(7);
break;
@ -260,6 +270,7 @@
case 'cloudflare-v6':
case 'dreamhost-v6':
case 'godaddy-v6':
case 'azurev6':
$this->_useIPv6 = true;
break;
default:
@ -349,6 +360,8 @@
case 'hover':
case 'godaddy':
case 'godaddy-v6':
case 'azure':
case 'azurev6':
$this->_update();
if ($this->_dnsDummyUpdateDone == true) {
// If a dummy update was needed, then sleep a while and do the update again to put the proper address back.
@ -995,9 +1008,77 @@
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
break;
case 'azurev6':
case 'azure':
$hostname = "{$this->_dnsHost}";
$resourceid = trim($this->_dnsZoneID);
$app_id = $this->_dnsUser;
$client_secret = $this->_dnsPass;
$newip = $this->_dnsIP;
$newttl = $this->_dnsTTL;
// ensure resourceid starts with / and has no trailing /
$resourceid = '/' . trim($resourceid, '/');
// extract subscription id from resource id
preg_match('/\\/subscriptions\\/(?<sid>[^\\/]*)/', $resourceid, $result);
$subscriptionid = isset($result['sid']) ? $result['sid'] : '';
if (isset($result['sid'])) {
$subscriptionid = $result['sid'];
} else {
log_error("Azure subscription id not found in resource id");
return false;
}
// find tenant id from subscription id
curl_setopt($ch, CURLOPT_URL, "https://management.azure.com/subscriptions/" . $subscriptionid . "?api-version=2016-09-01");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
$output = curl_exec($ch);
$pattern = '/Bearer authorization_uri="https:\\/\\/login.windows.net\\/(?<tid>[^"]*)/i';
preg_match($pattern, $output, $result);
if (isset($result['tid'])) {
$tenantid = $result['tid'];
} else {
log_error("Tenant ID not found");
return false;
}
// get an bearer token
curl_setopt($ch, CURLOPT_URL, "https://login.microsoftonline.com/" . $tenantid . "/oauth2/token");
curl_setopt($ch, CURLOPT_POST, 1);
$body = "resource=" . urlencode("https://management.core.windows.net/") . "&grant_type=client_credentials&client_id=" . $app_id . "&client_secret=" . urlencode($client_secret);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
preg_match("/\"access_token\":\"(?<tok>[^\"]*)\"/", $server_output, $result);
if (isset($result['tok'])) {
$bearertoken = $result['tok'];
} else {
log_error("no valid bearer token");
return false;
}
// Update the DNS record
if ($this->_useIPv6) {
$url = "https://management.azure.com" . $resourceid . "/AAAA/" . $hostname . "?api-version=2017-09-01";
$body = '{"properties":{"TTL":"' . $newttl . '", "AaaaRecords":[{"ipv6Address":"' . $newip . '"}]}}';
} else {
$url = "https://management.azure.com" . $resourceid . "/A/" . $hostname . "?api-version=2017-09-01";
$body = '{"properties":{"TTL":"' . $newttl . '", "ARecords":[{"ipv4Address":"' . $newip . '"}]}}';
}
$request_headers = array();
$request_headers[] = 'Accept: application/json';
$request_headers[] = 'Authorization: Bearer ' . $bearertoken;
$request_headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERAGENT, $this->_UserAgent);
curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
break;
default:
break;
default:
break;
}
if ($this->_dnsService != 'ods') {
curl_setopt($ch, CURLOPT_HEADER, 1);
@ -1952,6 +2033,23 @@
default:
break;
}
case 'azure':
case 'azurev6':
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_code == 401) {
$status = $status_intro . $error_str . gettext("User Authorization Failed");
} else if ($http_code == 201) {
$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
$successful_update = true;
} else if ($http_code == 200) {
$status = $status_intro . $success_str . gettext("IP Address Changed Successfully!");
$successful_update = true;
} else {
$status = $status_intro . "(" . gettext("Unknown Response") . ")";
log_error($status_intro . gettext("PAYLOAD:") . " " . $http_code);
$this->_debug($data);
}
break;
default:
break;
}

View File

@ -24,8 +24,8 @@
*/
define('DYNDNS_PROVIDER_VALUES', 'all-inkl citynetwork cloudflare cloudflare-v6 cloudns custom custom-v6 dnsexit dnsimple dnsmadeeasy dnsomatic dreamhost dreamhost-v6 duiadns duiadns-v6 dyndns dyndns-custom dyndns-static dyns easydns eurodns freedns freedns-v6 glesys godaddy godaddy-v6 googledomains gratisdns he-net he-net-v6 he-net-tunnelbroker hover loopia namecheap noip noip-free ods opendns ovh-dynhost route53 route53-v6 selfhost spdyn spdyn-v6 zoneedit');
define('DYNDNS_PROVIDER_DESCRIPTIONS', 'All-Inkl.com,City Network,Cloudflare,Cloudflare (v6),ClouDNS,Custom,Custom (v6),DNSexit,DNSimple,DNS Made Easy,DNS-O-Matic,DreamHost,Dreamhost (v6),DuiaDns.net,DuiaDns.net (v6),DynDNS (dynamic),DynDNS (custom),DynDNS (static),DyNS,easyDNS,Euro Dns,freeDNS,freeDNS (v6),GleSYS,GoDaddy,GoDaddy (v6),Google Domains,GratisDNS,HE.net,HE.net (v6),HE.net Tunnelbroker,Hover,Loopia,Namecheap,No-IP,No-IP (free),ODS.org,OpenDNS,OVH DynHOST,Route 53,Route 53 (v6),SelfHost,SPDYN,SPDYN (v6),ZoneEdit');
define('DYNDNS_PROVIDER_VALUES', 'all-inkl azure azurev6 citynetwork cloudflare cloudflare-v6 cloudns custom custom-v6 dnsexit dnsimple dnsmadeeasy dnsomatic dreamhost dreamhost-v6 duiadns duiadns-v6 dyndns dyndns-custom dyndns-static dyns easydns eurodns freedns freedns-v6 glesys godaddy godaddy-v6 googledomains gratisdns he-net he-net-v6 he-net-tunnelbroker hover loopia namecheap noip noip-free ods opendns ovh-dynhost route53 route53-v6 selfhost spdyn spdyn-v6 zoneedit');
define('DYNDNS_PROVIDER_DESCRIPTIONS', 'All-Inkl.com,Azure DNS,Azure DNS (v6),City Network,Cloudflare,Cloudflare (v6),ClouDNS,Custom,Custom (v6),DNSexit,DNSimple,DNS Made Easy,DNS-O-Matic,DreamHost,Dreamhost (v6),DuiaDns.net,DuiaDns.net (v6),DynDNS (dynamic),DynDNS (custom),DynDNS (static),DyNS,easyDNS,Euro Dns,freeDNS,freeDNS (v6),GleSYS,GoDaddy,GoDaddy (v6),Google Domains,GratisDNS,HE.net,HE.net (v6),HE.net Tunnelbroker,Hover,Loopia,Namecheap,No-IP,No-IP (free),ODS.org,OpenDNS,OVH DynHOST,Route 53,Route 53 (v6),SelfHost,SPDYN,SPDYN (v6),ZoneEdit');
/* implement ipv6 route advertising daemon */
function services_radvd_configure($blacklist = array()) {

View File

@ -357,6 +357,7 @@ $section->addInput(new Form_Input(
'text',
$pconfig['username']
))->setHelp('Username is required for all types except Namecheap, FreeDNS and Custom Entries.%1$s' .
'Azure: Enter your Azure AD application ID%1$s' .
'DNS Made Easy: Dynamic DNS ID%1$s' .
'Route 53: Enter the Access Key ID.%1$s' .
'GleSYS: Enter the API user.%1$s' .
@ -370,6 +371,7 @@ $section->addPassword(new Form_Input(
'password',
$pconfig['password']
))->setHelp('FreeDNS (freedns.afraid.org): Enter the "Authentication Token" provided by FreeDNS.%1$s' .
'Azure: client secret of the AD application%1$s' .
'DNS Made Easy: Dynamic DNS Password%1$s' .
'Route 53: Enter the Secret Access Key.%1$s' .
'GleSYS: Enter the API key.%1$s' .
@ -384,6 +386,7 @@ $section->addInput(new Form_Input(
'text',
$pconfig['zoneid']
))->setHelp('Route53: Enter AWS Zone ID.%1$s' .
'Azure: Enter the resource id of the of the DNS Zone%1$s' .
'DNSimple: Enter the Record ID of record to update.', '<br />');
$section->addInput(new Form_Input(
@ -553,6 +556,21 @@ events.push(function() {
hideInput('zoneid', true);
hideInput('ttl', false);
break;
case "azurev6":
case "azure":
hideGroupInput('domainname', true);
hideInput('resultmatch', true);
hideInput('updateurl', true);
hideInput('requestif', true);
hideCheckbox('curl_ipresolve_v4', true);
hideCheckbox('curl_ssl_verifypeer', true);
hideInput('host', false);
hideInput('mx', true);
hideCheckbox('wildcard', true);
hideCheckbox('proxied', true);
hideInput('zoneid', false);
hideInput('ttl', false);
break;
default:
hideGroupInput('domainname', true);
hideInput('resultmatch', true);