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
@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