Created
September 12, 2020 01:19
-
-
Save zikeji/87c0b750e60eeff833db5cf173521c58 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 | |
CF_TOKEN="Gh_0000000000000000000000000000000000000" # generated API token with DNS edit on your zone ID | |
CF_ZONE_ID="00000000000000000000000000000000" # the zone ID found in the Overview tab | |
CF_RECORD="dynamic.example.domain" # your record within the zone you want to update | |
# SCRIPT BELOW - DON'T EDIT | |
RESET=$(tput sgr0) | |
DATE_ANSI=$(tput setaf 4) | |
HEADER_ANSI="$(tput setaf 6)$(tput bold)" | |
ERROR_ANSI="$(tput setab 1)$(tput setaf 7)$(tput bold)" | |
log() { | |
echo "${DATE_ANSI}[`date -u`]${RESET}" "${HEADER_ANSI}[CloudFlare DDNS]${RESET} $@" | |
} | |
log_error() { | |
log "${ERROR_ANSI}[$1]${RESET}" "${@:2}" | |
} | |
if ! command -v jq &> /dev/null; then | |
log_error "Error" "jq is not installed." | |
exit 1 | |
fi | |
if ! command -v curl &> /dev/null; then | |
log_error "Error" "curl is not installed." | |
exit 1 | |
fi | |
api() { | |
local result; | |
result=$(curl -s -X $1 \ | |
-H "Authorization: Bearer $CF_TOKEN" \ | |
-H "Content-Type: application/json" \ | |
--data "$3" \ | |
"https://api.cloudflare.com/client/v4/zones/$CF_ZONE_ID/dns_records$2") | |
if [[ "$?" != "0" ]]; then | |
log_error "CURL Error" "Returned non-zero. Check your WAN connectivity." | |
exit 1 | |
fi | |
if [[ $(echo "$result" | jq -r '.success') == "false" ]]; then | |
log_error "CloudFlare Error" "CloudFlare call did not succeed. Check credentials." | |
exit 1 | |
fi | |
echo "$result" | |
} | |
UPDATES=false | |
IPV4=$(dig -4 TXT +short o-o.myaddr.l.google.com @ns1.google.com | awk -F'"' '{ print $2 }') | |
IPV6=$(dig -6 TXT +short o-o.myaddr.l.google.com @ns1.google.com | awk -F'"' '{ print $2 }') | |
RESULT=$(api GET "?name=$CF_RECORD") | |
if [[ "$?" != "0" ]]; then | |
echo "$RESULT" | |
exit 1 | |
fi | |
RECORD_IPV4=$(echo "$RESULT" | jq -r '.result[] | select(.type == "A") | .content') | |
RECORD_IPV4_ID=$(echo "$RESULT" | jq -r '.result[] | select(.type == "A") | .id') | |
if [[ "$RECORD_IPV4_ID" == "" ]]; then | |
log "Warning: No A record found for $CF_RECORD. Skipped A update." | |
elif [[ "$RECORD_IPV4" != "$IPV4" ]]; then | |
IPV4_RESULT=$(api PUT "/$RECORD_IPV4_ID" "{\"id\":\"$RECORD_IPV4_ID\",\"type\":\"A\",\"proxied\":false,\"name\":\"$CF_RECORD\",\"content\":\"$IPV4\"}") | |
if [[ "$?" != "0" ]]; then | |
echo "$RESULT" | |
exit 1 | |
fi | |
UPDATES=true | |
log "Updated A $CF_RECORD to $IPV4" | |
fi | |
RECORD_IPV6=$(echo "$RESULT" | jq -r '.result[] | select(.type == "AAAA") | .content') | |
RECORD_IPV6_ID=$(echo "$RESULT" | jq -r '.result[] | select(.type == "AAAA") | .id') | |
if [[ "$RECORD_IPV6_ID" == "" ]]; then | |
log "Warning: No AAAA record found for $CF_RECORD. Skipped AAAA update." | |
elif [[ "$RECORD_IPV6" != "$IPV6" ]]; then | |
IPV6_RESULT=$(api PUT "/$RECORD_IPV6_ID" "{\"id\":\"$RECORD_IPV6_ID\",\"type\":\"AAAA\",\"proxied\":false,\"name\":\"$CF_RECORD\",\"content\":\"$IPV6\"}") | |
if [[ "$?" != "0" ]]; then | |
echo "$RESULT" | |
exit 1 | |
fi | |
UPDATES=true | |
log "Updated AAAA $CF_RECORD to $IPV6" | |
fi | |
if [[ "$UPDATES" == "false" ]]; then | |
log "No updates needed." | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have it installed as a crontab in my
$HOME/bin
folder. My crontab looks like this:Keep in mind because I'm using tput in the script to make it fancy you should set the TERM=xterm in either the script or the crontab. You could also change the formatting lines (at the top) to remove the tput reliance.