Ein flexibler Hub-Service für Dynamic DNS Updates, der Anfragen von Routern (z.B. FritzBox) entgegennimmt und an verschiedene DNS-Provider weiterleitet. https://git.irohlf.de/iRohlf/ddns-hub
Find a file
2026-09-06 21:22:33 +02:00
config feat: Provider-Statistik (Erfolgsquote + DNS-Erreichbarkeit) 2026-09-06 14:14:54 +02:00
docs docs(security): document container CVE impact 2026-09-06 21:22:19 +02:00
logos release: v2.5.3 – Statistik-Charts, Demo-Daten, Doku 2026-09-06 20:15:50 +02:00
plans release: v2.5.3 – Statistik-Charts, Demo-Daten, Doku 2026-09-06 20:15:50 +02:00
providers fix(dns-checker): compare against effective provider IPs (v2.5.3) 2026-09-06 19:19:52 +02:00
scripts release: v2.5.3 – Statistik-Charts, Demo-Daten, Doku 2026-09-06 20:15:50 +02:00
templates fix(dns-checker): compare against effective provider IPs (v2.5.3) 2026-09-06 19:19:52 +02:00
tests fix(dns-checker): compare against effective provider IPs (v2.5.3) 2026-09-06 19:19:52 +02:00
web release: v2.5.3 – Statistik-Charts, Demo-Daten, Doku 2026-09-06 20:15:50 +02:00
.dockerignore Support für mehrere RFC2136 Endpunkte 2026-01-05 22:44:55 +01:00
.gitignore release: v2.5.3 – Statistik-Charts, Demo-Daten, Doku 2026-09-06 20:15:50 +02:00
auth.py WebUI: Passwort-Reset über ADMIN_INITIAL_PASSWD und /set-password 2026-09-06 01:39:52 +02:00
build.sh build und deploy skripte 2026-09-06 02:15:22 +02:00
config.py feat: Provider-Statistik (Erfolgsquote + DNS-Erreichbarkeit) 2026-09-06 14:14:54 +02:00
ddns-hub.py feat: Provider-Statistik (Erfolgsquote + DNS-Erreichbarkeit) 2026-09-06 14:14:54 +02:00
deploy.sh build und deploy skripte 2026-09-06 02:15:22 +02:00
dispatcher.py fix(dns-checker): compare against effective provider IPs (v2.5.3) 2026-09-06 19:19:52 +02:00
dns_checker.py fix(dns-checker): compare against effective provider IPs (v2.5.3) 2026-09-06 19:19:52 +02:00
docker-compose.yaml WebUI: Passwort-Reset über ADMIN_INITIAL_PASSWD und /set-password 2026-09-06 01:39:52 +02:00
docker-entrypoint.sh fix(dns-checker): compare against effective provider IPs (v2.5.3) 2026-09-06 19:19:52 +02:00
Dockerfile fix(dns-checker): compare against effective provider IPs (v2.5.3) 2026-09-06 19:19:52 +02:00
install.sh v3.0.0: WebUI für Status-Anzeige und Provider-Verwaltung 2026-09-05 02:42:46 +02:00
LICENSE.md - License.md hinzugefügt 2026-01-06 09:14:10 +01:00
LICENSE.pdf - License.md hinzugefügt 2026-01-06 09:14:10 +01:00
README.md release: v2.5.3 – Statistik-Charts, Demo-Daten, Doku 2026-09-06 20:15:50 +02:00
README.pdf - License.md hinzugefügt 2026-01-06 09:14:10 +01:00
requirements.txt v3.0.0: WebUI für Status-Anzeige und Provider-Verwaltung 2026-09-05 02:42:46 +02:00
state.py fix(dns-checker): compare against effective provider IPs (v2.5.3) 2026-09-06 19:19:52 +02:00
stats.py feat: Provider-Statistik (Erfolgsquote + DNS-Erreichbarkeit) 2026-09-06 14:14:54 +02:00
VERSION fix(dns-checker): compare against effective provider IPs (v2.5.3) 2026-09-06 19:19:52 +02:00

