Skip to content

Instantly share code, notes, and snippets.

@Knocks83
Created December 27, 2020 13:56
Show Gist options
  • Save Knocks83/03b1a2a4b049f2b4df6621d95a78443a to your computer and use it in GitHub Desktop.
Save Knocks83/03b1a2a4b049f2b4df6621d95a78443a to your computer and use it in GitHub Desktop.
Cloudflare DDNS with PHP (must use a cronjob)
<?php
// create your API Key at https://dash.cloudflare.com/profile/api-tokens
// Required permissions: Zone Settings:Read, Zone:Read, DNS:Edit (all under zone)
$apiKey = "";
$zoneName = "example.com"; // The domain (eg. example.com)
$recordName = "test.example.com"; // The full domain (eg. test.example.com)
$proxied = "false"; // Whether the domain should be proxied or not (https://support.cloudflare.com/hc/en-us/articles/200169156-Identifying-network-ports-compatible-with-Cloudflare-s-proxy)
/* ------------------------------------------ */
// Root URL for the Cloudflare APIs
$baseURL = "https://api.cloudflare.com/client/v4/";
// Init cURL
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => array(
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json'
),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FORBID_REUSE => true
]);
// Get zone name (zones?name=$zoneName)
curl_setopt($curl, CURLOPT_URL, $baseURL . "zones?name=$zoneName");
$res = curl_exec($curl);
$res = json_decode($res)->result;
if (count($res) > 0) {
$res = $res[0];
if (property_exists($res, 'id')) {
// Save the zone ID
$zoneID = $res->id;
} else {
print("An error has occurred while getting the zone infos!" . PHP_EOL);
exit(1);
}
} else {
print("Cannot find the specified zone! Are you sure about the zone you set? (eg: example.com)");
exit(1);
}
// Get the record ID and record content (zones/$zoneID/dns_records?type=A&name=$recordName)
curl_setopt($curl, CURLOPT_URL, $baseURL . "zones/$zoneID/dns_records?type=A&name=$recordName");
$res = curl_exec($curl);
$res = json_decode($res)->result;
// Check the result
if (count($res) > 0) {
$res = $res[0];
if (property_exists($res, 'id') && property_exists($res, 'content')) {
// Save the record infos
$recordID = $res->id;
$recordContent = $res->content; // the record content is the IP associated with the DNS
} else {
print("An error has occurred while getting the record infos!" . PHP_EOL);
exit(1);
}
} else {
print("Cannot find the specified record! Are you sure about the record you set? (eg: test.example.com)");
exit(1);
}
// Get the current IP of the machine
curl_setopt($curl, CURLOPT_URL, 'https://diagnostic.opendns.com/myip');
$res = curl_exec($curl);
$machineIP = $res;
// If the current IP is different from the IP saved in the DNS record, update it
if ($machineIP != $recordContent) {
// Update the DNS record (zones/$zoneID/dns_records/$recordID)
// This is a PUT request, not a GET request
// Generate the data JSON that contains the new values for the DNS entry
$data = '{"type":"A","name":"' . $recordName . '","content":"' . $machineIP . '","ttl":1,"proxied":' . $proxied . '}';
// Tune cURL to send a PUT request with the data we generated
curl_setopt_array($curl, [
CURLOPT_URL => $baseURL . "zones/$zoneID/dns_records/$recordID",
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_POSTFIELDS => $data
]);
$res = curl_exec($curl);
$res = json_decode($res);
if (property_exists($res, 'success')) {
if (!$res->success) {
print("An error has occurred while updating the DNS!" . PHP_EOL);
exit(1);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment