/ raspberry pi

Cloudflare DDNS and Raspberry Pi

If you've been following my guides on installing Ghost on Raspberry Pi, hopefully by now you have managed to set up a custom domain name that points towards your external IP address.

Unless you have an ISP that provides you with a static IP address, problems will arise when your dynamically provided IP address changes because visitors will no longer be directed to your site. This is because the "A" record we set up in Cloudflare has the IP address we specified the first time around.

Thankfully, Cloudflare has a free API that allows you to automatically update your DNS records, and with a little patience we can create a script to do just that. In this guide, we will cover a few methods of updating your Cloudflare DNS "A" record with your external IP address, using the API.

Cloudflare API

This process may look a little complicated at first, but the string of commands we will be entering in our terminal will get us the relevant ID's that will allow us to automatically update our IP address in Cloudflare. I followed a useful guide I found online for this, but tweaked a few parts to ensure that the Cloudflare proxy was turned on, in order to gain the benefits of Cloudflare's CDN too.

Get your API key

This is as simple as going into your account settings within Cloudflare, and then finding the "Global API Key" section. When you select "View Key" you should see a random string of text and numbers - this is your API key and you should not share this with anybody! It is a good idea to copy and past this into a blank text document and label it as your API key as we will be collecting a few of these during this process and it can be a little confusing.

