Last active
May 14, 2024 21:31
-
-
Save kernelkaribou/5bd4a1b845ad005df6ab595c55e7dbeb to your computer and use it in GitHub Desktop.
Used to regularly update a Cloudflare DNS record from your Synology NAS.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
#################################################################################### | |
# Author: Kernelkaribou@github | |
# | |
# Purpose: Update a DNS record hosted at Cloudflare to represent network public IP. | |
# Based upon Cloudflare API v4 | |
# | |
# Additional Notes: This will send notifications to Synology log center. | |
# Comment out writeLog lines if not desired or on Synology platform | |
# | |
# Last Update: 10/22/2022 | |
#################################################################################### | |
### User Defined | |
#Main domain zone e.g. example.com | |
ZONE_DOMAIN="example.com" | |
#DNS Record to update e.g. home.example.com | |
DNS_RECORD="record.example.com" | |
#API Key generated with Zone Read and DNS Edit permissions on above Main Zone, NOT A GLOBAL KEY! | |
API_KEY="MyCloudFlareDomainApiKey" | |
#Send message of execution to log center on Synology | |
writeLog() | |
{ | |
LOG_MESSAGE=$(synologset1 sys $1 0x11800000 "Cloudflare DDNS - $2") | |
echo $2 | |
} | |
### Main Script | |
#Get my public IP address | |
PUBLIC_IP=$(curl -s ifconfig.me) | |
#Get current DNS Record configured IP from Cloudflare | |
CURRENT_DNS_IP=$(nslookup -type=a $DNS_RECORD 1.1.1.1 | grep 'Address' | awk -F":" 'NF==2' | awk '{ if($2 !~ /#/){print $2}}') | |
#CHECK IF DNS Record matches Public IP | |
if [[ $CURRENT_DNS_IP == $PUBLIC_IP ]]; then | |
#IP Matches no need to continue | |
MESSAGE="$DNS_RECORD IP: $CURRENT_DNS_IP, Public IP: $PUBLIC_IP Match! No DNS update necessary!" | |
MESSAGE_TYPE="info" | |
writeLog "$MESSAGE_TYPE" "$MESSAGE" | |
else | |
MESSAGE="$DNS_RECORD IP $CURRENT_DNS_IP, Public IP: $PUBLIC_IP Mismatch! Updating!" | |
MESSAGE_TYPE="info" | |
writeLog "$MESSAGE_TYPE" "$MESSAGE" | |
#Getting Domain Zone ID | |
ZONE_RESULT=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$ZONE_DOMAIN" \ | |
-H "Authorization: Bearer $API_KEY" \ | |
-H "Content-Type: application/json") | |
ZONE_ID=$(echo $ZONE_RESULT | grep -oP "(?<={\"result\":\[{\"id\":\").*?(?=\",)") | |
echo "ZONE ID: $ZONE_ID" | |
if [ -z "$ZONE_ID" ]; then | |
MESSAGE="Unable to get ID for Zone '$ZONE_DOMAIN', check script configuration and API key" | |
MESSAGE_TYPE="err" | |
sendNotification "$NOTIFICATION" | |
writeLog "$MESSAGE_TYPE" "$MESSAGE" | |
echo $ZONE_RESULT | |
exit 1 | |
fi | |
#Getting DNS Record ID | |
RECORD_RESULT=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?name=$DNS_RECORD" \ | |
-H "Authorization: Bearer $API_KEY" \ | |
-H "Content-Type: application/json") | |
DNS_ID=$(echo $RECORD_RESULT | grep -oP "(?<={\"result\":\[{\"id\":\").*?(?=\",)") | |
echo "DNS RECORD ID: $DNS_ID" | |
if [ -z "$DNS_ID" ]; then | |
MESSAGE="Unable to get ID for DNS Record '$DNS_RECORD', check script configuration and Zone ID" | |
MESSAGE_TYPE="err" | |
sendNotification "$NOTIFICATION" | |
writeLog "$MESSAGE_TYPE" "$MESSAGE" | |
echo $RECORD_RESULT | |
exit 1 | |
fi | |
#Updating DNS record. | |
RESPONSE=$(curl -s -X PUT https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$DNS_ID \ | |
-H "Content-Type: application/json" \ | |
-H "Authorization: Bearer $API_KEY" \ | |
-H "cache-control: no-cache" \ | |
-d "{\"type\" : \"A\", \"name\" : \"$DNS_RECORD\", \"content\" : \"$PUBLIC_IP\" }") | |
#Update failed | |
ERROR_STRING='"success":false,' | |
if [[ "$RESPONSE" == *"$ERROR_STRING"* ]]; then | |
ERROR_MESSAGE="" | |
if [[ $RESPONSE =~ \"errors\"\:[{.*[A-Za-z0-9].*}\] ]]; then | |
ERROR_MESSAGE=$(echo ${BASH_REMATCH[0]} | sed 's/[^a-z A-Z:0-9]/ /g') | |
else | |
ERROR_MESSAGE="Unable to parse error message" | |
fi | |
MESSAGE="DNS Record $DNS_RECORD error on update: $PUBLIC_IP - $ERROR_MESSAGE" | |
MESSAGE_TYPE="err" | |
#Update was successful | |
else | |
MESSAGE="DNS Record $DNS_RECORD successfully updated to $PUBLIC_IP" | |
MESSAGE_TYPE="info" | |
NOTIFICATION="$DNS_RECORD was successfully updated to $PUBLIC_IP" | |
fi | |
writeLog "$MESSAGE_TYPE" "$MESSAGE" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment