Dynamic DNS with CloudFlare

This is a simple hack I found for my self to have a “Dynamic DNS” for my home IP.

I’m using CloudFlare as my name server to manage the zone file for my domain, And one of the nice things about FC is that they have nice API to manage your account. One of the options this API provides is the capability to update you DNS entries in the Zone.

Get your token

For all the action with the API you’ll 3 thinks, your privet token (called tkn in the API),  email and the action you like to perform.

You can find your token under your Account page

DNS Record ID

Next you’ll need to find the action you like to perform, in my case is to edit the zone file. which is under the “DNS Record Management” -> rec_edit menu, but for using this action you will need the ID number for the recored you like to change, and for that you will need to use “rec_load_all” action.


curl https://www.cloudflare.com/api_json.html \
  -d 'a=rec_load_all' \
  -d 'tkn=8afbe6dea02407989af4dd4c97bb6e25' \
  -d '[email protected]' \
  -d 'z=example.com'

The output will be in a JSON format, and the part you are looking for will look similar to this,

    "rec_id": "18136402",
    "rec_tag": "3bcef45cdf5b7638b13cfb89f1b6e716",
    "zone_name": "example.com",
    "name": "test.example.com",
    "display_name": "test",
    "type": "A",
    "prio": null,
    "content": "[server IP]",
    "display_content": "[server IP]",
    "ttl": "1",
    "ttl_ceil": 86400,
    "ssl_id": null,
    "ssl_status": null,
    "ssl_expires_on": null,
    "auto_ttl": 1,
    "service_mode": "0",
    "props": {
        "proxiable": 1,
        "cloud_on": 0,
        "cf_open": 1,
        "ssl": 0,
        "expired_ssl": 0,
        "expiring_ssl": 0,
        "pending_ssl": 0

Edit/Update the DNS record

Now that you have the ID for the record you like to change, it’s a matter of a simple curl command,

curl https://www.cloudflare.com/api_json.html \
  -d 'a=rec_edit' \
  -d 'tkn=8afbe6dea02407989af4dd4c97bb6e25' \
  -d 'id=18136402' \
  -d '[email protected]' \
  -d 'z=example.com' \
  -d 'type=A' \
  -d 'name=test' \
  -d 'content=' \
  -d 'service_mode=0' \
  -d 'ttl=1'

This command will update the IP to for test.example.com entery.

Automate the update process

To automate the process, i have a cron job which runs every 5 minutes, and query my external IP and compare it to the resolved IP form my DNS.


CURRENT_IP=$(dig myip.opendns.com @resolver1.opendns.com +short)
RESOLVE_IP=$(dig dyn.example.com +short @jean.ns.cloudflare.com)

if [[ ${CURRENT_IP} != ${RESOLVE_IP} ]] ;
    echo "need to update IP from: ${RESOLVE_IP} -> ${CURRENT_IP}"
    curl https://www.cloudflare.com/api_json.html -d 'a=rec_edit' \
        -d 'tkn=c7ee1aef8131daf52e103a21a786ecbd99193' \
        -d '[email protected]' \
        -d 'id=42' \
        -d 'z=example.com' \
        -d 'type=A' \
        -d 'name=dyn' \
        -d 'content='${CURRENT_IP} \
        -d 'service_mode=0' \
        -d 'ttl=120' \

    echo "nothing to do"
    exit 0;


You may also like...

Leave a Reply

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