Skip to content

Instantly share code, notes, and snippets.

@Ciantic
Last active March 17, 2025 09:13
Show Gist options
  • Save Ciantic/4e543f2d878a87a38c25032d5c727bf2 to your computer and use it in GitHub Desktop.
Save Ciantic/4e543f2d878a87a38c25032d5c727bf2 to your computer and use it in GitHub Desktop.
cloudflare dyndns script / update a A and AAAA record using bash script
#!/bin/bash
# Author: Jari Pennanen
# Url: https://gist.github.com/Ciantic/4e543f2d878a87a38c25032d5c727bf2
AUTH_EMAIL="[email protected]" # Your Cloudflare email
AUTH_KEY="" # Get this from My profile -> API Keys -> View
DOMAIN="example.com" # main domain
SUBDOMAIN="home.example.com" # set A and AAAA-record of this subdomain
ZONE_ID=$(\
curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$DOMAIN&status=active" \
-H "X-Auth-Email: $AUTH_EMAIL" \
-H "X-Auth-Key: $AUTH_KEY" \
-H "Content-Type: application/json" \
| \
python3 -c "import sys, json; print(json.load(sys.stdin)['result'][0]['id'])" \
)
if [[ -z "$ZONE_ID" ]]; then
echo "Zone ID can't be determined" 1>&2
exit 1
fi
echo "Zone ID:" $ZONE_ID
RECORD_IPV4_ID=$(\
curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?type=A&name=$SUBDOMAIN" \
-H "X-Auth-Email: $AUTH_EMAIL" \
-H "X-Auth-Key: $AUTH_KEY" \
-H "Content-Type: application/json" \
| \
python3 -c "import sys, json; print(json.load(sys.stdin)['result'][0]['id'])" \
)
if [[ -z "$RECORD_IPV4_ID" ]]; then
echo "Record ID can't be determined" 1>&2
exit 1
fi
echo "A-Record ID:" $RECORD_IPV4_ID
RECORD_IPV6_ID=$(\
curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?type=AAAA&name=$SUBDOMAIN" \
-H "X-Auth-Email: $AUTH_EMAIL" \
-H "X-Auth-Key: $AUTH_KEY" \
-H "Content-Type: application/json" \
| \
python3 -c "import sys, json; print(json.load(sys.stdin)['result'][0]['id'])" \
)
if [[ -z "$RECORD_IPV6_ID" ]]; then
echo "Record ID can't be determined" 1>&2
exit 1
fi
echo "AAAA-Record ID:" $RECORD_IPV6_ID
IPV4_ADDRESS=$(\
curl -s -4 https://ifconfig.co/ip \
)
if [[ -z "$IPV4_ADDRESS" ]]; then
echo "IPV4 Address can't be determined" 1>&2
exit 1
fi
IPV6_ADDRESS=$(\
curl -s -6 https://ifconfig.co/ip \
)
if [[ -z "$IPV6_ADDRESS" ]]; then
echo "IPV6 Address can't be determined" 1>&2
exit 1
fi
echo "IP Address: " $IPV4_ADDRESS " / " $IPV6_ADDRESS
# Note: TTL=1 automatic
IPV4_UPDATE_RESULT=$(\
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_IPV4_ID" \
-H "X-Auth-Email: $AUTH_EMAIL" \
-H "X-Auth-Key: $AUTH_KEY" \
-H "Content-Type: application/json" \
--data '{"type":"A","name":"'"$SUBDOMAIN"'","content":"'"$IPV4_ADDRESS"'","ttl":1,"proxied":false}' \
| \
python3 -c "import sys, json; print(json.load(sys.stdin)['success'])" \
)
if [[ "$IPV4_UPDATE_RESULT" -ne "True" ]]; then
echo "IPV4 Address can't be set" 1>&2
exit 1
fi
IPV6_UPDATE_RESULT=$(\
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_IPV6_ID" \
-H "X-Auth-Email: $AUTH_EMAIL" \
-H "X-Auth-Key: $AUTH_KEY" \
-H "Content-Type: application/json" \
--data '{"type":"AAAA","name":"'"$SUBDOMAIN"'","content":"'"$IPV6_ADDRESS"'","ttl":1,"proxied":false}' \
| \
python3 -c "import sys, json; print(json.load(sys.stdin)['success'])" \
)
if [[ "$IPV6_UPDATE_RESULT" -ne "True" ]]; then
echo "IPV6 Address can't be set" 1>&2
exit 1
fi
@fltb
Copy link

fltb commented Aug 19, 2023

Solved by changing the cloudflare mail from Firefox Relay to Outlook. Thank you!

--- Original ---
I've tried this, filled arg correctly but only got an error:

Traceback (most recent call last):
File "", line 1, in
TypeError: 'NoneType' object is not subscriptable
Zone ID can't be determined

run curl manually and got error json:

{"success":false,"errors":[{"code":6003,"message":"Invalid request headers","error_chain":[{"code":6102,"message":"Invalid format for X-Auth-Email header"}]}],"messages":[],"result":null}(base)

If I fill Zone ID manually, then this script will stuck at $RECORD_IPV6_ID . Is Cloudflare API broken?

@jessy5765
Copy link

Solved by changing the cloudflare mail from Firefox Relay to Outlook. Thank you!

--- Original --- I've tried this, filled arg correctly but only got an error:

Traceback (most recent call last):
File "", line 1, in
TypeError: 'NoneType' object is not subscriptable
Zone ID can't be determined

run curl manually and got error json:

{"success":false,"errors":[{"code":6003,"message":"Invalid request headers","error_chain":[{"code":6102,"message":"Invalid format for X-Auth-Email header"}]}],"messages":[],"result":null}(base)

If I fill Zone ID manually, then this script will stuck at $RECORD_IPV6_ID . Is Cloudflare API broken?

What exactly did you do to "change the cloudflare mail from firefox relay to outlook." I dont see anything in the script mentioning this so I am not entirely sure. I am having this same issue.

@Ciantic
Copy link
Author

Ciantic commented Jan 11, 2025

This worked for me today, if your Auth email doesn't work it is something else.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment