Created
August 13, 2023 02:57
-
-
Save lucasmaurice/f0594adea625bdf1ed32cbf3886f58f8 to your computer and use it in GitHub Desktop.
This script will get current Public IP, and check if the IP match the Cloudflare record.
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 | |
# REQUIREMENTS: | |
# - curl | |
# - jq | |
# Required environment variables: | |
# CF_TOKEN: ------------ Cloudflare API token | |
# CF_ZONE: ------------- Cloudflare zone ID | |
# CF_ENTRY: ------------ Cloudflare DNS record ID | |
# PO_TOKEN: ------------ Pushover API token | |
# PO_USERKEY: ---------- Pushover user key | |
# List of remotes that return our public IP address | |
PUBLIC_IP_PROVIDERS="ipinfo.io/ip icanhazip.com ifconfig.me/ip ipecho.net/plain checkip.amazonaws.com ifconfig.co/ip" | |
IPS=() | |
# Try each providers and add the IP to the list if it's a valid IP | |
for provider in $PUBLIC_IP_PROVIDERS; do | |
ip=$(curl -s https://$provider) | |
if [[ $ip =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | |
IPS+=($ip) | |
else | |
echo "Invalid IP from $provider: $ip" | |
fi | |
done | |
# Check that there is at least two IPs | |
if [ ${#IPS[@]} -lt 2 ]; then | |
echo "Not enough public IPs found to be sure - will not update DNS" | |
exit 1 | |
fi | |
# Check that all the IPs are the same | |
for (( i=1; i<${#IPS[@]}; i++ )); do | |
if [ "${IPS[$i]}" != "${IPS[0]}" ]; then | |
echo "Public IPs don't match - will not update DNS" | |
exit 1 | |
fi | |
done | |
# Check the current DNS record using the cloudflare API | |
RECORD_IP=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$CF_ZONE/dns_records/$CF_ENTRY" \ | |
-H "Authorization: Bearer $CF_TOKEN" \ | |
-H "Content-Type:application/json" | jq -r .result.content) | |
# If the public IP and the DNS record IP are the same, we don't need to do anything | |
if [ "${IPS[0]}" == "$RECORD_IP" ]; then | |
echo "IPs match - no update required" | |
exit 0 | |
fi | |
# Change the DNS record to the new IP using the cloudflare API | |
CHANGE_RETURN=$(curl -sX PATCH https://api.cloudflare.com/client/v4/zones/$CF_ZONE/dns_records/$CF_ENTRY \ | |
-H "Authorization: Bearer $CF_TOKEN" \ | |
--data "{\"content\": \"${IPS[0]}\"}") | |
echo "Record IP: $RECORD_IP" | |
echo "Public IP: ${IPS[0]}" | |
# Send a notification to Pushover | |
if $(echo $CHANGE_RETURN | jq .success); | |
then | |
echo "DNS updated successfully." | |
curl https://api.pushover.net/1/messages.json \ | |
--form-string "token=$PO_TOKEN" \ | |
--form-string "user=$PO_USERKEY" \ | |
--form-string "title=Home public IP updated!" \ | |
--form-string "priority=-1" \ | |
--form-string "message=Public IP successfully changed from $RECORD_IP to ${IPS[0]}." | |
else | |
echo "Error updating DNS. See below:" | |
echo $CHANGE_RETURN | jq .errors[].message | |
MESSAGE="DNS update failed from $RECORD_IP to ${IPS[0]}. Errors: | |
$(echo $CHANGE_RETURN | jq .errors[].message)" | |
curl https://api.pushover.net/1/messages.json \ | |
--form-string "token=$PO_TOKEN" \ | |
--form-string "user=$PO_USERKEY" \ | |
--form-string "title=Home public IP update failed!" \ | |
--form-string "priority=1" \ | |
--form-string "message=$MESSAGE" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment