#!/bin/bash ### # Cloudflare API DDNS update script # Heavily inspired by https://gist.github.com/lifehome/eb3f7d798f9bc6720cdc7d2be1238d4f # # Requirements: jq, curl ### auth_token="XXXXXXXXXXXXXXX" # Token generated from "My profile > API Tokens" zone_identifier="XXXXXXX" # Can be found in the "Overview" tab of your domain record_name="my.hostname.example.com" # Which record you want to be synced # DO NOT CHANGE LINES BELOW #ip=$(curl -s https://ipv4.icanhazip.com/) ip=$(curl -s https://ifconfig.me/ip) # SCRIPT START echo "[Cloudflare DDNS] Check Initiated" # Seek for the record record=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records?name=$record_name" -H "Authorization: Bearer $auth_token" -H "Content-Type: application/json") # Can't do anything without the record if [[ $record == *"\"count\":0"* ]]; then >&2 echo -e "[Cloudflare DDNS] Record does not exist, perhaps create one first?" exit 1 fi # Set existing IP address from the fetched record old_ip=$(echo "$record" | jq -r ".result[0].content") # Compare if they're the same if [ $ip == $old_ip ]; then echo "[Cloudflare DDNS] IP address has not changed." exit 0 fi # Set the record identifier from result record_identifier=$(echo "$record" | jq -r ".result[0].id") # The execution of update update=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records/$record_identifier" -H "Authorization: Bearer $auth_token" -H "Content-Type: application/json" --data "{\"id\":\"$zone_identifier\",\"type\":\"A\",\"proxied\":false,\"name\":\"$record_name\",\"content\":\"$ip\"}") # The moment of truth case "$update" in *"\"success\":false"*) >&2 echo -e "[Cloudflare DDNS] Update failed for $record_identifier. DUMPING RESULTS:\n$update" exit 1;; *) echo "[Cloudflare DDNS] IPv4 context '$ip' has been synced to Cloudflare.";; esac