Created
March 31, 2025 06:22
-
-
Save ripsnortntear/bae00a0058e18ec09aaf99b175e11e6f to your computer and use it in GitHub Desktop.
This script retrieves the current public IP address and updates the corresponding A records in Cloudflare DNS if they differ, using the Cloudflare API and the jq tool for JSON processing.
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 | |
# Access the environment variables | |
api_token="CLOUDFLARE_API_TOKEN" | |
zone_name="FQDN" | |
# Function to get the current public IP address | |
get_public_ip() { | |
curl -s -X GET https://ifconfig.co | |
} | |
# Function to get the zone ID | |
get_zone_id() { | |
local response | |
response=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$zone_name" \ | |
-H "Authorization: Bearer $api_token" \ | |
-H "Content-Type: application/json") | |
if [[ $(echo "$response" | jq -r '.success') == "false" ]]; then | |
echo "Error retrieving zone ID: $(echo "$response" | jq -r '.errors')" | |
exit 1 | |
fi | |
echo "$response" | jq -r '.result[0].id' | |
} | |
# Function to fetch all A records | |
get_a_records() { | |
local zone_id="$1" | |
local response | |
response=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records?type=A" \ | |
-H "Authorization: Bearer $api_token" \ | |
-H "Content-Type: application/json") | |
if [[ $(echo "$response" | jq -r '.success') == "false" ]]; then | |
echo "Error fetching A records: $(echo "$response" | jq -r '.errors')" | |
exit 1 | |
fi | |
echo "$response" | jq -c '.result[]' | |
} | |
# Function to install jq | |
install_jq() { | |
if command -v apt &> /dev/null; then | |
echo "Installing jq using apt..." | |
sudo apt update && sudo apt install -y jq | |
elif command -v dnf &> /dev/null; then | |
echo "Installing jq using dnf..." | |
sudo dnf install -y jq | |
elif command -v yum &> /dev/null; then | |
echo "Installing jq using yum..." | |
sudo yum install -y jq | |
elif command -v apk &> /dev/null; then | |
echo "Installing jq using apk..." | |
sudo apk add jq | |
elif command -v pacman &> /dev/null; then | |
echo "Installing jq using pacman..." | |
sudo pacman -Sy --noconfirm jq | |
elif command -v brew &> /dev/null; then | |
echo "Installing jq using Homebrew..." | |
brew install jq | |
else | |
echo "Error: Could not detect package manager!" | |
return 1 | |
fi | |
} | |
# Check for jq installation | |
if ! command -v jq &> /dev/null; then | |
echo "jq is not installed. Attempting to install..." | |
install_jq | |
# Verify installation | |
if ! command -v jq &> /dev/null; then | |
echo "Failed to install jq. Please install it manually." | |
exit 1 | |
fi | |
echo "jq has been successfully installed." | |
else | |
echo "jq is already installed." | |
fi | |
# Main script logic | |
ipv4=$(get_public_ip) | |
if [ -z "$ipv4" ]; then | |
echo "Unable to retrieve public IP address." | |
exit 1 | |
fi | |
echo "Current public IP: $ipv4" | |
zone_id=$(get_zone_id) | |
if [ -z "$zone_id" ]; then | |
echo "Zone ID is null. Please check the zone name and API token permissions." | |
exit 1 | |
fi | |
# Fetch all A records | |
records=$(get_a_records "$zone_id") | |
# Loop through each record and update if necessary | |
while IFS= read -r record; do | |
name=$(echo "$record" | jq -r '.name') | |
record_id=$(echo "$record" | jq -r '.id') | |
current_ip=$(echo "$record" | jq -r '.content') | |
proxied=$(echo "$record" | jq -r '.proxied') | |
ttl=$(echo "$record" | jq -r '.ttl // 1') | |
if [ "$current_ip" != "$ipv4" ]; then | |
echo "Updating $name from $current_ip to $ipv4..." | |
update_response=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zone_id/dns_records/$record_i> -H "Authorization: Bearer $api_token" \ | |
-H "Content-Type: application/json" \ | |
--data "{\"type\":\"A\",\"name\":\"$name\",\"content\":\"$ipv4\",\"ttl\":$ttl,\"proxied\":$proxied}") | |
if [[ $(echo "$update_response" | jq -r '.success') == "true" ]]; then | |
echo "✓ Successfully updated $name ($current_ip -> $ipv4)" | |
else | |
echo "✗ Failed to update $name: $(echo "$update_response" | jq -r '.errors')" | |
fi | |
else | |
echo "✓ $name is up to date ($current_ip)" | |
fi | |
done <<< "$records" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment