Revision d9d91d5d
Added by Nita Vesa almost 2 years ago
src/etc/inc/dyndns.class | ||
---|---|---|
71 | 71 |
* - Namecheap (namecheap.com) |
72 | 72 |
* - No-IP (no-ip.com) |
73 | 73 |
* - OpenDNS (opendns.com) |
74 |
* - Porkbun (porkbun.com) |
|
74 | 75 |
* - SelfHost (selfhost.de) |
75 | 76 |
* - SPDYN (spdyn.de) |
76 | 77 |
* - SPDYN IPv6 (spdyn.de) |
... | ... | |
141 | 142 |
* ODS - Last Tested: 02 August 2005 |
142 | 143 |
* OpenDNS - Last Tested: 4 August 2008 |
143 | 144 |
* OVH DynHOST - Last Tested: NEVER |
145 |
* Porkbun - Last Tested: 26 June 2023 |
|
144 | 146 |
* SelfHost - Last Tested: 26 December 2011 |
145 | 147 |
* SPDYN - Last Tested: 02 July 2016 |
146 | 148 |
* SPDYN IPv6 - Last Tested: 02 July 2016 |
... | ... | |
309 | 311 |
if (!$dnsZoneID) $this->_error(8); |
310 | 312 |
if (!$dnsTTL) $this->_error(9); |
311 | 313 |
break; |
314 |
case 'porkbun': |
|
315 |
case 'porkbun-v6': |
|
316 |
if (!$dnsUser) $this->_error(3); |
|
317 |
if (!$dnsPass) $this->_error(4); |
|
318 |
if (!$dnsHost) $this->_error(5); |
|
319 |
if (!$dnsDomain) $this->_error(5); |
|
320 |
break; |
|
312 | 321 |
default: |
313 | 322 |
if (!$dnsUser) $this->_error(3); |
314 | 323 |
if (!$dnsPass) $this->_error(4); |
... | ... | |
337 | 346 |
case 'name.com-v6': |
338 | 347 |
case 'noip-free-v6': |
339 | 348 |
case 'noip-v6': |
349 |
case 'porkbun-v6': |
|
340 | 350 |
case 'route53-v6': |
341 | 351 |
case 'spdyn-v6': |
342 | 352 |
case 'yandex-v6': |
... | ... | |
464 | 474 |
case 'ods': |
465 | 475 |
case 'opendns': |
466 | 476 |
case 'ovh-dynhost': |
477 |
case 'porkbun': |
|
478 |
case 'porkbun-v6': |
|
467 | 479 |
case 'route53': |
468 | 480 |
case 'route53-v6': |
469 | 481 |
case 'selfhost': |
... | ... | |
949 | 961 |
$server = "https://api.nic.ru/dyndns/update?hostname={$this->_dnsHost}&{$iptype}={$this->_dnsIP}"; |
950 | 962 |
curl_setopt($ch, CURLOPT_URL, $server); |
951 | 963 |
break; |
964 |
case 'porkbun': |
|
965 |
case 'porkbun-v6': |
|
966 |
// API documentation: https://porkbun.com/api/json/v3/documentation |
|
967 |
$porkbun_api = "https://porkbun.com/api/json/v3/dns/retrieve/{$this->_dnsDomain}"; |
|
968 |
$record_type = $this->_useIPv6 ? "AAAA" : "A"; |
|
969 |
// Check if a record already exists for this host. |
|
970 |
$post_data['apikey'] = $this->_dnsUser; |
|
971 |
$post_data['secretapikey'] = $this->_dnsPass; |
|
972 |
curl_setopt($ch, CURLOPT_URL, "{$porkbun_api}"); |
|
973 |
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data)); |
|
974 |
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); |
|
975 |
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); |
|
976 |
$response = json_decode(curl_exec($ch), true); |
|
977 |
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); |
|
978 |
if ($http_code != "200") { |
|
979 |
log_error(gettext("Error message: ") . $response); |
|
980 |
return false; |
|
981 |
} |
|
982 |
if (!is_array($response["records"])) { |
|
983 |
log_error(gettext("Unexpected response: ") . $response); |
|
984 |
return false; |
|
985 |
} |
|
986 |
foreach($response["records"] as $record) { |
|
987 |
if (($this->_dnsHost == "@" || $this->_dnsHost == "") && |
|
988 |
($record["name"] == $this->_dnsDomain) && |
|
989 |
($record["type"] == $record_type)) { |
|
990 |
$record_id = $record["id"]; |
|
991 |
break; |
|
992 |
} |
|
993 |
else if (($record["name"] == "{$this->_dnsHost}.{$this->_dnsDomain}") && |
|
994 |
($record["type"] == $record_type)) { |
|
995 |
$record_id = $record["id"]; |
|
996 |
break; |
|
997 |
} |
|
998 |
} |
|
999 |
// No record exists for this host, add one. |
|
1000 |
if (!$record_id) |
|
1001 |
{ |
|
1002 |
$porkbun_api = "https://porkbun.com/api/json/v3/dns/create/{$this->_dnsDomain}"; |
|
1003 |
if ($this->_dnsHost == "@" || $this->_dnsHost == "") |
|
1004 |
$post_data['name'] = ""; |
|
1005 |
else |
|
1006 |
$post_data['name'] = $this->_dnsHost; |
|
1007 |
} else { |
|
1008 |
$porkbun_api = "https://porkbun.com/api/json/v3/dns/edit/{$this->_dnsDomain}/{$record_id}"; |
|
1009 |
$post_data['name'] = $this->_dnsHost; |
|
1010 |
} |
|
1011 |
$post_data['type'] = $record_type; |
|
1012 |
// Porkbun doesn't allow you to "update" an existing record with the same IP |
|
1013 |
if (($record_id) && |
|
1014 |
($this->_forceUpdateNeeded == true) && |
|
1015 |
($this->_dnsDummyUpdateDone == false)) { |
|
1016 |
$post_data['content'] = $this->_useIPv6 ? "fd00:d::1" : "127.0.0.1"; |
|
1017 |
$this->_dnsDummyUpdateDone = true; |
|
1018 |
$log_message = 'Dynamic DNS %1$s (%2$s): '; |
|
1019 |
$log_message .= 'Performing forced update. '; |
|
1020 |
$log_message .= 'IP temporarily set to %3$s'; |
|
1021 |
log_error(sprintf(gettext($log_message), $this->_dnsService, $this->_dnsHost, $post_data['content'])); |
|
1022 |
} else { |
|
1023 |
$post_data['content'] = $this->_dnsIP; |
|
1024 |
} |
|
1025 |
if (intval($this->_dnsTTL)) $post_data['ttl'] = $this->_dnsTTL; |
|
1026 |
curl_setopt($ch, CURLOPT_URL, "{$porkbun_api}"); |
|
1027 |
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data)); |
|
1028 |
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); |
|
1029 |
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); |
|
1030 |
break; |
|
952 | 1031 |
case 'yandex': |
953 | 1032 |
case 'yandex-v6': |
954 | 1033 |
// https://yandex.com/dev/connect/directory/api/concepts/domains/dns-records-via-pdd.html |
... | ... | |
2975 | 3054 |
break; |
2976 | 3055 |
} |
2977 | 3056 |
break; |
3057 |
case 'porkbun': |
|
3058 |
case 'porkbun-v6': |
|
3059 |
$result = json_decode($data, true); |
|
3060 |
if ($result['status'] == 'SUCCESS') { |
|
3061 |
$status = $status_intro . $success_str . gettext("IP Address Updated Successfully!"); |
|
3062 |
$successful_update = true; |
|
3063 |
} else { |
|
3064 |
log_error($status_intro . " ( " . gettext("Error message: ") . $result['status'] . " )"); |
|
3065 |
} |
|
3066 |
break; |
|
2978 | 3067 |
default: |
2979 | 3068 |
break; |
2980 | 3069 |
} |
src/etc/inc/globals.inc | ||
---|---|---|
218 | 218 |
]; |
219 | 219 |
|
220 | 220 |
global $dyndns_split_domain_types; |
221 |
$dyndns_split_domain_types = ['namecheap', 'cloudflare', 'cloudflare-v6', 'gratisdns', 'cloudns', 'godaddy', 'godaddy-v6', 'linode', 'linode-v6']; |
|
221 |
$dyndns_split_domain_types = ['namecheap', 'cloudflare', 'cloudflare-v6', 'gratisdns', 'cloudns', 'godaddy', 'godaddy-v6', 'linode', 'linode-v6', 'porkbun', 'porkbun-v6'];
|
|
222 | 222 |
|
223 | 223 |
// pf tokens from FreeBSD source /sbin/pfctl/parse.y |
224 | 224 |
global $pf_reserved_keywords; |
src/etc/inc/services.inc | ||
---|---|---|
26 | 26 |
*/ |
27 | 27 |
|
28 | 28 |
|
29 |
define('DYNDNS_PROVIDER_VALUES', 'all-inkl azure azurev6 citynetwork cloudflare cloudflare-v6 cloudns custom custom-v6 desec desec-v6 digitalocean digitalocean-v6 dnsexit dnsimple dnsimple-v6 dnsmadeeasy dnsomatic domeneshop domeneshop-v6 dreamhost dreamhost-v6 duiadns duiadns-v6 dyfi dyndns dyndns-custom dyndns-static dyns dynv6 dynv6-v6 easydns easydns-v6 eurodns freedns freedns-v6 freedns2 freedns2-v6 glesys gandi-livedns gandi-livedns-v6 godaddy godaddy-v6 googledomains gratisdns he-net he-net-v6 he-net-tunnelbroker hover linode linode-v6 loopia mythicbeasts mythicbeasts-v6 name.com name.com-v6 namecheap nicru nicru-v6 noip noip-v6 noip-free noip-free-v6 onecom onecom-v6 ods opendns ovh-dynhost route53 route53-v6 selfhost spdyn spdyn-v6 strato yandex yandex-v6 zoneedit'); |
|
30 |
define('DYNDNS_PROVIDER_DESCRIPTIONS', 'All-Inkl.com,Azure DNS,Azure DNS (v6),City Network,Cloudflare,Cloudflare (v6),ClouDNS,Custom,Custom (v6),deSEC,deSEC (v6),DigitalOcean,DigitalOcean (v6),DNSexit,DNSimple,DNSimple (v6),DNS Made Easy,DNS-O-Matic,Domeneshop,Domeneshop (v6),DreamHost,Dreamhost (v6),DuiaDns.net,DuiaDns.net (v6),DY.fi,DynDNS (dynamic),DynDNS (custom),DynDNS (static),DyNS,Dynv6,Dynv6 (v6),easyDNS,easyDNS (v6),Euro Dns,freeDNS,freeDNS (v6),freeDNS API Version 2, freeDNS API Version 2 (v6),GleSYS,Gandi Live DNS,Gandi Live DNS (v6),GoDaddy,GoDaddy (v6),Google Domains,GratisDNS,HE.net,HE.net (v6),HE.net Tunnelbroker,Hover,Linode,Linode (v6),Loopia,Mythic Beasts,Mythic Beasts (v6),Name.com,Name.com (v6),Namecheap,NIC.RU,NIC.RU (v6),No-IP,No-IP (v6),No-IP (free),No-IP (free-v6),One.com,One.com (v6),ODS.org,OpenDNS,OVH DynHOST,Route 53,Route 53 (v6),SelfHost,SPDYN,SPDYN (v6),Strato,Yandex,Yandex (v6),ZoneEdit'); |
|
29 |
define('DYNDNS_PROVIDER_VALUES', 'all-inkl azure azurev6 citynetwork cloudflare cloudflare-v6 cloudns custom custom-v6 desec desec-v6 digitalocean digitalocean-v6 dnsexit dnsimple dnsimple-v6 dnsmadeeasy dnsomatic domeneshop domeneshop-v6 dreamhost dreamhost-v6 duiadns duiadns-v6 dyfi dyndns dyndns-custom dyndns-static dyns dynv6 dynv6-v6 easydns easydns-v6 eurodns freedns freedns-v6 freedns2 freedns2-v6 glesys gandi-livedns gandi-livedns-v6 godaddy godaddy-v6 googledomains gratisdns he-net he-net-v6 he-net-tunnelbroker hover linode linode-v6 loopia mythicbeasts mythicbeasts-v6 name.com name.com-v6 namecheap nicru nicru-v6 noip noip-v6 noip-free noip-free-v6 onecom onecom-v6 ods opendns ovh-dynhost route53 route53-v6 selfhost spdyn spdyn-v6 strato yandex yandex-v6 zoneedit porkbun porkbun-v6');
|
|
30 |
define('DYNDNS_PROVIDER_DESCRIPTIONS', 'All-Inkl.com,Azure DNS,Azure DNS (v6),City Network,Cloudflare,Cloudflare (v6),ClouDNS,Custom,Custom (v6),deSEC,deSEC (v6),DigitalOcean,DigitalOcean (v6),DNSexit,DNSimple,DNSimple (v6),DNS Made Easy,DNS-O-Matic,Domeneshop,Domeneshop (v6),DreamHost,Dreamhost (v6),DuiaDns.net,DuiaDns.net (v6),DY.fi,DynDNS (dynamic),DynDNS (custom),DynDNS (static),DyNS,Dynv6,Dynv6 (v6),easyDNS,easyDNS (v6),Euro Dns,freeDNS,freeDNS (v6),freeDNS API Version 2, freeDNS API Version 2 (v6),GleSYS,Gandi Live DNS,Gandi Live DNS (v6),GoDaddy,GoDaddy (v6),Google Domains,GratisDNS,HE.net,HE.net (v6),HE.net Tunnelbroker,Hover,Linode,Linode (v6),Loopia,Mythic Beasts,Mythic Beasts (v6),Name.com,Name.com (v6),Namecheap,NIC.RU,NIC.RU (v6),No-IP,No-IP (v6),No-IP (free),No-IP (free-v6),One.com,One.com (v6),ODS.org,OpenDNS,OVH DynHOST,Route 53,Route 53 (v6),SelfHost,SPDYN,SPDYN (v6),Strato,Yandex,Yandex (v6),ZoneEdit,Porkbun,Porkbun (v6)');
|
|
31 | 31 |
|
32 | 32 |
/* implement ipv6 route advertising daemon */ |
33 | 33 |
function services_radvd_configure($blacklist = array()) { |
src/usr/local/www/services_dyndns_edit.php | ||
---|---|---|
155 | 155 |
} elseif (($pconfig['type'] == "cloudflare") || ($pconfig['type'] == "cloudflare-v6")) { |
156 | 156 |
$host_to_check = $_POST['host'] == '@' ? $_POST['domainname'] : ( $_POST['host'] . '.' . $_POST['domainname'] ); |
157 | 157 |
$allow_wildcard = true; |
158 |
} elseif (($pconfig['type'] == "linode") || ($pconfig['type'] == "linode-v6") || ($pconfig['type'] == "gandi-livedns") || ($pconfig['type'] == "gandi-livedns-v6") || ($pconfig['type'] == "yandex") || ($pconfig['type'] == "yandex-v6")) { |
|
158 |
} elseif (($pconfig['type'] == "linode") || ($pconfig['type'] == "linode-v6") || ($pconfig['type'] == "gandi-livedns") || ($pconfig['type'] == "gandi-livedns-v6") || ($pconfig['type'] == "yandex") || ($pconfig['type'] == "yandex-v6") || ($pconfig['type'] == "porkbun") || ($pconfig['type'] == "porkbun-v6")) {
|
|
159 | 159 |
$host_to_check = $_POST['host'] == '@' ? $_POST['domainname'] : ( $_POST['host'] . '.' . $_POST['domainname'] ); |
160 | 160 |
$allow_wildcard = true; |
161 | 161 |
} elseif (($pconfig['type'] == "route53") || ($pconfig['type'] == "route53-v6")) { |
... | ... | |
364 | 364 |
)); |
365 | 365 |
|
366 | 366 |
$group->setHelp('Enter the complete fully qualified domain name. Example: myhost.dyndns.org%1$s' . |
367 |
'Cloudflare, Linode: Enter @ as the hostname to indicate an empty field.%1$s' . |
|
367 |
'Cloudflare, Linode, Porkbun: Enter @ as the hostname to indicate an empty field.%1$s' .
|
|
368 | 368 |
'deSEC: Enter the FQDN.%1$s' . |
369 | 369 |
'DNSimple: Enter only the domain name.%1$s' . |
370 | 370 |
'DNS Made Easy: Dynamic DNS ID (NOT hostname)%1$s' . |
371 | 371 |
'GleSYS: Enter the record ID.%1$s' . |
372 | 372 |
'he.net tunnelbroker: Enter the tunnel ID.%1$s' . |
373 |
'Cloudflare, ClouDNS, DigitalOcean, GoDaddy, GratisDNS, Hover, Linode, Name.com, Namecheap: Enter the hostname and domain name separately. |
|
373 |
'Cloudflare, ClouDNS, DigitalOcean, GoDaddy, GratisDNS, Hover, Linode, Name.com, Namecheap, Porkbun: Enter the hostname and domain name separately.
|
|
374 | 374 |
The domain name is the domain or subdomain zone being handled by the provider.', '<br />'); |
375 | 375 |
|
376 | 376 |
$section->add($group); |
... | ... | |
436 | 436 |
'GleSYS: Enter the API user.%1$s' . |
437 | 437 |
'Godaddy: Enter the API key.%1$s' . |
438 | 438 |
'NoIP: For group authentication, replace semicolon (:) with pound-key (#).%1$s' . |
439 |
'Porkbun: Enter the API key.%1$s' . |
|
439 | 440 |
'Route 53: Enter the Access Key ID.', '<br />'); |
440 | 441 |
|
441 | 442 |
$section->addPassword(new Form_Input( |
... | ... | |
458 | 459 |
'GoDaddy: Enter the API secret.%1$s' . |
459 | 460 |
'Linode: Enter the Personal Access Token.%1$s' . |
460 | 461 |
'Name.com: Enter the API token.%1$s' . |
462 |
'Porkbun: Enter the API secret.%1$s' . |
|
461 | 463 |
'Route 53: Enter the Secret Access Key.%1$s' . |
462 | 464 |
'Yandex: Yandex PDD Token.', '<br />'); |
463 | 465 |
|
... | ... | |
636 | 638 |
case "name.com-v6": |
637 | 639 |
case "onecom": |
638 | 640 |
case "onecom-v6": |
641 |
case "porkbun": |
|
642 |
case "porkbun-v6": |
|
639 | 643 |
hideGroupInput('domainname', false); |
640 | 644 |
hideInput('mx', true); |
641 | 645 |
hideCheckbox('wildcard', true); |
Also available in: Unified diff
Add dynamic DNS support for Porkbun DNS, closes #14402
Signed-off-by: Nita Vesa <nita.vesa@elektrik.link>