DDNS Hub

Ein Multi-Provider Dynamic DNS Update Service für die Verwendung mit FritzBox und anderen DynDNS-Clients.

Features

  • Multi-Provider Support Sendet Updates gleichzeitig an mehrere DNS-Dienste
  • HTTP-basierte Provider DuckDNS, dynv6, No-IP, Cloudflare und beliebige andere
  • RFC 2136 Support Native DNS-Updates mit TSIG-Authentifizierung (Technitium, BIND, PowerDNS, etc.)
  • Multi-Router Support Verschiedene Provider für verschiedene Internetverbindungen (z.B. Glasfaser + DSL)
  • IPv6 Präfix-Handling Berechnet Server-IPv6 aus LAN-Präfix + statischem Host-Teil
  • WebUI Status-Dashboard und vollständige Provider-Verwaltung im Browser
  • Provider-Statistik Erfolgsquote und DNS-Erreichbarkeit über die Zeit (24h/7d/30d/90d) mit Charts
  • Docker-ready Einfaches Deployment mit Docker Compose
  • FritzBox-kompatibel Funktioniert als Custom DynDNS-Ziel

Quickstart (Docker)

# Repository klonen oder Archiv entpacken
cd ddns-hub

# Config-Verzeichnis erstellen
mkdir -p config

# Beispiel-Konfiguration kopieren und anpassen
cp templates/ddns-hub.conf.docker config/ddns-hub.conf
nano config/ddns-hub.conf

# Container starten
docker compose up -d

FritzBox einrichten

In der FritzBox unter Internet → Freigaben → DynDNS:

Feld Wert
DynDNS-Anbieter Benutzerdefiniert
Update-URL http://<server>:3080/update?domains=<domain>&ip=<ipaddr>&ipv6prefix=<ip6lanprefix>
Domainname home (oder beliebig)
Benutzername (leer lassen)
Kennwort (leer lassen)

Wichtig: ipv6prefix=<ip6lanprefix> ist nötig für Server hinter der FritzBox. Siehe FritzBox-Doku.

WebUI

Die WebUI läuft auf demselben Port wie der Update-Service und bietet:

  • Dashboard Status aller Provider (OK/Fehler/kein Update), letzte bekannte IPs, letzte Aktivitäten, Erfolgsquote (24h) und DNS-Status
  • Provider-Verwaltung Provider anlegen, bearbeiten, löschen, aktivieren/deaktivieren
  • Update now Führt sofort ein Update für einen einzelnen Provider aus
  • Statistik Erfolgsquote und DNS-Erreichbarkeit pro Provider als Charts (Zeitfenster 24h/7d/30d/90d)
  • Einstellungen General-, IPv6-, WebUI-, Statistik- und DNS-Optionen
  • Konfiguration Export/Import der INI-Konfiguration
  • Aktivitäts-Log Die letzten Update-Ereignisse

Zugriff: http://<server>:<port>/

WebUI-Sicherheit

Die WebUI kann mit Benutzername/Passwort abgesichert werden. Lege in der Konfiguration eine [Web]-Sektion an:

[Web]
enabled = true
username = admin
password_hash = <scrypt-Hash>
session_secret = <beliebiger-Wert>

Den Passwort-Hash generierst du mit:

python3 -c "from werkzeug.security import generate_password_hash; print(generate_password_hash('geheim'))"

Ist password_hash leer, ist die WebUI gesperrt (kein Zugriff). Der /update-Endpoint bleibt immer ohne Authentifizierung erreichbar, damit die FritzBox Updates senden kann.

Passwort setzen / vergessen?

Starte den Service mit der Umgebungsvariable ADMIN_INITIAL_PASSWD:

ADMIN_INITIAL_PASSWD=<initial> ddns-hub

