From 87264ffd4ac922ea28c037d0baca24a7e92c29c7 Mon Sep 17 00:00:00 2001 From: Thore Cimbal Date: Tue, 28 Jul 2026 21:42:36 +0200 Subject: [PATCH] Document issue #38 fix: coturn TURN-secret architecture fix + automated rotation --- 00-TASKS.md | 31 +++++++++++++++++++++++++++++++ Home.md | 2 +- TURN-Server.md | 3 ++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/00-TASKS.md b/00-TASKS.md index c5a3a3c..eaffdd9 100644 --- a/00-TASKS.md +++ b/00-TASKS.md @@ -244,6 +244,37 @@ MAS 256 / Authentik 1641 TOC-Einträge), alle media_store-Dateien mit Original-T intakt. Hetzners eigener monatlicher Storage-Box-Snapshot bleibt zusätzlich aktiv (schützt die Borg-Repos selbst, komplementär zur Retention). +**Update 2026-07-28 (Issue #38, coturn TURN-Secret-Rotation)**: Diskussion zur +Rotationspolitik deckte einen echten Bug auf: das TURN-Shared-Secret war dupliziert - +korrekt SOPS-verschlüsselt in `coturn-secret.yaml`, aber **zusätzlich im Klartext** in +`synapse-values.yaml` (git-Historie, unverschlüsselte ConfigMap). Ausgelagert in eine +eigene SOPS-Secret-Datei (`synapse-turn-secret.yaml`), Wert sofort rotiert. Nebenbei +gefunden+gefixt: coturns `hostNetwork`-Deployment nutzte die Default-`RollingUpdate`- +Strategie, die auf einem Single-Node-Cluster nie schedulen kann (neuer Pod braucht +dieselben Ports 3478/5349 wie der alte) - auf `Recreate` umgestellt. + +**Automatisierung**: monatlicher CronJob (`0 4 1 * *`, `rohana.axion1337.de/sorb/axion-secret-rotation:v1`) +rotiert das Secret automatisch. Zwei bewusste Sicherheits-Entscheidungen: +- **Dedizierter, gescopter age-Key** für den Job statt des Repo-Master-Keys - kann nur + `coturn-secret.yaml` + `synapse-turn-secret.yaml` entschlüsseln, nicht die anderen + Secrets im Repo. Live verifiziert: Master-Key entschlüsselt weiterhin beide Dateien, + Scoped-Key entschlüsselt beide, aber **nicht** ein unabhängiges Secret (authentik-secret.yaml). +- Der Job **pusht nicht direkt nach main**, sondern öffnet eine **Pull Request** - ein + Mensch muss bewusst mergen, bevor die Rotation live geht. + +**Live-Test (PR #42) durchlaufen**: Job clonte, rotierte, committete, pushte, öffnete PR - +Diff exakt wie erwartet (nur die 2 Secret-Werte + 2 Checksum/Rotated-at-Annotationen). +Nach Merge zeigte sich ein reales, aber selbstheilendes Timing-Problem: coturn +(Kustomization-Ebene, 1m Intervall) restartete schnell, **Synapse aber verzögert**, da +es über eine separate HelmRelease (eigenes 5m-Reconcile-Intervall) läuft - kurzes Fenster, +in dem coturn schon das neue Secret hatte, Synapse noch das alte (Anrufe wären in dem +Fenster fehlgeschlagen). Kein Hänger, nur eine Verzögerung - HelmRelease-Intervall auf 1m +reduziert, um das Fenster zu verkürzen. Danach: echter Call getestet, funktioniert. + +Nebenbei gefunden+gefixt: Pod-Netzwerk-Erreichbarkeit zum Gitea-Host war zeitweise down +(hängt mit #41 zusammen) - `hostAliases` auf den Rotation-Job ergänzt, damit er über das +private Hetzner-Netzwerk läuft statt vom öffentlichen Firewall-Status abhängig zu sein. + ### Authentik Stage 2 – MAS Integration (⏳ Depends on Manual Config) — historisch, siehe Update oben **Beschreibung**: Authentik OIDC Provider muss manuell im Authentik Admin UI konfiguriert werden, bevor Stage 2 Deployment möglich ist. diff --git a/Home.md b/Home.md index 6d3f57f..0335664 100644 --- a/Home.md +++ b/Home.md @@ -68,7 +68,7 @@ PostgreSQL + TURN (turn.axion1337.chat) | Category | Count | Status | |----------|-------|--------| -| **Completed** | 14 | ✅ K3S, Flux, ESS, Themes, Desktop, Monitoring, TURN, Authentik (Enrollment/Recovery/2FA), coturn-Fix, Element Call Fork, NetworkPolicies, Authentik OIDC Provider as Code, authentik-postgresql NetworkPolicy, Postgres+Media Backups | +| **Completed** | 15 | ✅ K3S, Flux, ESS, Themes, Desktop, Monitoring, TURN, Authentik (Enrollment/Recovery/2FA), coturn-Fix, Element Call Fork, NetworkPolicies, Authentik OIDC Provider as Code, authentik-postgresql NetworkPolicy, Postgres+Media Backups, coturn TURN-Secret Rotation | | **In Progress** | 0 | — | | **Backlog** | 30+ | 📋 tracked as individual Gitea issues (#9, #11-#41), see [[00-TASKS]] | | **Security** | 10 | 🔒 Firewall, SSH, auditd, Kernel hardening, CrowdSec, Falco | diff --git a/TURN-Server.md b/TURN-Server.md index 00533ea..bf5369b 100644 --- a/TURN-Server.md +++ b/TURN-Server.md @@ -22,7 +22,8 @@ Client A ──→ coturn (turn.axion1337.chat) ──→ Client B |-------|--------| | `coturn.yaml` | ConfigMap + Deployment + Service | | `coturn-secret.yaml` | SOPS-Secret: `TURN_SECRET` | -| `custom-configs/synapse-values.yaml` | TURN URIs + shared secret | +| `synapse-turn-secret.yaml` | SOPS-Secret: TURN URIs + shared secret für Synapse (seit 2026-07-28, vorher fälschlich im Klartext in `custom-configs/synapse-values.yaml` - siehe Issue #38) | +| `turn-secret-rotation-secret.yaml` + `turn-secret-rotation.yaml` | Monatlicher automatisierter Rotations-CronJob (Issue #38) - eigener gescopter age-Key, öffnet PR statt direkt zu pushen | | `matrix-certificates.yaml` | cert-manager Cert für `turn.axion1337.chat` | ## DNS & Firewall (manuell)