Skip to content

Instantly share code, notes, and snippets.

@yashodhank
Forked from HackingGate/cf-ddns.sh
Last active November 21, 2021 18:52
Show Gist options
  • Save yashodhank/8730c2623052ee859722af71804a87ef to your computer and use it in GitHub Desktop.
Save yashodhank/8730c2623052ee859722af71804a87ef to your computer and use it in GitHub Desktop.
Cloudflare API v4 Dynamic DNS Update for both IPv4 and IPv6 with Proxy Mode On/Off in Bash
#!/bin/bash
LOGTIME=$(date "+%Y-%m-%d %H:%M:%S")
# CHANGE THESE
auth_email="[email protected]"
auth_key="c2547eb745079dac9320b638f5e225cf483cc5cfdda41" # found in cloudflare account settings | Login >> My Profile >>> Scroll down to API Keys and locate Global API Key >>>> Click API Key to see your API identifier
record_name="www.example.com"
zone_identifier="023e105f4ecef8ad9ca31a8372d0c353"
record_identifier_ipv4="372e67954025e0ba6aaa6d586b9e0b59" # use List DNS Records api to get record id, link below ↓ or see help above.
record_identifier_ipv6="372e67954025e0ba6aaa6d586b9e0b5a" # https://api.cloudflare.com/#dns-records-for-a-zone-list-dns-records
proxy_mode_on=true
# MAYBE CHANGE THESE
ipv4=$(curl -s http://ipv4.whatismyip.akamai.com)
ipv6=$(curl -s http://ipv6.whatismyip.akamai.com)
# SCRIPT START
update_ipv4=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records/$record_identifier_ipv4" \
-H "X-Auth-Email: $auth_email" \
-H "X-Auth-Key: $auth_key" \
-H "Content-Type: application/json" \
--data "{\"id\":\"$zone_identifier\",\"type\":\"A\",\"name\":\"$record_name\",\"content\":\"$ipv4\",\"proxied\":$proxy_mode_on}")
update_ipv6=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records/$record_identifier_ipv6" \
-H "X-Auth-Email: $auth_email" \
-H "X-Auth-Key: $auth_key" \
-H "Content-Type: application/json" \
--data "{\"id\":\"$zone_identifier\",\"type\":\"AAAA\",\"name\":\"$record_name\",\"content\":\"$ipv6\",\"proxied\":$proxy_mode_on}")
if [[ $update_ipv4 == *"\"success\":false"* ]]; then
message="API UPDATE A RECORD FAILED. DUMPING RESULTS:\n$update_ipv4"
echo -e "['$LOGTIME'] $message"
exit 1
else
message="A record updated to: $ipv4"
echo "['$LOGTIME'] $message"
fi
if [[ $update_ipv6 == *"\"success\":false"* ]]; then
message="API UPDATE AAAA RECORD FAILED. DUMPING RESULTS:\n$update_ipv6"
echo -e "['$LOGTIME'] $message"
exit 1
else
message="AAAA record updated to: $ipv6"
echo "['$LOGTIME'] $message"
fi
# Run every 10 minutes
# crontab -e
*/10 * * * * /path-to-file/ddns/cf-ddns.sh >> /path-to-file/ddns/cf-ddns.log 2>&1

To find Zone ID for domain

you need jq and curl installed to run following:
sudo apt install jq curl -y

Fetch Zones

curl -s -X GET "https://api.cloudflare.com/client/v4/zones/?per_page=100" -H "X-Auth-Email: [email protected]" -H "X-Auth-Key: a123344555566789cc886c1c12347cf9ee53c" -H "Content-Type: application/json"| jq -r '.result[] | "\(.id) \(.name)"'
# Example Output:
# f123456789cfcb7adb712345638102ca domain1.ext

To find Record ID for A & AAAA Record (IPv4 & IPv6)

Then find Record ID for A OR AAAA using zone id obtained in previous curl call:

FOR IPv4 i.e. A Record

curl -s -X GET "https://api.cloudflare.com/client/v4/zones/<replace-with-zone-id-from-previouscommand>/dns_records?type=A&name=domain1.ext&content=<replace-with-ipv4-from-cloudflare-dashboard>&page=1&per_page=20&order=type&direction=desc&match=all" -H "X-Auth-Email: [email protected]" -H "X-Auth-Key: a123344555566789cc886c1c12347cf9ee53c" -H "Content-Type: application/json"| jq -r '.result[] | "\(.id) \(.name)"'
#### Example Output: Record ID & Name

For IPv6 i.e. AAAA Record

curl -s -X GET "https://api.cloudflare.com/client/v4/zones/<replace-with-zone-id-from-previouscommand>/dns_records?type=AAAA&name=domain1.ext&content=<replace-with-ipv6-from-cloudflare-dashboard>&page=1&per_page=20&order=type&direction=desc&match=all" -H "X-Auth-Email: [email protected]" -H "X-Auth-Key: a123344555566789cc886c1c12347cf9ee53c" -H "Content-Type: application/json"| jq -r '.result[] | "\(.id) \(.name)"'
#### Example Output: Record ID & Name

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