This is a simple and ugly script to update a single cloudflare A record and get notified when it happens via email Use case: home server, raspberry pi open on network...
Cloudflare up to now does not support record update trough api for following extensions: .cf, .ga, .gq, .ml, or .tk
- Linux
- macOS
./script.sh [-s config_file.json]
Just clone it on your machine
git clone https://github.com/CatMonster/update-cloudflare-record.git
Debian or debian based like Ubuntu
sudo apt-get install jq mailutils
Fedora
sudo dnf install jq mailx
Archlinux or arch based
sudo pacman -Sy jq mailutils
brew install jq
Now you need to retrive all needed data to make work properly the script
Api Key
- Log into your cloudflare account -> Cloudflare dashboard
- Go to API Tokens page
- Create a token with this permissions:
- You can test if your token is working using the following command:
curl -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \
-H "Authorization: Bearer your-token" \
-H "Content-Type:application/json"
- Select interested zone
- Under "Overview" menu you can find the zone id
- To get the interested
id
for therecord
field, you can get it by using postman or whatever method you prefer, use that API call to get a full list of all records inside the specific zone:zones/:zone_identifier/dns_records
(more info inside cloudflare api doc), replace:zone_identifier
andyour-token
with the keys copied previously. Here is an example code:
curl -X GET "https://api.cloudflare.com/client/v4/zones/:zone_identifier/dns_records" \
-H "Authorization: Bearer your-token" \
-H "Content-Type:application/json"
- Take the response and copy the interested
id
Now you can fill out the config.json, under cloudflare object you need to put all retrived data until now like in this exaple below
...
"cloudflare" : {
"token": "your-token",
"zones": "zone_id",
"record": "id"
},
...
If ssmtp isn't configured yet, you need to find the working config for your mail provider, Google and stackExchange are best your friends 😏, I'm using gmail and this config works fine for me. If your google account uses a two factor authentication, you need to create a custom app password to make it work, here is a great tutorial about it. Here is an example of the final ssmtp.conf :
#
# Config file for sSMTP sendmail
#
# The person who gets all mail for userids < 1000
# Make this empty to disable rewriting.
[email protected]
# The place where the mail goes. The actual machine name is required no
# MX records are consulted. Commonly mailhosts are named mail.domain.com
mailhub=smtp.gmail.com:465
# Where will the mail seem to come from?
rewriteDomain=gmail.com
# The full hostname
# [email protected]
[email protected]
AuthPass=your_email_password/custom_app_password
UseTLS=YES
UseSTARTTLS=NO
# Are users allowed to set their own From: address?
# YES - Allow the user to specify their own From: address
# NO - Use the system generated From: address
FromLineOverride=YES
Inside config.json, under mail, you can specify the recipient and a custom subject. If you don't need to send a mail, just leave them blank.
...
"mail" : {
"recipient": "",
"subject": ""
}
...
Any modification at the mail body can be done on mail_template file.
Personally for home use I set a cron running every minute, it's pretty safe because Cloudflare api can be called 1200 times in 5 minutes, for ipfy.org you can do "millions of requests per minute" as they say; keep that in mind if you are planning to conquest the galaxy.
To set a cron, type crontab -e
and you'll get a file like that
Make sure to set system variables to get all commands working as well
printenv | grep SHELL && printenv | grep PATH
otherwise export them:
export SHELL=/bin/bash
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
and call your script
* * * * * cd /home/user/scripts/update-cloudflare-record/ && ./script.sh -s config.json
One little trick, if you don't wish to recieve the terminal output in the emails, you can opt out by placing
MAILTO=""
in the beginning of your cron 😉
As mentioned above i run that every minute; by replacing * * * * * you can set whatever time you want. If you are cron noob like me take a look at crontab guru's website and all their examples
Cloudflare api doc --> https://api.cloudflare.com/