Project

General

Profile

« Previous | Next » 

Revision d9d91d5d

Added by Nita Vesa almost 2 years ago

Add dynamic DNS support for Porkbun DNS, closes #14402

Signed-off-by: Nita Vesa <>

View differences:

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
			}

Also available in: Unified diff