| config | ||
| docs | ||
| logos | ||
| plans | ||
| providers | ||
| scripts | ||
| templates | ||
| tests | ||
| web | ||
| .dockerignore | ||
| .gitignore | ||
| auth.py | ||
| build.sh | ||
| config.py | ||
| ddns-hub.py | ||
| deploy.sh | ||
| dispatcher.py | ||
| dns_checker.py | ||
| docker-compose.yaml | ||
| docker-entrypoint.sh | ||
| Dockerfile | ||
| install.sh | ||
| LICENSE.md | ||
| LICENSE.pdf | ||
| README.md | ||
| README.pdf | ||
| requirements.txt | ||
| state.py | ||
| stats.py | ||
| VERSION | ||
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
- Installation – Docker und native Installation
- Konfiguration – Alle Optionen im Detail
- Provider – DynDNS und RFC 2136 Provider
- FritzBox – FritzBox-Integration
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.pyunddns_checker.pywerden 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.pybefü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