Watchdog: Sicherheit und Datenschutz
Zugang, Agenten-Tokens, gespeicherte Zugangsdaten, nötige Berechtigungen (Docker-Socket, pid host, Host-Mount), Sicherheits-Header sowie gespeicherte Daten und Datenfluss von Watchdog.
Watchdog: Sicherheit und Datenschutz
Zugang zur Oberfläche
| Thema | Verhalten |
|---|---|
| Verfahren | HTTP Basic Auth mit Realm Watchdog |
| Benutzer | Genau ein Admin-Benutzer aus APP_ADMIN_USER und APP_ADMIN_PASSWORD_HASH. Es gibt keine Benutzerverwaltung und keine Rollen |
| Geltungsbereich | Alle Seiten, auch Impressum und Datenschutz. Ausnahmen: /api/ mit eigener Token-Authentifizierung sowie im Entwicklungsmodus (APP_ENV=dev) die Pfade /_profiler, /_wdt, /assets und /build |
| Passwort-Speicherung | Bcrypt-Hash in der Env-Datei, nicht in der Datenbank |
| Schutz vor Raten | Watchdog begrenzt Anmeldeversuche nicht. Lege bei Bedarf eine Begrenzung im Reverse Proxy fest |
Basic Auth überträgt Benutzername und Passwort bei jeder Anfrage. Betreibe Watchdog nur hinter HTTPS. Der Header
Strict-Transport-Securitywird nur bei gesicherten Anfragen gesetzt.
Auf Stage und im lokalen Stack läuft die App mit
APP_ENV=dev. Dort sind der Symfony-Profiler und die Debug-Toolbar (/_profiler,/_wdt) ohne Anmeldung erreichbar, weil die Firewall diese Pfade von der Authentifizierung ausnimmt. Sie zeigen Requests, Konfiguration und Umgebungswerte. Nur der Live-Stack (APP_ENV=prod) schützt wirklich alle Seiten. Stelle Stage und lokale Instanzen deshalb nicht ungeschützt ins Netz.
Agenten-Tokens
- Ein Token besteht aus 64 Hex-Zeichen (32 Zufallsbytes) und wird nur einmal angezeigt.
- In der Datenbank liegt nur der SHA-256-Hash. Der Vergleich nutzt
hash_equals. - Jede Anfrage trägt das Token als
Authorization: Bearer .... - Mit Regenerate Token machst Du das alte Token sofort ungültig.
- Pro IP sind 60 Anfragen pro Minute auf
/api/erlaubt, danach antwortet Watchdog mit429. - Ein Agent kann nur Ergebnisse für Checks melden, die ihm zugewiesen sind. Pro Anfrage nimmt Watchdog höchstens 500 Ergebnisse an. Zeitstempel müssen zwischen 5 Minuten in der Vergangenheit und 1 Minute in der Zukunft liegen, sonst gilt die Serverzeit.
Der Agent bekommt über /api/v1/agent/config die vollständige Konfiguration seiner Checks, einschließlich gespeicherter Passwörter von Datenbank-Checks. Schütze das Token wie ein Passwort.
Gespeicherte Zugangsdaten
| Daten | Ort | Form |
|---|---|---|
| Admin-Passwort | Env-Datei | Bcrypt-Hash |
| BasicAuth-Zugangsdaten überwachter URLs | Tabelle client_urls |
Klartext |
| Datenbank-Passwort eines Datenbank-Checks | Tabelle site_checks, Spalte config |
Klartext |
| Agenten-Token | Tabelle agents |
SHA-256-Hash |
| SMTP-Zugang | MAILER_DSN in der Env-Datei |
Klartext |
Lege für Datenbank-Checks einen eigenen Benutzer mit minimalen Rechten an. Sichere und schütze die Datenbank-Datei var/data.db entsprechend.
Berechtigungen der Container
| Container | Läuft als | Zugriff |
|---|---|---|
app |
www-data (UID 82) bei Stage und Live |
eigenes Datenvolume |
worker, scheduler |
Standardbenutzer des Images (kein user: gesetzt) |
Datenvolume und Docker-Socket (nur lesend eingebunden, die Docker-API lässt sich damit dennoch nutzen) |
agent |
www-data |
Host-Dateisystem lesend unter /host/root, pid: host, optional Docker-Socket |
Daraus folgt:
- Der Docker-Socket ermöglicht Docker-Checks, bedeutet aber weitreichende Rechte auf dem Host. Der Check Docker Exec führt außerdem frei konfigurierbare Befehle in Containern aus.
pid: hostund der Mount von/machen jeden Container-Ausbruch aus dem Agenten gefährlicher. Entferne beides, wenn Du die zugehörigen Checks nicht nutzt.- In
compose.stage.ymlundcompose.live.ymlbekommt auch der Agent-Container die vollständige Env-Datei (env_file), also auch Admin-Hash,APP_SECRETundMAILER_DSN. Für Remote-Agenten überdocker-compose.agent.ymlgilt das nicht, dort stehen nur die zwei Agenten-Variablen. - Der lokale Stack
compose.ymlveröffentlicht App und Mailpit auf allen Netzwerk-Schnittstellen (8087,8128). Nutze ihn nur auf einem Entwicklungsrechner.
HTTP-Header und Browser-Schutz
Jede Antwort enthält X-Frame-Options: DENY, X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, eine Permissions-Policy ohne Kamera, Mikrofon und Standort sowie eine Content-Security-Policy. Die Richtlinie erlaubt Inline-Skripte (unsafe-inline), weil Templates Inline-Skripte enthalten. Schreibende Aktionen sind per CSRF-Token geschützt.
Reverse Proxy
Setze TRUSTED_PROXIES auf die IP Deines Proxys, nie auf *. In compose.stage.yml und compose.live.yml setzt Compose den Wert fest auf REMOTE_ADDR, die App vertraut also der direkt verbundenen Gegenstelle. Die App lauscht dort nur auf 127.0.0.1.
Gespeicherte Daten und Datenschutz
| Daten | Personenbezug | Zweck |
|---|---|---|
| Kontakte (Name, E-Mail-Adresse) | ja | Empfänger der Alarm-E-Mails |
| Clients, URLs, Labels | je nach Inhalt | Überwachungsziele |
| Ergebnisse (Status, Meldung, HTTP-Code, Antwortzeit, Zeitpunkt) | nein, die Meldung kann Hostnamen, Pfade und Fehlertexte enthalten | Verlauf und Alarmierung |
| Agenten (Name, letzter Kontakt, Token-Hash) | nein | Zuordnung der Agenten-Checks |
| Server-Logs | IP-Adressen der Browser | Betrieb |
Watchdog sendet keine Daten an Dritte und enthält keine Telemetrie. Ausgehende Verbindungen gehen zu den überwachten Zielen, zum SMTP-Server und, bei Agenten, zum Dashboard. Das Hosting, die Aufbewahrungsdauer der Ergebnisse (siehe Konfiguration) und die Rechtstexte liegen in Deiner Verantwortung. Die mitgelieferten Seiten Impressum und Datenschutz sind Platzhalter.
Sicherheitslücken melden
Melde Sicherheitslücken nicht als öffentliches Issue, sondern über die private Schwachstellenmeldung des GitHub-Repositories (Security > Report a vulnerability).