104 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
		
		
			
		
	
	
			104 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
|  | #!/usr/bin/env php
 | ||
|  | <?php | ||
|  | 
 | ||
|  | 	if ($_REQUEST['do'] != 'update') { | ||
|  | 		throw new Exception("Invalid request"); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	require __DIR__ . '/class/Cloudflare.php'; | ||
|  | 
 | ||
|  | 	$confFile = __DIR__ . '/CloudFlare.config.php'; | ||
|  | 	if (!file_exists($confFile)) { | ||
|  | 		echo "Missing config file. Please copy config.php.skel to config.php and fill out the values therein.\n"; | ||
|  | 		return 1; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	$config = require $confFile; | ||
|  | 
 | ||
|  | 	foreach (['cloudflare_email', 'cloudflare_apikey_file', 'domainnames', 'ttl', 'protocol'] as $key) { | ||
|  | 		if (!isset($config[$key]) || $config[$key] === '') { | ||
|  | 			echo "config.php is missing the '$key' config value\n"; | ||
|  | 			return 1; | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	$api = new Cloudflare($config['cloudflare_email'], file_get_contents($config['cloudflare_apikey_file'])); | ||
|  | 
 | ||
|  | 	if (isset($config['auth_token']) && $config['auth_token']) { | ||
|  | 		// API mode. Use IP from request params.
 | ||
|  | 		if (empty($_GET['auth_token']) || empty($_GET['ip']) || $_GET['auth_token'] != $config['auth_token']) { | ||
|  | 			echo "Missing or invalid 'auth_token' param, or missing 'ip' param\n"; | ||
|  | 			return 1; | ||
|  | 		} | ||
|  | 		$ip = $_GET['ip']; | ||
|  | 	} else { | ||
|  | 		// Local mode. Get IP from service.
 | ||
|  | 		$ip = getIP($config['protocol']); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	//$verbose = !isset($argv[1]) || $argv[1] != '-s';
 | ||
|  | 	$verbose = True; | ||
|  | 
 | ||
|  | 	$updatedDomains = array(); | ||
|  | 	$encounteredErrors = 0; | ||
|  | 
 | ||
|  | 	foreach ($config['domainnames'] as $pseudoDomainName) { | ||
|  | 		preg_match("'\[(.*?)\](.*)'i", $pseudoDomainName, $patternMatch); | ||
|  | 		$recordName = rtrim($patternMatch[1], '.'); | ||
|  | 		$domain = $patternMatch[2]; | ||
|  | 
 | ||
|  | 		$recordName = $recordName == '@' ? $domain : implode('.', [$recordName, $domain]); | ||
|  | 
 | ||
|  | 		try { | ||
|  | 			$zone = $api->getZone($domain); | ||
|  | 			if (!$zone) { | ||
|  | 				if ($verbose) echo "Domain $domain not found\n" . PHP_EOL; | ||
|  | 				$encounteredErrors += 1; | ||
|  | 				continue; | ||
|  | 			} | ||
|  | 
 | ||
|  | 			$records = $api->getZoneDnsRecords($zone['id'], ['name' => $recordName]); | ||
|  | 			$record  = $records && $records[0]['name'] == $recordName ? $records[0] : null; | ||
|  | 
 | ||
|  | 			if (!$record) { | ||
|  | 				if ($verbose) echo "No existing record [$recordName] found. Creating a new one\n" . PHP_EOL; | ||
|  | 				$ret = $api->createDnsRecord($zone['id'], 'A', $recordName, $ip, ['ttl' => $config['ttl']]); | ||
|  | 				if ($ret) $updatedDomains[] = $pseudoDomainName; | ||
|  | 			} elseif ($record['type'] != 'A' || $record['content'] != $ip || $record['ttl'] != $config['ttl']) { | ||
|  | 				if ($verbose) echo "Updating record [$recordName] from [{$record['content']}] to [$ip].\n" . PHP_EOL; | ||
|  | 				$ret = $api->updateDnsRecord($zone['id'], $record['id'], [ | ||
|  | 					'type'    => 'A', | ||
|  | 					'name'    => $recordName, | ||
|  | 					'content' => $ip, | ||
|  | 					'ttl'     => $config['ttl'], | ||
|  | 				]); | ||
|  | 				if ($ret) $updatedDomains[] = $pseudoDomainName; | ||
|  | 			} else { | ||
|  | 				if ($verbose) echo "Record [$recordName] appears OK. No need to update.\n" . PHP_EOL; | ||
|  | 			} | ||
|  | 		} | ||
|  | 		catch (Exception $e) { | ||
|  | 			if ($verbose) echo "Error: " . $e->getMessage() . "\n" . PHP_EOL; | ||
|  | 			$encounteredErrors += 1; | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	$date = new DateTime("now", new DateTimeZone('Europe/Amsterdam')); | ||
|  | 
 | ||
|  | 	if (sizeof($updatedDomains) > 0) { | ||
|  | 		echo '[' . $date->format('d-m-Y H:i:s') . ']: ' . sizeof($updatedDomains) . ' out of ' . sizeof($config['domainnames']) . ' domains updated to ' . $ip . ' [' . implode(', ', $updatedDomains) . ']' . PHP_EOL; | ||
|  | 	} else { | ||
|  | 		echo '[' . $date->format('d-m-Y H:i:s') . ']: No changes made' . ($encounteredErrors > 0 ? ', however with ' . $encounteredErrors . ' errors!' : '') . PHP_EOL; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	function getIP($protocol) { | ||
|  | 		/*  $prefixes = ['ipv4' => 'ipv4.', 'ipv6' => 'ipv6.', 'auto' => '']; | ||
|  | 		if (!isset($prefixes[$protocol])) | ||
|  | 		{ | ||
|  | 		throw new Exception('Invalid "protocol" config value.'); | ||
|  | 		} | ||
|  | 		return trim(file_get_contents('http://' . $prefixes[$protocol] . 'icanhazip.com')); | ||
|  | 		*/return trim(file_get_contents('https://api.ipify.org')); | ||
|  | 	} | ||
|  | 
 | ||
|  | ?>
 |