clawd/scripts/ddns-update.sh

51 lines
1.6 KiB
Bash
Executable File

#!/bin/bash
# DDNS updater — keeps jongsma.me A record current in Cloudflare
# Runs every 5 min via cron; only calls CF API when IP has changed
ZONE_ID="60b98ddacd2a61df9ac36b39acfe8b2c"
RECORD_NAME="jongsma.me"
STATE_FILE="/tmp/ddns-last-ip"
source /home/johan/.config/cloudflare.env
# Get current public IP
CURRENT_IP=$(curl -sf --max-time 5 https://api.ipify.org || curl -sf --max-time 5 https://ifconfig.me)
if [ -z "$CURRENT_IP" ]; then
echo "$(date -u): Failed to get public IP" >&2
exit 1
fi
# Compare to last known
LAST_IP=$(cat "$STATE_FILE" 2>/dev/null)
if [ "$CURRENT_IP" = "$LAST_IP" ]; then
exit 0
fi
echo "$(date -u): IP changed: $LAST_IP -> $CURRENT_IP"
# Get record ID
RECORD_ID=$(curl -sf \
"https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?type=A&name=$RECORD_NAME" \
-H "Authorization: Bearer $CF_API_TOKEN" | \
python3 -c "import sys,json; r=json.load(sys.stdin)['result']; print(r[0]['id'] if r else '')")
if [ -z "$RECORD_ID" ]; then
echo "$(date -u): Record not found for $RECORD_NAME" >&2
exit 1
fi
# Update record
RESULT=$(curl -sf -X PUT \
"https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
-H "Authorization: Bearer $CF_API_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"type\":\"A\",\"name\":\"$RECORD_NAME\",\"content\":\"$CURRENT_IP\",\"ttl\":1,\"proxied\":false}")
if echo "$RESULT" | python3 -c "import sys,json; sys.exit(0 if json.load(sys.stdin).get('success') else 1)"; then
echo "$(date -u): Updated $RECORD_NAME -> $CURRENT_IP"
echo "$CURRENT_IP" > "$STATE_FILE"
else
echo "$(date -u): CF API error: $RESULT" >&2
exit 1
fi