Due to the nature of CloudFlare’s services, CloudFlare has emerged as one of the best, reliable, robust yet free DNS hosting service provider. Many webmasters have used the DNS hosting service of CloudFlare without utilizing it as reverse proxy and content delivery network. Unfortunately, CloudFlare does not provide an easy way to update dynamic IP address, the IP address of the host that constantly changes, to the DNS records hosted on its distributed name server system.

The lack of a client to update DDNS (Dynamic DNS) does not mean it can’t be done. In fact, CloudFlare has a client interface API that can be used for DNS records updating and maintenance, and hence it’s possible to update the record whenever the IP address changed. What we need is just a script that checks for WAN public facing IP address, and if the IP address changed, update the corresponding DNS record hosted in CloudFlare.

Method 1: Using DDclient

Install DDclient. Make sure that you apply the patch to support CloudFlare if you’re installing DDclient =< version 3.8.2.

Once DDclient is installed, edit the /etc/ddclient/ddclient.conf file. If you haven't enabled any method to obtain the WAN IP address for your host, enable the following line so that DDclient will visit checkip.dyndns.com to retrieve the public IP address. If you're behind NAT, chance is that you will need this line to get the correct IP address.

use=web, web=checkip.dyndns.com/, web-skip='IP Address'

Add the following lines to the end of the file to update CloudFlare:

##
## Cloudflare (cloudflare.com)
##
protocol=cloudflare,                            \
server=www.cloudflare.com,                      \
zone=techjourney.net,                           \
login=CloudFlare_Email_Address,                 \
password=CloudFlare_API_Key                     \
subdomain.techjourney.net

Replace:
techjourney.net with the actual domain name (website zone) configured in CloudFlare.
CloudFlare_Email_Address with email address used to login.
CloudFlare_API_Key with API key from your CloudFlare account.
subdomain.techjourney.net with the domain name / host name that the IP address is pointed to.

Note
If you encounter the following error when running DDclient, install Perl JSON module. In Ubuntu, run apt-get install libjson-perl while in RedHat/CentOS, run yum install perl-JSON-Any.

Can’t locate JSON/Any.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl/usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /usr/sbin/ddclient line 26.
BEGIN failed–compilation aborted at /usr/sbin/ddclient line 26.

Once you confirm that the dynamic update of DDNS by DDclient is working, make sure that the DDclient daemon is started, or you have set up a cron job to run it regularly.

Method 2: Use Shell Script Scheduled by Crontab

In order to use a shell script to update a CloudFlare hosted DNS record with dynamic IP address, first we need to know the DNS Record ID. Run the following command once to retrieve all information about the top-level domain (TLD):

curl https://www.cloudflare.com/api_json.html -d 'a=rec_load_all' \
  -d 'tkn=CloudFlare_API_Key' \
  -d 'email=CloudFlare_Email_Address' \
  -d 'z=techjourney.net'

Where,
techjourney.net is the actual domain name (website zone) configured in CloudFlare.
CloudFlare_Email_Address is email address used to login.
CloudFlare_API_Key is API key from your CloudFlare account.

CloudFlare API Get All Records

The return is a wall of text in JSON format. Copy and paste all of the text to a JSON viewer or JSON parser for easy reading. For convenient, you can also add a pipe command > FileName.json to the end of above command to export the return to a file.

In the JSON return result, search for the record with the name that matches the host name that has dynamic IP address, with the type A, which is normally the record to modify for DDNS. If you want other DNS record type, such as MX, change it accordingly. Then, retrieve it’s corresponding rec_id (top of the section).

CloudFlare Records JSON

After getting the record ID for the DNS record that you want to modify, create the following script at a location of your choice, e.g. /scripts, and name it with a .sh extension, e.g. cloudflare_ddns.sh.

#!/bin/sh
NEW_IP=`wget -O - -q http://ifconfig.me/ip`
CURRENT_IP=`cat /var/tmp/current_ip.txt`

if [ "$NEW_IP" = "$CURRENT_IP" ]
then
        echo "No Change in IP Adddress"
else
        curl https://www.cloudflare.com/api_json.html \
          -d 'a=rec_edit' \
          -d 'tkn=CloudFlare_API_Key' \
          -d 'email=CloudFlare_Email_Address' \
          -d 'z=techjourney.net' \
          -d 'id=CloudFlare_Record_ID' \
          -d 'type=CloudFlare_Record_Type' \
          -d 'name=CloudFlare_Record_Name' \
          -d 'ttl=1' \
          -d "content=$NEW_IP"
        echo $NEW_IP > /var/tmp/current_ip.txt
fi

Where,
techjourney.net is the actual domain name (website zone) configured in CloudFlare.
CloudFlare_Email_Address is email address used to login.
CloudFlare_API_Key is API key from your CloudFlare account.
CloudFlare_Record_ID is the DNS record IP provided by CloudFlare in step above.
CloudFlare_Record_Type is the type of DNS record, most commonly A, but can also be CNAME, AAAA, MX, SRV, and etc.
CloudFlare_Record_Name is the name of sub-domain or TLD that you want to change its DNS, without the root domain name, i.e. www instead of www.techjourney.net.

For example, the CloudFlare API update query is:

curl https://www.cloudflare.com/api_json.html \
          -d 'a=rec_edit' \
          -d 'tkn=1234567890987654321' \
          -d '[email protected]' \
          -d 'z=techjourney.net' \
          -d 'id=123456789' \
          -d 'type=A' \
          -d 'name=www.techjourney.net' \
          -d 'ttl=1' \
          -d "content=$NEW_IP"

Create an empty file to store the current IP address in /var/tmp with the following command. If you change the file name or location of the file, remember to update the script above to reflect the new path.

touch /var/tmp/current_ip.txt

Finally, set up a cron job to run the script every 5 minutes

To automate the process I simply wrote a cron to:

*/5   *   *   *   *   ~/scripts/cloudflare_ddns.sh
Note
Script above relies on the ifconfig.me service to provide the real WAN IP address for the host. If the service is down or too slow, here’s a few alternatives:

ident.me
ifconfig.co
ip.appspot.com

Method 3: Through Google AppEngine

If you have Google App Engine platform as a service (PaaS) account, you can use an App Engine instance to update CloudFlare record to the public IP address of host that initiating the request.

Download the AppEnging instance from https://cloudflare-updater.appspot.com/.

Note: It’s recommended that you run the app yourself to update the DNS records, as you will need to pass the API key that is equivalent to your password.

Method 4: Using PHP Script

Essentially similar to using BASH shell script, but if you’re more familiar or more comfortable with PHP, it’s also can be used to create DDNS service with CloudFlare. You can get a sample PHP CloudFlare DDNS scripts at https://github.com/ScottHelme/CloudFlareDDNS. You still need a shell script that calls the PHP and a cron job though.

Method 5: Windows CloudFlare DDNS Update Client

While DNS-O-Matic hasn’t updated with CloudFlare support yet, there are a few Windows DDNS clients that support CloudFlare. Here’s some example: