Note: This is an update to a post from 2019 and features a rewrite in Python with various new features including IPv6 support, logging, argument parser, …
I’m using Cloudflare as CDN and DNS provider as well as domain registrar. For a system with an external IPv4 address that changes daily I needed a way to dynamically update a DNS record at Cloudflare with the system’s current external IP address.
There are numerous ways to do DynDNS but I wanted to get into Cloudflare’s API anyway and it turns out that this is, at least in my opinion, much easier to set up than some generic DynDNS package.
Getting the script
I’ve written a Python script, based on a bash script by benkulbertis.
The Python script does not require a general API token. So you can set up API tokens specifically authorized for what the script needs to do.
You can get the script here.
Setting up API tokens
The script needs two tokens:
- one to read DNS records and settings
- one to actually edit a DNS zone
To set the tokens up, log in to your Cloudflare account and go to this page.
Note, that you can also limit the tokens to a specific domain! This is of course important to know if you have multiple domains in your Cloudflare account and the script shall only read/edit the settings of one of these.
On the API token page, click Create Token and use the template Edit zone DNS.
Alternatively, click Get started next to Create Custom Token and configure the token as follows:
Click here for a screenshot.
On the API token page, click Create Token and click Get started next to Create Custom Token.
Click here for a screenshot.
Create config file
The script uses a YAML-format config file and assumes it at
./cloudflare-update-record_config.yaml. You can give a different path using the
-c | --config parameter.
read_token: "<YOUR READ TOKEN>" edit_token: "<YOUR EDIT TOKEN>" zone_name: "<YOUR ZONE NAME>" record_name: "<YOUR RECORD NAME>"
So if I wanted to change a DNS record called hello.example.com using a read token foo and an edit token bar, the config would look like this:
read_token: "foo" edit_token: "bar" zone_name: "example.com" record_name: "hello.example.com"
Lastly run the script with your desired parameters. I recommend reading the brief usage info at least once:
The scripts logs to
cloudflare-update-record.log with log level
info by default. You can change the log file and log level, see
It gets the external IP address from a provider, by default: icanhazip.com
You can specify a different provider, see
The provider must return just the IP address as plain text on a
HTTP GET request - no additional HTML or anything else. Assuming an external IPv4 address
184.108.40.206, it should look like this, when tested with curl:
# curl https://ipv4.icanhazip.com 220.127.116.11
Update a DNS A (IPv4) record
Update a DNS AAAA (IPv6) record
Check the log for a message
INFO: DNS A record update succeeded, IP changed to: <YOUR IP ADDRESS>
and remember that it might take up to 24 hours for your DNS update to be propagated around the world.