Ok, now open up your terminal (you can do this via SSH on your Raspberry Pi if you want) and enter the following command in full (i.e. copy everything from curl to the /json":

curl -X GET "https://api.cloudflare.com/client/v4/zones?name=your.hostname" \
    -H "X-Auth-Email: [email protected]" \
    -H "X-Auth-Key: YOUR_CLOUDFLARE_GLOBAL_API_KEY" \
    -H "Content-Type: application/json"

Making sure you replace the following parts:

  1. your.hostname (in the URL part) with the custom domain you want to use
  2. [email protected] with the email address you used when opening your Cloudflare account
  3. YOUR_CLOUDFLARE_GLOBAL_API_KEY with the API key from Cloudflare

You should then see a load of data returned in your terminal window - this is good!

What you now need to find is the part right near the beginning that looks something like {"result":[{"id":"somethingrandomhere",, specifically the somethingrandomhere part, which will look like another API key. This is your Zone ID, so copy and past this into the text document that contains your API key and label it "Zone ID".

Now we're going to try to find our Record ID by using the Zone ID we just found. In the terminal, now run:

curl -X GET "https://api.cloudflare.com/client/v4/zones/YOUR_ZONE_ID/dns_records?name=your.hostname" \
    -H "X-Auth-Email: [email protected]" \
    -H "X-Auth-Key: YOUR_CLOUDFLARE_GLOBAL_API_KEY" \
    -H "Content-Type: application/json"

Replacing:

  1. YOUR_ZONE_ID with the Zone ID we found from the previous command
  2. [email protected] as before
  3. YOUR_CLOUDFLARE_GLOBAL_API_KEY as before

Again, you should see another load of data returned in the terminal window, and this time we'll be collecting the {"result":[{"id":"againsomethingrandomhere", part, specifically the ID string, which is our Record ID. Copy and past this ID into your text document and label it accordingly. You can see how this can become confusing quickly!

Now we have all the information we require to create the script we'll use on our Raspberry Pi to update our Cloudflare "A" record automatically.


Create your script

We'll now create the script on our Raspberry Pi, so SSH into your Pi and then make sure you are in the home directory before creating our script file:

cd ~
nano cfddns.sh

Next, copy and paste this script into a text editor on your computer (not the Raspberry Pi just yet) as we'll need to substitute the relevant parts with the information we just acquired:

#!/bin/sh

[ ! -f /var/tmp/current_ip.txt ] && touch /var/tmp/currentip.txt

NEWIP='dig +short myip.opendns.com @resolver1.opendns.com'
CURRENTIP='cat /var/tmp/currentip.txt'

if [ "$NEWIP" = "$CURRENTIP" ]
then
  echo "IP address unchanged"
else
  curl -X PUT "https://api.cloudflare.com/client/v4/zones/YOUR_ZONE_ID/dns_records/YOUR_RECORD_ID" \
    -H "X-Auth-Email: [email protected]" \
    -H "X-Auth-Key: YOUR_CLOUDFLARE_GLOBAL_API_KEY" \
    -H "Content-Type: application/json"
    --data "{\"type\":\"A\",\"name\":\"your.hostname\",\"content\":\"$NEWIP\",\"proxied\":true}"
  echo $NEWIP > /var/tmp/currentip.txt
fi

Again, be sure to replace the relevant parts with your information:

  1. YOUR_ZONE_ID with your Zone ID
  2. YOUR_RECORD_ID with your Record ID
  3. [email protected] with the email address used to access your Cloudflare account
  4. YOUR_CLOUDFLARE_GLOBAL_API_KEY with your API key
  5. your.hostname with the custom domain you'll be using.

Once you have replaced the parts in the script above on your local computer, copy and paste the updated script into the blank cfddns.sh file on your Raspberry Pi and then exit CTRL+X and save Y.


Make the script executable

Right now, you should have the new script saved on your Raspberry Pi but we need to make it executable, so that it can do its job. Do that from the terminal on your Pi by running:

chmod +x cfddns.sh

Now before we test it out, we need to install a small package on our Raspberry Pi, so that the script can work completely:

sudo apt-get update
sudo apt-get install dnsutils

Once installed, test your script by running:

sudo ./cfddns.sh

If all has gone to plan, you should be returned to the command line, and if the IP address hasn't change, you will likely see IP address unchanged.

Our script should now automatically update the "A" record in our Cloudflare account, as well as writing our latest IP address in a text file stored on our Raspberry Pi in the /var/tmp/current_ip.txt file.


Set up a Cron job

The last thing to do is to automate the running of this script and we can do this quickly and easily using Cron. We'll set this to run every 5 minutes:

sudo crontab -e

If you are running this command for the first time, you'll be asked which editor to use. Make your selection using the relevant number key (I usually use Nano for simplicity). Then you will need to add this to the very end of the file:

*/5 * * * * /home/pi/cfddns.sh

Finally exit CTRL+X and save Y and you're done!


Use Synology NAS drive to update Cloudflare

If you have a Synology NAS drive, you can use the Task Scheduler on DSM to run a custom script, much like the way we did it on our Raspberry Pi.

This is extremely simple to do, and you can create more than one script to update different domains if you have a number of them running:

  1. Log into your Synology DSM web interface and then go to the Control Panel
  2. Open Task Scheduler
  3. Select Create -> Scheduled Task -> User-defined script from the top
  4. Give your Task a name - i.e. Cloudflare DDNS and make sure the Enabled checkbox is ticked
  5. Switch to the Schedule tab and then set it to Daily with the First run time set to "00:00"; the Frequency to "Every 5 minute(s)" and the Last run time to "23:55"
  6. Switch to the Task Settings tab and then paste the following script into the User-defined script box:
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/YOUR_ZONE_ID/dns_records/YOUR_RECORD_ID" -H "X-Auth-Email: [email protected]" -H "X-Auth-Key: YOUR_CLOUDFLARE_GLOBAL_API_KEY" -H "Content-Type: application/json" --data "{\"id\":\"YOUR_ZONE_ID\",\"type\":\"A\",\"name\":\"your.hostname\",\"content\":\"`curl ifconfig.co`\",\"proxied\":true}"

Make sure you replace the relevant parts again and finally elect "OK" and your Synology NAS Drive will now run this script every 5 minutes and will update your Cloudflare DDNS automatically too.

Wesley Archer

Wesley Archer

Digital Account Manager by day, and maker in his spare time. Also, a regular contributor to The MagPi Magazine for the Raspberry Pi Foundation.

Read More