#! /usr/bin/env bash set -euo pipefail ZONE_ID="" ZONE_ID_FILE="" DNS_RECORD="" DNS_RECORD_FILE="" DOMAIN="" CACHED_PUBLIC_IP="" AUTHORIZATION="$(cat .var/bearer)" IP_URL="ifconfig.me/ip" SEND_TELEGRAM="$(pwd)/send_telegram" LOG_FILE_PARENT="/var/log/cloudflare_update" LOG_FILE="${LOG_FILE_PARENT}/$(date +%d_%m_%Y_update_dns).log" mkdir -p "${LOG_FILE_PARENT}" function info() { echo "$(date --iso-8601=minutes) CLOUDFLARE_DNS_UPDATE [INFO]: ${*}" echo "$(date --iso-8601=minutes) CLOUDFLARE_DNS_UPDATE [INFO]: ${*}" >> "${LOG_FILE}" } function error() { echo "$(date --iso-8601=minutes) CLOUDFLARE_DNS_UPDATE [ERROR]: ${*}" } function check_internet_access() { wget -q --spider https://google.com if [ $? -ne 0 ]; then error "No internet connection. Exiting..." exit 1 fi } function check_new_ip() { local new_ip new_ip="$(curl -s ${IP_URL})" if [[ "$new_ip" =~ ^([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})$ ]] then for (( i=1; i<${#BASH_REMATCH[@]}; ++i )) do (( ${BASH_REMATCH[$i]} <= 255 )) || { info "Bad IP from curl. ${new_ip}"; exit 1; } done else info "Bad IP from curl. ${new_ip}"; exit 1; fi if [[ "${new_ip}" == "${CACHED_PUBLIC_IP}" ]]; then info "Public IP has not changed from ${new_ip}. Exiting..." exit 0; else info "Public IP has changed from ${CACHED_PUBLIC_IP} to ${new_ip}. Updating records..." "${SEND_TELEGRAM}" "Public IP has changed from ${CACHED_PUBLIC_IP} to ${new_ip}. Updating records..." CACHED_PUBLIC_IP="${new_ip}" echo "${new_ip}" > ${PUBLIC_IP_FILE} fi } # Parse command-line arguments while [[ $# -gt 0 ]]; do case $1 in -z|--zone-id-file) ZONE_ID_FILE="$2" shift # past argument shift # past value ;; -d|--dns-record-file) DNS_RECORD_FILE="$2" shift # past argument shift # past value ;; --domain) DOMAIN="$2" shift # past argument shift # past value ;; -*|--*) echo "Unknown option $1" exit 1 ;; *) echo "Unknown option $1" exit 1 ;; esac done DNS_RECORD=$(cat "${DNS_RECORD_FILE}") ZONE_ID=$(cat "${ZONE_ID_FILE}") PUBLIC_IP_FILE=".var/${DOMAIN}_cached_ip" if [ -e "$PUBLIC_IP_FILE" ]; then CACHED_PUBLIC_IP=$(cat "${PUBLIC_IP_FILE}") else touch "${PUBLIC_IP_FILE}" fi check_internet_access check_new_ip curl_answer="$(curl --request PATCH \ --url "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records/${DNS_RECORD}" \ --header 'Content-Type: application/json' \ --header 'X-Auth-Email: ' \ --silent \ --data '{ "content": "'${CACHED_PUBLIC_IP}'", "name": "'${DOMAIN}'", "proxied": false, "type": "A", "comment": "Main Record", "ttl": 3600 }' \ -H "Authorization: Bearer ${AUTHORIZATION}")" info "${curl_answer}" "${SEND_TELEGRAM}" "$(echo ${curl_answer} | jq)"