restore repo
This commit is contained in:
parent
729dcdeed3
commit
ea0fb8af02
4 changed files with 327 additions and 2 deletions
169
cloudflare-dns-update.sh
Executable file
169
cloudflare-dns-update.sh
Executable file
|
|
@ -0,0 +1,169 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
### Function to log messages
|
||||
log() {
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") $1" | tee -a "$LOG_FILE" >&2
|
||||
}
|
||||
|
||||
### Function to log messages only to the log file
|
||||
log_to_file() {
|
||||
echo "$(date "+%Y-%m-%d %H:%M:%S") $1" >> "$LOG_FILE"
|
||||
}
|
||||
|
||||
### Create log file
|
||||
parent_path="$(dirname "${BASH_SOURCE[0]}")"
|
||||
LOG_FILE="${parent_path}/cloudflare-dns-update.log"
|
||||
touch "$LOG_FILE"
|
||||
|
||||
log "==> Script started"
|
||||
|
||||
### Validate config file
|
||||
config_file="${1:-${parent_path}/cloudflare-dns-update.conf}"
|
||||
if ! source "$config_file"; then
|
||||
log "Error! Missing configuration file $config_file or invalid syntax!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
### Check validity of parameters
|
||||
if ! [[ "$ttl" =~ ^[0-9]+$ ]] || { [ "$ttl" -lt 120 ] || [ "$ttl" -gt 7200 ]; } && [ "$ttl" -ne 1 ]; then
|
||||
log "Error! ttl must be 1 or between 120 and 7200"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
### Valid IPv4 and IPv6 Regex
|
||||
readonly IPV4_REGEX='^([0-9]{1,3}\.){3}[0-9]{1,3}$'
|
||||
readonly IPV6_REGEX='^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$'
|
||||
|
||||
### Function to get external IP (IPv4 or IPv6)
|
||||
get_external_ip() {
|
||||
local ip_type=$1
|
||||
local sources=()
|
||||
local regex
|
||||
|
||||
case "$ip_type" in
|
||||
ipv4)
|
||||
sources=("https://api.ipify.org" "https://checkip.amazonaws.com" "https://ifconfig.me/ip")
|
||||
regex="$IPV4_REGEX"
|
||||
;;
|
||||
ipv6)
|
||||
sources=("https://api64.ipify.org" "https://ifconfig.co/ip")
|
||||
regex="$IPV6_REGEX"
|
||||
;;
|
||||
*)
|
||||
log "Error! Invalid IP type specified: $ip_type"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
for source in "${sources[@]}"; do
|
||||
if ip=$(curl -"${ip_type:3:1}" -s "$source" --max-time 10) && [[ "$ip" =~ $regex ]]; then
|
||||
echo "$ip"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
|
||||
log "Error! Unable to retrieve $ip_type address from any source."
|
||||
return 1
|
||||
}
|
||||
|
||||
### Get external IPs
|
||||
ipv4=$(get_external_ip "ipv4") || ipv4=""
|
||||
ipv6=$(get_external_ip "ipv6") || ipv6=""
|
||||
|
||||
[ -n "$ipv4" ] && log "==> External IPv4 is: $ipv4"
|
||||
[ -n "$ipv6" ] && log "==> External IPv6 is: $ipv6"
|
||||
|
||||
### Function to extract value from JSON
|
||||
json_extract() {
|
||||
local key=$1
|
||||
sed -n 's/.*"'"$key"'":"\?\([^,"]*\)"\?.*/\1/p'
|
||||
}
|
||||
|
||||
### Function to update DNS record
|
||||
update_dns_record() {
|
||||
local record=$1
|
||||
local ip=$2
|
||||
local type=$3
|
||||
local ttl=$4
|
||||
local proxied=$5
|
||||
|
||||
# Get the DNS record information from Cloudflare API
|
||||
local cloudflare_record_info
|
||||
cloudflare_record_info=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records?type=$type&name=$record" \
|
||||
-H "Authorization: Bearer $cloudflare_zone_api_token" \
|
||||
-H "Content-Type: application/json")
|
||||
|
||||
log_to_file "Cloudflare API response: $cloudflare_record_info" # Log the API response to file for debugging
|
||||
|
||||
if [[ $cloudflare_record_info == *"\"success\":false"* ]]; then
|
||||
log "Error! Can't get $record ($type) record information from Cloudflare API"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Get the current IP and proxy status from the API response
|
||||
local current_ip
|
||||
current_ip=$(echo "$cloudflare_record_info" | json_extract "content")
|
||||
local current_proxied
|
||||
current_proxied=$(echo "$cloudflare_record_info" | json_extract "proxied")
|
||||
|
||||
# Check if IP or proxy have changed
|
||||
if [ "$current_ip" == "$ip" ] && [ "$current_proxied" == "$proxied" ]; then
|
||||
log "==> DNS $type record of $record is $current_ip, no changes needed."
|
||||
return 0
|
||||
fi
|
||||
|
||||
log "==> DNS $type record of $record is: $current_ip. Trying to update..."
|
||||
|
||||
# Get the DNS record ID from response
|
||||
local cloudflare_dns_record_id
|
||||
cloudflare_dns_record_id=$(echo "$cloudflare_record_info" | json_extract "id")
|
||||
|
||||
# Push new DNS record information to Cloudflare API
|
||||
if ! curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records/$cloudflare_dns_record_id" \
|
||||
-H "Authorization: Bearer $cloudflare_zone_api_token" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data "{\"type\":\"$type\",\"name\":\"$record\",\"content\":\"$ip\",\"ttl\":$ttl,\"proxied\":$proxied}" | grep -q '"success":true'; then
|
||||
log "Error! Update failed for $record ($type)"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log "==> Success!"
|
||||
log "==> $record DNS $type Record updated to: $ip, ttl: $ttl, proxied: $proxied"
|
||||
|
||||
# Telegram notification
|
||||
if [ "${notify_me_telegram:-no}" == "yes" ]; then
|
||||
send_telegram_notification "$record" "$type" "$ip" "$ttl" "$proxied"
|
||||
fi
|
||||
}
|
||||
|
||||
### Function to send Telegram notification
|
||||
send_telegram_notification() {
|
||||
local record=$1
|
||||
local type=$2
|
||||
local ip=$3
|
||||
local ttl=$4
|
||||
local proxied=$5
|
||||
|
||||
if ! curl -s -X POST "https://api.telegram.org/bot${telegram_bot_API_Token}/sendMessage" \
|
||||
-H "Content-Type: application/json" \
|
||||
--data "{\"chat_id\":\"${telegram_chat_id}\",\"text\":\"DNS Record Update\nDomain: ${record}\nType: ${type}\nIP: ${ip}\nTTL: ${ttl}\nProxied: ${proxied}\"}" | grep -q '"ok":true'; then
|
||||
log "Error! Telegram notification failed for $record ($type)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Update DNS records
|
||||
|
||||
for dns_record in "${dns_record[@]}"; do
|
||||
IFS=',' read -r record ttl proxied <<< "$dns_record"
|
||||
|
||||
ttl="${ttl:-1}" # if TTL is null, set to automatic 1
|
||||
proxied="${proxied:-true}" # if proxied is null, set true
|
||||
|
||||
[ -n "$ipv4" ] && update_dns_record "$record" "$ipv4" "A" "$ttl" "$proxied"
|
||||
[ -n "$ipv6" ] && update_dns_record "$record" "$ipv6" "AAAA" "$ttl" "$proxied"
|
||||
done
|
||||
|
||||
log "==> Script finished"
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue