Skip to content

Instantly share code, notes, and snippets.

@syncip
Last active March 21, 2026 16:31
Show Gist options
  • Select an option

  • Save syncip/75289540aad4afa2f6fe27d1d3366acd to your computer and use it in GitHub Desktop.

Select an option

Save syncip/75289540aad4afa2f6fe27d1d3366acd to your computer and use it in GitHub Desktop.
IPv64 DynDNS Updater (Bash): prüft IPv4/IPv6 via icanhazip, vergleicht mit DNS und updated nur bei Änderung. Optional ntfy-Benachrichtigungen. Keine State-Dateien nötig, ideal für dynamische IPs.
#!/usr/bin/env bash
set -u
########################################
# Konfiguration
########################################
# IPv64
ENABLE_IPV64=true
IPV64_DOMAIN="XXX.ipv64.net"
IPV64_TOKEN="XXXXXXXXXXXXXXXXXXXXXXXXXXXX"
IPV64_UPDATE_URL="https://ipv64.net/nic/update"
# IPv4
ENABLE_IPV4=true
IPV4_CHECK_URL="https://ipv4.icanhazip.com"
# IPv6
ENABLE_IPV6=false
IPV6_CHECK_URL="https://ipv6.icanhazip.com"
# IPv64 autoritativer DNS
ENABLE_DNS_CHECK=true
DNS_SERVER_V4="ns1.ipv64.net"
DNS_SERVER_V6="ns1.ipv64.net"
# ntfy
ENABLE_NTFY=true
NTFY_URL="https://ntfy.sh/dein-topic"
NTFY_TITLE_PREFIX="IPv64 DDNS"
# Sonstiges
CURL_TIMEOUT=15
DIG_TIMEOUT=5
########################################
# Funktionen
########################################
log() {
printf '%s %s\n' "$(date '+%F %T')" "$*"
}
send_ntfy() {
local title="$1"
local message="$2"
local priority="${3:-default}"
[ "$ENABLE_NTFY" = true ] || return 0
curl -fsS \
-H "Title: ${NTFY_TITLE_PREFIX} - ${title}" \
-H "Priority: ${priority}" \
-d "$message" \
"$NTFY_URL" >/dev/null 2>&1 || true
}
fetch_ipv4() {
curl -4 -fsS --max-time "$CURL_TIMEOUT" "$IPV4_CHECK_URL" | tr -d '[:space:]'
}
fetch_ipv6() {
curl -6 -fsS --max-time "$CURL_TIMEOUT" "$IPV6_CHECK_URL" | tr -d '[:space:]'
}
fetch_dns_ipv4() {
dig @"$DNS_SERVER_V4" +short A "$IPV64_DOMAIN" +time="$DIG_TIMEOUT" +tries=1 | head -n1 | tr -d '[:space:]'
}
fetch_dns_ipv6() {
dig @"$DNS_SERVER_V6" +short AAAA "$IPV64_DOMAIN" +time="$DIG_TIMEOUT" +tries=1 | head -n1 | tr -d '[:space:]'
}
update_ipv64() {
local ipv4="$1"
local ipv6="$2"
local url="${IPV64_UPDATE_URL}?key=${IPV64_TOKEN}&domain=${IPV64_DOMAIN}"
if [ "$ENABLE_IPV4" = true ] && [ -n "$ipv4" ]; then
url="${url}&ip=${ipv4}"
fi
if [ "$ENABLE_IPV6" = true ] && [ -n "$ipv6" ]; then
url="${url}&ip6=${ipv6}"
fi
curl --retry 5 --retry-delay 3 --retry-all-errors -fsS --max-time "$CURL_TIMEOUT" "$url"
}
########################################
# Start
########################################
if [ "$ENABLE_IPV64" != true ]; then
log "IPv64 deaktiviert."
exit 0
fi
if [ "$ENABLE_IPV4" != true ] && [ "$ENABLE_IPV6" != true ]; then
log "Weder IPv4 noch IPv6 aktiviert."
exit 0
fi
CURRENT_IPV4=""
CURRENT_IPV6=""
DNS_IPV4=""
DNS_IPV6=""
NEED_UPDATE=false
CHANGED_IPV4=false
CHANGED_IPV6=false
# IPv4
if [ "$ENABLE_IPV4" = true ]; then
if ! CURRENT_IPV4="$(fetch_ipv4)"; then
log "Fehler beim Abrufen der aktuellen IPv4."
send_ntfy "Fehler" "Fehler beim Abrufen der aktuellen IPv4 über ${IPV4_CHECK_URL}" urgent
exit 1
fi
if [ "$ENABLE_DNS_CHECK" = true ]; then
if ! DNS_IPV4="$(fetch_dns_ipv4)"; then
log "Fehler beim DNS-Check der IPv4 bei IPv64."
send_ntfy "Fehler" "Fehler beim DNS-Check der IPv4 für ${IPV64_DOMAIN}" urgent
exit 1
fi
if [ "$CURRENT_IPV4" != "$DNS_IPV4" ]; then
NEED_UPDATE=true
CHANGED_IPV4=true
fi
else
NEED_UPDATE=true
CHANGED_IPV4=true
fi
fi
# IPv6
if [ "$ENABLE_IPV6" = true ]; then
if ! CURRENT_IPV6="$(fetch_ipv6)"; then
log "Fehler beim Abrufen der aktuellen IPv6."
send_ntfy "Fehler" "Fehler beim Abrufen der aktuellen IPv6 über ${IPV6_CHECK_URL}" urgent
exit 1
fi
if [ "$ENABLE_DNS_CHECK" = true ]; then
if ! DNS_IPV6="$(fetch_dns_ipv6)"; then
log "Fehler beim DNS-Check der IPv6 bei IPv64."
send_ntfy "Fehler" "Fehler beim DNS-Check der IPv6 für ${IPV64_DOMAIN}" urgent
exit 1
fi
if [ "$CURRENT_IPV6" != "$DNS_IPV6" ]; then
NEED_UPDATE=true
CHANGED_IPV6=true
fi
else
NEED_UPDATE=true
CHANGED_IPV6=true
fi
fi
if [ "$NEED_UPDATE" != true ]; then
log "Kein Update nötig."
exit 0
fi
if RESPONSE="$(update_ipv64 "$CURRENT_IPV4" "$CURRENT_IPV6" 2>&1)"; then
MSG="IPv64 Update erfolgreich
Domain: $IPV64_DOMAIN"
if [ "$CHANGED_IPV4" = true ]; then
MSG="${MSG}
IPv4: ${DNS_IPV4:-leer} -> ${CURRENT_IPV4}"
fi
if [ "$CHANGED_IPV6" = true ]; then
MSG="${MSG}
IPv6: ${DNS_IPV6:-leer} -> ${CURRENT_IPV6}"
fi
log "$MSG"
send_ntfy "Update" "$MSG" default
else
log "IPv64 Update fehlgeschlagen: $RESPONSE"
send_ntfy "Fehler" "IPv64 Update fehlgeschlagen:
$RESPONSE" urgent
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment