Skip to content

Instantly share code, notes, and snippets.

@kdallas
Last active February 26, 2017 03:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kdallas/6162568 to your computer and use it in GitHub Desktop.
Save kdallas/6162568 to your computer and use it in GitHub Desktop.
CloudFlare DDNS updater, inspired by: http://bit.ly/2mqyiwI -- I put this on a server that I know is going to be up 24/7, and pointed my DD-WRT router to it for Dynamic DNS updates.
<?php
/*
http://SOME_RELIABLE_SERVER/update_cloudflare/CLOUDFLARE_EMAIL/CLOUDFLARE_API-KEY/HOST
...where "update_cloudflare" is a directory containing this file (index.php)
...and the URL slug/segments are parsed with the following regex:
RewriteRule ^/update_cloudflare/([^/]+)?/?([^/]+)?/?(.*) /update_cloudflare/index.php?e=$1&k=$2&h=$3 [L,QSA]
which sends the following GET params:
k: e
v: CLOUDFLARE_EMAIL
k: k
v: CLOUDFLARE_API-KEY
k: h
v: HOST
Note: $dns_id below can be retrieved by changing the action to 'rec_load_all'
-- you only need to do this one time (for performance).
But for multiple users or hosts, you might like to use a function and store
some data for a quick lookup... or simply do 'rec_load_all' every time.
*/
if(empty($_GET['e']) || empty($_GET['k']) || empty($_GET['h'])) {
die('missing params');
}
$ip = $_SERVER['REMOTE_ADDR'];
$email = $_GET['e'];
$api = $_GET['k'];
$hostname = $_GET['h'];
$oldIP = gethostbyname($hostname);
// check current IP against host IP
if ($oldIP==$ip) {
die("IP still set to $ip");
}
// for new users... I will need to retrieve the DNS Record ID, and store it in the DB against the host name.
$dns_id = '12345678'; // insert YOUR domain's ID here
//$action = 'rec_load_all'; // use this to query the full DNS records [ http://www.cloudflare.com/docs/client-api.html#s3.3 ]
$action = 'rec_edit';
$curl_url = 'https://www.cloudflare.com/api_json.html';
$fields = [
'a' => urlencode($action),
'z' => urlencode($hostname),
'email' => urlencode($email),
'tkn' => urlencode($api)
];
if ($action == 'rec_edit') {
$fields['type'] = 'A';
$fields['id'] = urlencode($dns_id);
$fields['name'] = urlencode($hostname);
$fields['content'] = urlencode($ip);
$fields['ttl'] = '1';
$fields['service_mode'] = '0';
}
//url-ify the data for the POST
$i=0;
$fields_str = '';
foreach($fields as $key=>$value) {
$fields_str .= $key.'='.$value.((++$i < count($fields)) ? '&' : '');
}
//set the url, number of POST vars, POST data
$csesh = curl_init();
curl_setopt($csesh, CURLOPT_URL, $curl_url);
curl_setopt($csesh, CURLOPT_POST, count($fields));
curl_setopt($csesh, CURLOPT_POSTFIELDS, $fields_str);
curl_setopt($csesh, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($csesh, CURLOPT_HEADER, 0);
curl_setopt($csesh, CURLOPT_RETURNTRANSFER, 1);
$retJSON = curl_exec($csesh);
curl_close($csesh);
$retArr = json_decode($retJSON, true);
if ($retArr["result"]=='success') {
echo "IP updated to $ip<br/> \n";
} else {
echo "Houston, we had a problem:<br/> \n";
print_r($retArr);
}
@kdallas
Copy link
Author

kdallas commented Feb 3, 2014

The previous version put all the data in the CURLOPT_URL, as well as left out CURLOPT_SSL_VERIFYPEER. My host seemed to update cURL which meant I needed to turn off SSL verification. So I also put the POST data into an array for making future changes easier.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment