fix: harden DynDNS recovery and publish v1.5.1
This commit is contained in:
1 parent
3383b91e49
commit
81def77e3c
37 files changed
+2415
-250
No files matched your search
@@ -25,7 +25,7 @@ Beim ersten Start werden Datenbank und Verschlüsselungsschlüssel automatisch i
|
||||
```yaml
|
||||
services:
|
||||
dyndns:
|
||||
image: &image git.j-mahler.de/admin/domain-control-webinterface-prod:v1.5.0
|
||||
image: &image git.j-mahler.de/admin/domain-control-webinterface-prod:v1.5.1
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 20s
|
||||
ports: ["9090:8080"]
|
||||
@@ -61,7 +61,7 @@ Soll ein anderer Port verwendet werden, muss nur die linke Zahl geändert werden
|
||||
Eine vollständige Schritt-für-Schritt-Anleitung für WebUI, Docker Compose,
|
||||
Portainer/Dockge und Rollbacks steht in [`UPDATE.md`](UPDATE.md).
|
||||
|
||||
Administratoren können im Menü **Update** nach stabilen Releases suchen und eine neue Version direkt installieren. Dabei dürfen auch mehrere Versionen bis hin zu einem kompatiblen Major-Release übersprungen werden. Vor dem Neustart prüft der Agent Versionsgrenze, Agent-Protokoll, Datenbankvertrag, Laufzeitkonfiguration und Healthcheck des Ziel-Images. Gitea-Benutzername und wahlweise Passwort oder Token werden einmalig in der Weboberfläche hinterlegt; das Geheimnis wird mit dem Master-Key verschlüsselt gespeichert und weder an Templates noch an den Browser zurückgegeben.
|
||||
Administratoren können im Menü **Update** nach stabilen Releases suchen und eine neue Version direkt installieren. Dabei dürfen auch mehrere Versionen bis hin zu einem kompatiblen Major-Release übersprungen werden. Vor dem Neustart prüft der Agent Versionsgrenze, Agent-Protokoll, Datenbankvertrag, Laufzeitkonfiguration und Healthcheck des Ziel-Images. Öffentliche Releases und öffentliche Container-Images funktionieren ohne Anmeldung. Für private Repositories oder Images können Gitea-Benutzername und Passwort oder Token einmalig hinterlegt werden; das Geheimnis wird mit dem Master-Key verschlüsselt gespeichert und weder an Templates noch an den Browser zurückgegeben.
|
||||
|
||||
`v1.4.0` ist die sichere Basis für diesen Update-Weg. Eine ältere Installation wird einmalig mit Docker Compose auf `v1.4.0` gebracht; danach kann der Agent auch spätere kompatible Releases direkt installieren. Web-App und Agent dürfen dabei unterschiedliche Versionsnummern haben: Maßgeblich ist das ausdrücklich ausgewiesene Protokoll. Verlangt ein Ziel-Image einen neueren Vertrag, bleibt der laufende Container unverändert und die Oberfläche fordert ein Compose-Update an.
|
||||
|
||||
@@ -94,8 +94,69 @@ Benutzer, Domains und Einstellungen bleiben in `dyndns-data`. Der Schlüssel fü
|
||||
- eine Pi-hole-v6-Verbindung mit verschlüsseltem Anwendungspasswort und geschützter Anzeige nach erneuter Admin-Passwortprüfung
|
||||
- lokale Pi-hole-DNS-Einträge für IPv4 und IPv6 anlegen, aktivieren/deaktivieren, bearbeiten, aus der WebUI trennen, wiederherstellen und vollständig löschen
|
||||
|
||||
Der Container muss die verbundene Pi-hole-Adresse direkt im internen Netz erreichen können. Pi-hole-Sitzungen werden nur für die jeweilige Aktion erstellt und danach aktiv beendet; dauerhaft gespeichert wird ausschließlich das mit dem Master-Key verschlüsselte Anwendungspasswort. Secret- und Datenverzeichnis werden auf `0700`, Master-Key und SQLite-Datei auf `0600` gehärtet. Das Compose-Setup verwendet außerdem ein schreibgeschütztes Root-Dateisystem und ein begrenztes `/tmp`-Tmpfs. HTTPS mit gültigem Zertifikat ist empfohlen.
|
||||
Die Pi-hole-Seite zeigt sofort den gespeicherten Stand. **Records neu einlesen** aktualisiert ihn mit einer begrenzten API-Abfrage. Eine nicht mehr erreichbare Verbindung kann über **Lokale Verbindung entfernen** entfernt werden. Der Container muss die verbundene Pi-hole-Adresse für API-Aktionen direkt im internen Netz erreichen können. Pi-hole-Sitzungen werden nur für die jeweilige Aktion erstellt und danach aktiv beendet; dauerhaft gespeichert wird ausschließlich das mit dem Master-Key verschlüsselte Anwendungspasswort. Secret- und Datenverzeichnis werden auf `0700`, Master-Key und SQLite-Datei auf `0600` gehärtet. Das Compose-Setup verwendet außerdem ein schreibgeschütztes Root-Dateisystem und ein begrenztes `/tmp`-Tmpfs. HTTPS mit gültigem Zertifikat ist empfohlen.
|
||||
|
||||
Damit ein Pi-hole-Anwendungspasswort lokale DNS-Einträge ändern darf, muss am Pi-hole `webserver.api.app_sudo=true` gesetzt sein; Pi-hole verwendet hierfür standardmäßig `false`. Zusätzlich darf der globale Schalter `misc.readOnly` nicht aktiviert sein. Bei einem Pi-hole-Docker-Container entspricht das beispielsweise `FTLCONF_webserver_api_app_sudo: "true"` und `FTLCONF_misc_readOnly: "false"`.
|
||||
|
||||
Port 9090 verwendet zunächst unverschlüsseltes HTTP. Den Port daher nur in einem vertrauenswürdigen Netz freigeben und nicht offen ins Internet stellen.
|
||||
|
||||
## Netzwerkausfälle und Diagnose
|
||||
|
||||
Der Build und die Container-Prüfungen verwenden Go 1.26.9. Damit sind auch
|
||||
die vom Sicherheitscheck gemeldeten HTTP-/Template-Probleme der bisherigen
|
||||
Go-1.25.13-Basis behoben (siehe etwa [GO-2026-6617](https://pkg.go.dev/vuln/GO-2026-6617)).
|
||||
|
||||
Nach fehlgeschlagenen DynDNS-Läufen folgen weitere Versuche nach 5, 10, 20,
|
||||
40 und höchstens 60 Sekunden; nach einem erfolgreichen Lauf gilt wieder das
|
||||
konfigurierte Intervall. Ein IP-Endpunkt hat einschließlich DNS, TLS und
|
||||
Antwort höchstens zehn Sekunden Zeit. IPv4 und IPv6 werden unabhängig und
|
||||
parallel ermittelt. Fehlgeschlagene Abfragen liefern keine alte IP für ein
|
||||
DNS-Update; vorhandene DNS-Records bleiben dann bestehen.
|
||||
|
||||
Hetzner-Änderungen gelten erst dann als erfolgreich, wenn der asynchrone
|
||||
API-Auftrag `success` meldet; `running`, spätere Fehler und Zeitüberschreitungen
|
||||
werden nicht als Erfolg gespeichert. Die Bestätigung wird bis zu 20 Sekunden
|
||||
abgewartet. Ein Fehler beim A-Record verhindert die Aktualisierung des
|
||||
AAAA-Records nicht und umgekehrt; bestätigte Teiländerungen bleiben sichtbar.
|
||||
Siehe den [Hetzner-API-Vertrag für Actions](https://docs.hetzner.cloud/reference/cloud#actions).
|
||||
|
||||
WebUI-Änderungen an DNS-Zielen und automatische Läufe werden vollständig
|
||||
nacheinander ausgeführt, damit ein alter Lauf keine gelöschten Ziele neu
|
||||
anlegt oder feste Adressen überschreibt. Dauert ein laufender Vorgang länger
|
||||
als fünf Sekunden, wird die neue WebUI-Änderung mit einer Meldung zum erneuten
|
||||
Senden abgewiesen. Unveränderte IP-Endpunkte brauchen beim Speichern der
|
||||
Updater-Einstellungen keine erneute DNS-Prüfung. Neue Endpunkte werden weiter
|
||||
geprüft (höchstens acht je IP-Familie).
|
||||
|
||||
Laufhistorie und letzter Status werden gemeinsam gespeichert, auch nach einem
|
||||
kontrollierten Abbruch. Beim Prozessstart werden durch einen Absturz offene
|
||||
Läufe als unterbrochen markiert. Der aktive Updater beginnt automatisch mit
|
||||
einer neuen Prüfung; beim Herunterfahren wird sein Abschluss abgewartet.
|
||||
|
||||
Bei einem vorübergehenden Fehler des System-DNS (Timeout/SERVFAIL) werden
|
||||
**nur** `api.ipify.org`, `api6.ipify.org`, `ifconfig.co` und
|
||||
`api.hetzner.cloud` zusätzlich direkt über Cloudflare und Quad9 aufgelöst
|
||||
(`1.1.1.1`, `9.9.9.9`, `2606:4700:4700::1111`, `2620:fe::fe`, Port 53).
|
||||
System-DNS und die parallelen Ausweichabfragen haben jeweils zwei Sekunden.
|
||||
Jede neue Abfrage beginnt wieder mit System-DNS. Negative DNS-Antworten
|
||||
(NXDOMAIN), eigene Endpunkte und lokale Pi-hole-Namen erhalten keinen solchen
|
||||
Ausweichweg. HTTPS-Zertifikate und öffentliche IP-Endpunkte werden weiterhin
|
||||
geprüft. Dieser Mechanismus ersetzt keine funktionierende Route oder
|
||||
Firewall-Freigabe auf dem Produktionsserver.
|
||||
|
||||
Unter **Fehler → Diagnose-Logs herunterladen** können Administratoren einen
|
||||
JSON-Bericht exportieren. Er enthält Version, letzte Laufstatus, IP-Abfragen,
|
||||
DNS-Ausweichversuche, Fehlertypen, Wartezeiten, Wiederherstellung und
|
||||
DNS-/IPv4-Routing-Daten. Die Ereignisse werden im bestehenden Daten-Volume in
|
||||
zwei Dateien zu höchstens je 4 MiB mit Dateirechten `0600` gespeichert und
|
||||
überleben Container-Neustarts. Bei langen Ausfällen wird der Netzwerkzustand
|
||||
beim ersten Fehler und anschließend alle 15 Minuten festgehalten.
|
||||
|
||||
Der Export enthält ausschließlich festgelegte technische Felder. Rohmeldungen,
|
||||
Audit-Texte, Zugangsdaten, Cookies, Sitzungs-IDs, HTTP-Header, URL-Pfade und
|
||||
Query-Parameter werden nicht übernommen. IP-Adressen und Netzwerkrouten sind
|
||||
zur Diagnose enthalten. Die Aufzeichnung beginnt mit dieser Funktion; alte
|
||||
Läufe sind nur mit Zeit und Status enthalten. Der lokale Healthcheck bestätigt
|
||||
die Erreichbarkeit der Web-App, nicht die Erreichbarkeit von Internet/Hetzner.
|
||||
Bei `no_route` müssen auf Prod Gateway, Docker-Bridge, Forwarding/NAT und
|
||||
Firewall geprüft werden; ein Container-Neustart allein belegt keine Behebung.
|
||||
Reference in new issue
Block a user