Skip to content

Instantly share code, notes, and snippets.

@lukedesu
Last active May 30, 2024 05:59
Show Gist options
  • Save lukedesu/80751505133828c122470bc56388b6c0 to your computer and use it in GitHub Desktop.
Save lukedesu/80751505133828c122470bc56388b6c0 to your computer and use it in GitHub Desktop.
Setting Up Automatic Cloudflare DNS Updates with Cron
#!/bin/bash
auth_email="example@gmail.com" # The email used to login 'https://dash.cloudflare.com'
auth_key="YOUR_KEY" # Top right corner, "My profile" > "Global API Key"
zone_identifier="YOUR_ZONE_ID" # Can be found in the "Overview" tab of your domain, Zone ID is at the right bottom
record_names=("www.example.com" "example.com") # List of records you want to be synced
proxy=false # Set the proxy to true or false
log_file="$(dirname "$0")/update-logs.log"
ip_file="$(dirname "$0")/current_ip.txt"
# Ensure the log file is writable
if [ ! -e "$log_file" ]; then
touch "$log_file"
fi
chmod 664 "$log_file"
# Ensure the IP file exists
if [ ! -e "$ip_file" ]; then
touch "$ip_file"
fi
###########################################
## Function to log messages with timestamp
###########################################
log_message() {
local message=$1
local timestamp=$(date +"%Y-%m-%d %H:%M:%S")
echo -e "[$timestamp] $message" | tee -a "$log_file"
}
###########################################
## Check if we have a public IP
###########################################
ip=$(curl -s https://ipv4.icanhazip.com/ || curl -s https://api.ipify.org)
if [ -z "$ip" ]; then
log_message "No public IP found."
exit 1
fi
###########################################
## Check if the IP has changed
###########################################
stored_ip=$(cat "$ip_file")
if [ "$ip" == "$stored_ip" ]; then
log_message "IP has not changed. Current IP: $ip"
exit 0
fi
###########################################
## Function to update DNS record
###########################################
update_record() {
local record_name=$1
###########################################
## Seek for the A record
###########################################
log_message "Check Initiated for $record_name"
record=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records?name=$record_name" -H "X-Auth-Email: $auth_email" -H "X-Auth-Key: $auth_key" -H "Content-Type: application/json")
###########################################
## Set the record identifier from result
###########################################
record_identifier=$(echo "$record" | grep -Po '(?<="id":")[^"]*' | head -1)
if [ -z "$record_identifier" ]; then
log_message "Record identifier for $record_name not found."
return 1
fi
###########################################
## Change the IP@Cloudflare using the API
###########################################
update=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records/$record_identifier" -H "X-Auth-Email: $auth_email" -H "X-Auth-Key: $auth_key" -H "Content-Type: application/json" --data "{\"type\":\"A\",\"proxied\":${proxy},\"name\":\"$record_name\",\"content\":\"$ip\"}")
###########################################
## Report the status
###########################################
case "$update" in
*""success":false"*)
log_message "$ip $record_name DDNS failed for $record_identifier ($ip). DUMPING RESULTS:\n$update"
return 1
;;
*)
log_message "$ip $record_name DDNS updated."
return 0
;;
esac
}
###########################################
## Loop through all record names
###########################################
for record_name in "${record_names[@]}"; do
update_record "$record_name"
done
###########################################
## Save the current IP
###########################################
echo "$ip" > "$ip_file"
@lukedesu
Copy link
Author

lukedesu commented May 30, 2024

Two Steps to Make it Auto-Running

Assign Permission

Make the script executable by setting the appropriate permissions:

sudo chmod +x ~/cloudflare.sh

Add to Your Crontab List

Open the crontab editor to add a new cron job:

sudo crontab -e

Append the following line to the end of the crontab file to schedule the script to run every 10 minutes:

## must be absolute path here
*/10 * * * * /bin/bash /home/yourname/cloudflare.sh

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