From 737c5c8d8afac5244ca4178a94a0cf07cf2868a7 Mon Sep 17 00:00:00 2001 From: Syed Daanish Date: Wed, 8 Jul 2026 19:27:55 +0100 Subject: [PATCH] Add IPv6 to ddns --- modules/cloudflare-ddns/ddns.sh | 74 +++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 23 deletions(-) diff --git a/modules/cloudflare-ddns/ddns.sh b/modules/cloudflare-ddns/ddns.sh index b902d1c..3b40bb8 100644 --- a/modules/cloudflare-ddns/ddns.sh +++ b/modules/cloudflare-ddns/ddns.sh @@ -2,32 +2,60 @@ source /run/secrets.env -cache=/var/lib/cloudflare-ddns/old_ip -IP=$(@curl@/bin/curl -s 'https://api.ipify.org') +# Separate caches for IPv4 and IPv6 +cache_v4=/var/lib/cloudflare-ddns/old_ip_v4 +cache_v6=/var/lib/cloudflare-ddns/old_ip_v6 + +# Fetch current IPs +IP_V4=$(@curl@/bin/curl -4 -s 'https://api.ipify.org') +IP_V6=$(@curl@/bin/curl -6 -s 'https://api6.ipify.org') + arr=("" "git." "www." "acs.") -if [[ -f "$cache" ]]; then - old_ip=$(cat "$cache") -else - old_ip="" -fi - -if [[ "$IP" != "$old_ip" ]]; then - for sub in "${arr[@]}"; do - RECORD_ID=$(@curl@/bin/curl -s -X GET \ - "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \ - -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ - -H "Content-Type: application/json" \ - | @jq@/bin/jq -r ".result[] | select(.name==\"${sub}syedm.dev\" and .type==\"A\") | .id") - - if [ -n "$RECORD_ID" ]; then - @curl@/bin/curl -s -X PUT \ - "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \ +if [[ -n "$IP_V4" ]]; then + old_ip_v4=$([[ -f "$cache_v4" ]] && cat "$cache_v4" || echo "") + + if [[ "$IP_V4" != "$old_ip_v4" ]]; then + for sub in "${arr[@]}"; do + RECORD_ID=$(@curl@/bin/curl -s -X GET \ + "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \ -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ -H "Content-Type: application/json" \ - -d "{\"type\":\"A\",\"name\":\"${sub}syedm.dev\",\"content\":\"$IP\",\"ttl\":3600,\"proxied\":false}" - fi - done - echo "$IP" > "$cache" + | @jq@/bin/jq -r ".result[] | select(.name==\"${sub}syedm.dev\" and .type==\"A\") | .id") + + if [ -n "$RECORD_ID" ]; then + @curl@/bin/curl -s -X PUT \ + "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \ + -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ + -H "Content-Type: application/json" \ + -d "{\"type\":\"A\",\"name\":\"${sub}syedm.dev\",\"content\":\"$IP_V4\",\"ttl\":3600,\"proxied\":false}" + fi + done + echo "$IP_V4" > "$cache_v4" + fi +fi + +if [[ -n "$IP_V6" ]]; then + old_ip_v6=$([[ -f "$cache_v6" ]] && cat "$cache_v6" || echo "") + + if [[ "$IP_V6" != "$old_ip_v6" ]]; then + for sub in "${arr[@]}"; do + RECORD_ID=$(@curl@/bin/curl -s -X GET \ + "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \ + -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ + -H "Content-Type: application/json" \ + + | @jq@/bin/jq -r ".result[] | select(.name==\"${sub}syedm.dev\" and .type==\"AAAA\") | .id") + + if [ -n "$RECORD_ID" ]; then + @curl@/bin/curl -s -X PUT \ + "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \ + -H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ + -H "Content-Type: application/json" \ + -d "{\"type\":\"AAAA\",\"name\":\"${sub}syedm.dev\",\"content\":\"$IP_V6\",\"ttl\":3600,\"proxied\":false}" + fi + done + echo "$IP_V6" > "$cache_v6" + fi fi