Sicherheits-Härtung und Bugfixes

This commit is contained in:
Patrick Asmus
2026-10-11 17:39:03 +02:00
parent c3f68ace96
commit 65b0b5ac0f
25 changed files with 2577 additions and 686 deletions
+46 -6
View File
@@ -8,13 +8,15 @@ Die Konfiguration liegt in `data/config.yml` und kann über das Web-UI unter **E
Beim ersten Start wird die Datei automatisch mit Standardwerten erstellt. Eine Vorlage mit Kommentaren findet sich in `bin/config.yml.dist`.
Die Datei enthält Secrets und wird beim Containerstart auf die Rechte `600` gesetzt.
## Abschnitte
### Aufnahme
| Parameter | Standard | Beschreibung |
|-----------|----------|-------------|
| `recording.download_path` | `/app/data/recordings` | Speicherort für Aufnahmen |
| `recording.download_path` | `/app/data/recordings` | Speicherort für Aufnahmen. Muss innerhalb eines Verzeichnisses aus `RECORDING_ROOTS` liegen |
| `recording.max_retries` | `5` | Max. Reconnect-Versuche bei Verbindungsabbruch (0 = unbegrenzt) |
| `recording.retry_delay` | `5` | Wartezeit (Sekunden) zwischen Reconnect-Versuchen |
@@ -25,13 +27,26 @@ Beim ersten Start wird die Datei automatisch mit Standardwerten erstellt. Eine V
| `server.host` | `0.0.0.0` | Bind-Adresse des Webservers |
| `server.port` | `8484` | Port des Webservers |
Der Abschnitt `server` wird nur aus der Datei gelesen und kann nicht über Web-UI/API geändert werden. Da die Anwendung nicht als root läuft, sind Ports unter 1024 nicht möglich.
### Authentifizierung
| Parameter | Standard | Beschreibung |
|-----------|----------|-------------|
| `auth.enabled` | `false` | Basic Auth aktivieren |
| `auth.enabled` | `true` | Basic Auth aktivieren (erfordert ein Passwort mit mind. 8 Zeichen) |
| `auth.username` | `admin` | Benutzername |
| `auth.password` | `stream-recorder` | Passwort |
| `auth.password_hash` | _(generiert)_ | PBKDF2-Hash des Passworts |
| `auth.password` | — | Optional: Klartext-Passwort, wird beim Start automatisch in `password_hash` umgewandelt |
Beim ersten Start (keine `config.yml` vorhanden) ist die Anmeldung aktiv. Benutzer ist `admin`, das zufällig erzeugte Passwort wird einmalig im Container-Log ausgegeben:
```bash
docker logs stream-recorder
```
Bestehende Installationen behalten ihre bisherige Auth-Einstellung. Nach 10 fehlgeschlagenen Logins innerhalb von 5 Minuten wird die IP für den Rest des Zeitfensters mit HTTP 429 abgewiesen.
**Passwort vergessen:** In `data/config.yml` den Eintrag `password_hash` durch `password: neues-passwort` ersetzen und den Container neu starten.
### Zeitplan-Puffer
@@ -47,7 +62,7 @@ Standardwerte für die Vor- und Nachlaufzeit bei neuen Jobs mit Zeitplan.
| Parameter | Standard | Beschreibung |
|-----------|----------|-------------|
| `ntfy.url` | _(leer)_ | NTFY Topic-URL (z.B. `https://ntfy.sh/mein-topic`) |
| `ntfy.token` | _(leer)_ | Bearer-Token für authentifizierte Topics |
| `ntfy.token` | _(leer)_ | Bearer-Token für authentifizierte Topics (wird von der API nie zurückgegeben) |
| `ntfy.events` | `error` | Kommaseparierte Events: `start`, `stop`, `error`, `upload` |
### Plik
@@ -55,7 +70,7 @@ Standardwerte für die Vor- und Nachlaufzeit bei neuen Jobs mit Zeitplan.
| Parameter | Standard | Beschreibung |
|-----------|----------|-------------|
| `plik.url` | _(leer)_ | Plik-Server URL (z.B. `https://plik.example.com`) |
| `plik.api_key` | _(leer)_ | API Key für authentifizierte Uploads |
| `plik.api_key` | _(leer)_ | API Key für authentifizierte Uploads (wird von der API nie zurückgegeben) |
| `plik.ttl` | `30d` | Aufbewahrungsdauer der Uploads (`30d`, `12h`, etc.) |
### Logging
@@ -64,6 +79,31 @@ Standardwerte für die Vor- und Nachlaufzeit bei neuen Jobs mit Zeitplan.
|-----------|----------|-------------|
| `logging.level` | `INFO` | Log-Level: `DEBUG`, `INFO`, `WARN`, `ERROR` |
Anwendungs-Logs erscheinen im Web-UI und zusätzlich auf stdout (`docker logs stream-recorder`). Einträge älter als `LOG_RETENTION_DAYS` Tage werden automatisch gelöscht.
## Umgebungsvariablen
| Variable | Standard | Beschreibung |
|----------|----------|-------------|
| `TZ` | — | Zeitzone (z.B. `Europe/Berlin`) |
| `PUID` | `1000` | UID, unter der die Anwendung läuft |
| `PGID` | `1000` | GID, unter der die Anwendung läuft |
| `RECORDING_ROOTS` | `/app/data/recordings:/recordings` | Erlaubte Basisverzeichnisse für `download_path` (durch `:` getrennt) |
| `LOG_RETENTION_DAYS` | `90` | Aufbewahrung der Log-Einträge in Tagen |
| `ENABLE_API_DOCS` | — | `1` aktiviert die Swagger-UI unter `/docs` |
Der Container startet als root, passt UID/GID des internen Users `app` an `PUID`/`PGID` an, setzt den Besitzer von `data/` und den vorhandenen Verzeichnissen aus `RECORDING_ROOTS` (nur abweichende Dateien) und startet die Anwendung anschließend ohne Root-Rechte.
Eigener Aufnahmepfad, z.B. auf einem separaten Laufwerk:
```yaml
volumes:
- ./data:/app/data
- /mnt/storage/recordings:/recordings
```
Danach in den Einstellungen `download_path` auf `/recordings` setzen. Andere Pfade müssen zusätzlich in `RECORDING_ROOTS` eingetragen werden.
## Beispiel
```yaml
@@ -79,7 +119,7 @@ server:
auth:
enabled: true
username: admin
password: mein-passwort
password: mein-passwort # wird beim Start in password_hash umgewandelt
schedule:
default_pre_buffer: 5