Skip to content

Instantly share code, notes, and snippets.

@remimikalsen
Last active May 24, 2024 15:52
Show Gist options
  • Save remimikalsen/29227894f052a3b7333180f0fdba41c9 to your computer and use it in GitHub Desktop.
Save remimikalsen/29227894f052a3b7333180f0fdba41c9 to your computer and use it in GitHub Desktop.
Update your Public IP on your cloudflare domains automatically
#/bin/bash
# https://theawesomegarage.com/blog/godaddy-terminated-my-free-dns-management-api-now-what
# This script will retrieve your Public IP, and if the service IP is different from last time
# the script will attempt to call Cloudflare's specific API endpoint for DNS updates.
# I suggest calling the script from crontab like this, for example every minute:
# */1 * * * * /mnt/web/scripts/updatecloudflare.sh /mnt/web/scripts/theawesomegarage.org.cfg >> /var/log/dns-updates.log
# You will have to give a .cfg-file for each domain you want to update, formatted like this (without the comments, obviously):
#TOKEN="*****************"
#ZONE_ID="*****************"
#DNS_RECORD_ID="***************"
#NAME="@"
#PROXIED="true"
#TYPE="A"
#COMMENT="IP changed at ISP"
#TTL=600
# Create your token here to Edit DNS: https://dash.cloudflare.com/profile/api-tokens
# Zone ID: You find it on the *Overview* page for your zone/domain to the right
# Zone Record ID - you need to call a CloudFlare API to find it:
# curl --request GET --url https://api.cloudflare.com/client/v4/zones/ZONE_ID_HERE/dns_records --header 'Content-Type: application/json' -H "Authorization: Bearer TOKEN_HERE"
# Check if a configuration file is provided as an argument
if [ -z "$1" ]; then
echo "Usage: $0 <config_file>"
exit 1
fi
# Source the configuration file
CONFIG_FILE="$1"
source "$CONFIG_FILE"
record_cache=/tmp/.cloudflareDNS.$TYPE.$ZONE_ID.$NAME.addr
[ -e $record_cache ] && old_record_ip=`cat $record_cache`
# A=IPv4 or AAAA=IPv6
if [ $TYPE = "AAAA" ]; then
public_ip=$(ip -6 addr list scope global $device | grep -v " fd" | sed -n 's/.*inet6 \([0-9a-f:]\+\).*/\1/p' | head -n 1)
else
public_cache=/tmp/.myPublicIP
[ -e $public_cache ] && public_ip=`cat $public_cache`
# Check if the IPv4 cached public ip address matches the IPv4 pattern
if ! [[ $public_ip =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
echo "$TYPE.$ZONE_ID.$NAME: $(date): Invalid Public IP Cache"
exit 1
fi
fi
# Re-validate that we got an IPv4 or IPv6 address
if [ -z "$public_ip" ]; then
echo "$TYPE.$ZONE_ID.$NAME: $(date): Empty IP. Exiting."
exit 1
fi
# Check cache ip, if matched, program exit
if [ "$old_record_ip" = "$public_ip" ]; then
#echo "$TYPE.$ZONE_ID.$NAME: $(date): Still $public_ip. Exiting."
exit
else
echo "$TYPE.$ZONE_ID.$NAME: $(date): New IP $public_ip. Updating..."
CONTENT=$public_ip
# Define the API URL
API_URL="https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$DNS_RECORD_ID"
# Define the JSON payload
JSON_PAYLOAD=$(cat <<EOF
{
"content": "$CONTENT",
"name": "$NAME",
"proxied": $PROXIED,
"type": "$TYPE",
"comment": "$COMMENT",
"ttl": $TTL
}
EOF
)
nresult=$(curl -o /dev/null -s -w "%{http_code}" \
--request PUT \
--url "$API_URL" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer $TOKEN" \
--data "$JSON_PAYLOAD")
if [ "$nresult" = "200" ]; then
echo "$TYPE.$ZONE_ID.$NAME: $(date): OK $nresult"
echo $public_ip > $record_cache
else
echo "$TYPE.$ZONE_ID.$NAME: $(date): NOT OK $nresult"
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment