Cloudflare dns dynamic ip updater script

cloudflare dns dynamic update

This is a dns dynamic ip updater bash script for Cloudflare. In case you self host a server and your provider gives you a dynamic external ip that changes from time to time, you can use this script that monitors ip changes and push the changes to the Cloudflare API.

It should work on any system with a BASH interpreter, provided you also have these tools installed: curl and jq.

You will also need your domain Zone ID in Cloudflare. You can find it in the main page for your site on the Cloudflare administration page. It usually is at the bottom of the right menu.

cloudflre zone id

A token is required to authenticate with the Cloudflare API. You can create this token from your profile page on Cloudflare, then clicking on ‘API Tokens’ and ‘Create Token’ button. You can use the ‘Edit zone DNS’ template, and add your desired zone to the ‘Zone Resources’ section. Continue and create the token. Important: copy the token at this stage as it won’t be shown again. You will use it later to configure the script.

Each dns record has an id in Clouflare. We need the id of the record we want to update in case our external ip changes. Below there is a curl call to get a list of A type records for a zone. Execute it and identify the record you want to be updated. Copy its id for later use in the script. Do not forget to change <yourzoneid> and <yourtoken> with your respective values.

curl -s -X GET "https://api.cloudflare.com/client/v4/zones/<yourzoneid>/dns_records?type=A" -H "Authorization: Bearer <yourtoken>" \
-H "Content-Type: application/json"|jq '.result[]|{id,name,type,content,ttl}'

If you have several subdomains pointing to the same ip with a type A record and you want all of them to be updated if your external ip changes, it is best leave one of them as A record and convert the rest to CNAME type, so when the A record is updated, the rest already point to the proper place.

Finally here is the script to update your dns record in case your external ip changes. Replace <yourzoneid>, <yourtoken> and <yourrecordid> with your own values.

#!/bin/bash

ZONE_ID="<yourzoneid>"
TOKEN="<yourtoken>"

# api url
URL="https://api.cloudflare.com/client/v4/zones"

# you can get the record id showing all A records with this call:
# curl -s -X GET "${URL}/${ZONE_ID}/dns_records?type=A" -H "Authorization: Bearer ${TOKEN}" \
# -H "Content-Type: application/json"|jq '.result[]|{id,name,type,content,ttl}'
RECORD_ID="<yourrecordid>"

# get actual record information
REC=$(curl -s -X GET "${URL}/${ZONE_ID}/dns_records/${RECORD_ID}" -H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json")

# actual registered ip
registered=$(echo ${REC}|jq '.result.content')
# current real external ip
current=\"$(curl -s ifconfig.me || curl -s icanhazip.com)\"

# function to update record ip (other values remain the same)
function change_record() {
    name=$(echo ${REC}|jq '.result.name')
    type=$(echo ${REC}|jq '.result.type')
    ttl=$(echo ${REC}|jq '.result.ttl')
    proxied=$(echo ${REC}|jq '.result.proxied')
    curl -X PUT "${URL}/${ZONE_ID}/dns_records/${RECORD_ID}" -H "Authorization: Bearer ${TOKEN}" \
    --data '{"type":'"${type}"',"name":'"${name}"',"content":'"${current}"',"ttl":'"${ttl}"',"proxied":'"${proxied}"'}'
}

[ "$current" != "$registered" ] && {
    change_record                                              
  }

Save it into a file and give it execution permissions (e.g. chmod u+x ). The last step you need to take is automate the execution of the script each one or five minutes (the shorter the quicker will be the dns update). You can do it setting up a cron job to execute the script.

We have seen a dynamic ip updater script for Cloudflare dns service. Use or modify it at will. If you have any comment or question, let me know.

Leave a Reply

Your email address will not be published.