From c323d0f91e3c0ce03f56d2e1469eff02ef007d3d Mon Sep 17 00:00:00 2001 From: James Date: Mon, 23 Feb 2026 16:57:30 -0500 Subject: [PATCH] =?UTF-8?q?feat:=20DDNS=20updater=20=E2=80=94=20keeps=20jo?= =?UTF-8?q?ngsma.me=20A=20record=20current=20in=20Cloudflare?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/ddns-update.sh | 50 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100755 scripts/ddns-update.sh diff --git a/scripts/ddns-update.sh b/scripts/ddns-update.sh new file mode 100755 index 0000000..28aecd2 --- /dev/null +++ b/scripts/ddns-update.sh @@ -0,0 +1,50 @@ +#!/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