Die WebUI ist dann nur über /set-password erreichbar, wo ein neues Passwort gesetzt werden kann (Bestätigung über das Initial-Passwort erforderlich). Sobald ein password_hash gesetzt ist, ist ADMIN_INITIAL_PASSWD ungültig.

Provider-Statistik

DDNS Hub zeichnet alle Update-Versuche und DNS-Checks in einer SQLite-Datenbank auf (90 Tage Historie, automatisches Aufräumen) und wertet sie in der WebUI aus:

  • Erfolgsquote Anteil erfolgreicher Update-Versuche pro Provider
  • DNS-Erreichbarkeit regelmäßiger NS-Lookup (A/AAAA) der Provider-Domain gegen öffentliche DNS-Server; "erreichbar" heißt: Domain löst sich auf und liefert die zuletzt bekannte IP (mit Stabilitätsfenster gegen False Positives bei IP-Wechsel)

In der WebUI:

  • Dashboard Erfolgsquote (24h) und DNS-Status (ok/fail/pending) pro Provider
  • Statistik Charts pro Provider mit Zeitfenster-Auswahl (24h/7d/30d/90d)

Konfiguration:

[Stats]
enabled = true
db_path = /config/stats.db
retention_days = 90

[DNS]
enabled = true
servers = 8.8.8.8, 208.67.222.222
interval = 900
stability_seconds = 600

Details in der Konfigurations-Doku.

Dokumentation

Beispiel-Konfiguration

[General]
port = 8080
debug = false

[IPv6]
static_host_part = ac4e:3cff:fef0:21ef

[DynDNS:duckdns]
enabled = true
domain = meinname.duckdns.org
token = abc123-xxxx-xxxx
update_url = https://www.duckdns.org/update?domains={domain}&token={token}&ip={ipv4}&ipv6={ipv6}

[RFC2136:technitium]
enabled = true
server = ns1.example.com
zone = ddns.example.com
key_name = ddns-hub
key_secret = BASE64SECRET==
key_algorithm = hmac-sha256
ttl = 300
domains = home, nas, server

Multi-Router Setup

Bei mehreren Internetverbindungen (z.B. Glasfaser + DSL Backup):

[RFC2136:glasfaser]
enabled = true
server = ns1.example.com
zone = ddns.example.com
domains = home, nas
connection = glasfaser

[RFC2136:dsl]
enabled = true
server = ns1.example.com
zone = ddns.example.com
domains = home-backup
connection = dsl

FritzBox-URLs:

  • FB1: http://server:3080/update?connection=glasfaser&ip=<ipaddr>&ipv6prefix=<ip6lanprefix>
  • FB2: http://server:3080/update?connection=dsl&ip=<ipaddr>&ipv6prefix=<ip6lanprefix>

Changelog

v2.5.3

  • Fix (DNS-Checker): Vergleich der aufgelösten Records gegen die effektiven Provider-IPs (inkl. ipv6_static-Transformation) statt der rohen Request-IPs Provider mit statischem IPv6-Host-Teil wurden zuvor fälschlich als "IP mismatch" gemeldet
  • Fix (Docker): stats.py und dns_checker.py werden jetzt in das Image kopiert
  • WebUI (Statistik): Chart.js-Initialisierung zentral im Template; Charts werden zuverlässig für alle aktiven Provider mit Daten gerendert
  • Demo: scripts/seed_demo_stats.py befüllt die Statistik-DB mit 90 Tagen realistischen Demo-Daten (drei Demo-Provider)

v2.5.1

  • Provider-Statistik: Erfolgsquote und DNS-Erreichbarkeit über die Zeit (SQLite-Persistenz, 90 Tage), neue WebUI-Seite "Statistik" mit Charts, Dashboard-Spalten, DNS-Checker als Hintergrund-Thread, [Stats]/[DNS]-Sektionen

Lizenz

MIT License