DDNS (Dynamic DNS) on Cloudflare (using your own domain name)

There are a number of dynamic DNS services available to set up in your home router, its easier to remember a domain name than a dynamically changing IP address.
Often you will create a hostname based on the DDNS providers domain name.

If you have your own domain name and a raspberry pi at home then this may be for you.

Amongst the many services offered by Cloudflare their DNS hosting is of interest to me.
For personal web sites they offer a BASIC plan for free.
By using their API I can change a DNS records using a script on the raspberry pi in my home office.

I obtained the following script from here,
https://gist.github.com/benkulbertis/fff10759c2391b6618dd

#!/bin/bash

# CHANGE THESE
auth_email="[email protected]"
auth_key="c2547eb745079dac9320b638f5e225cf483cc5cfdda41" # found in cloudflare account settings
zone_name="example.com"
record_name="www.example.com"

# MAYBE CHANGE THESE
ip=$(curl -s http://ipv4.icanhazip.com)
ip_file="/path/to/ip.txt"
id_file="/path/to/cloudflare.ids"
log_file="/path/to/cloudflare.log"

# LOGGER
log() {
    if [ "$1" ]; then
        echo -e "[$(date)] - $1" >> $log_file
    fi
}

# SCRIPT START
log "Check Initiated"

if [ -f $ip_file ]; then
    old_ip=$(cat $ip_file)
    if [ $ip == $old_ip ]; then
        echo "IP has not changed."
        exit 0
    fi
fi

if [ -f $id_file ] && [ $(wc -l $id_file | cut -d " " -f 1) == 2 ]; then
    zone_identifier=$(head -1 $id_file)
    record_identifier=$(tail -1 $id_file)
else
    zone_identifier=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$zone_name" -H "X-Auth-Email: $auth_email" -H "X-Auth-Key: $auth_key" -H "Content-Type: application/json" | grep -Po '(?<="id":")[^"]*' | head -1 )
    record_identifier=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records?name=$record_name" -H "X-Auth-Email: $auth_email" -H "X-Auth-Key: $auth_key" -H "Content-Type: application/json"  | grep -Po '(?<="id":")[^"]*')
    echo "$zone_identifier" > $id_file
    echo "$record_identifier" >> $id_file
fi

update=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records/$record_identifier" -H "X-Auth-Email: $auth_email" -H "X-Auth-Key: $auth_key" -H "Content-Type: application/json" --data "{\"id\":\"$zone_identifier\",\"type\":\"A\",\"name\":\"$record_name\",\"content\":\"$ip\"}")

if [[ $update == *"\"success\":false"* ]]; then
    message="API UPDATE FAILED. DUMPING RESULTS:\n$update"
    log "$message"
    echo -e "$message"
    exit 1 
else
    message="IP changed to: $ip"
    echo "$ip" > $ip_file
    log "$message"
    echo "$message"
fi

Locate the file in
/usr/local/bin/

Create a cron entry
*/2 * * * * /usr/local/bin/cf-ddns.sh >/dev/null 2>&1

This will run the script every 2 minutes.

1 thought on “DDNS (Dynamic DNS) on Cloudflare (using your own domain name)”

  1. Pingback: Your own Dynamic DNS (DDNS) with Raspberry Pi and Cloudflare – ryan erickson

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.