--- type: issue id: "0060" status: open created: 2026-07-28 milestone: M1 priority: medium area: security projekt: gitops gitlab_iid: "17" related: [] --- # Federation allowlist or closed federation decision > Adoptiert aus [gitops#17](https://git.lab/axion1337.chat/axion1337.chat-gitops/-/issues/17) (2026-08-18, ADR-0019). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei. Decide: open federation with all public Matrix servers (current default, larger attack surface) vs. an explicit `federation_domain_whitelist`, vs. fully closed federation (`allow_public_rooms_without_join_rules: false`). Config lives in `apps/production/custom-configs/synapse-values.yaml`. --- *Migriert aus Gitea `sorb/axion1337.chat-gitops#17` — dort erstellt am 2026-07-28 von sorb.* ## Entscheidungsgrundlage 2026-08-19 — gemessen statt geschätzt Die Frage war seit dem 2026-07-28 offen, weil niemand wusste, was eine Schließung kosten würde. Jetzt ist es beziffert. **Föderation ist offen und öffentlich erreichbar.** In `synapse-values.yaml` steht zu Föderation **nichts** — es gelten die Synapse-Vorgaben. Von außen gemessen: ``` https://matrix.axion1337.chat/_matrix/federation/v1/version -> HTTP 200 https://matrix.axion1337.chat/_matrix/key/v2/server -> HTTP 200 ``` Port 8448 ist zwar zu, das ändert nichts: Die Delegation (`/.well-known/matrix/server` → `matrix.axion1337.chat:443`) führt die Föderation über den regulären HTTPS-Port, und der ist offen. **Benutzt wurde sie noch nie.** Aus der Synapse-Datenbank, über die gesamte Betriebszeit (Erstkonto 2026-04-21): | | | |---|---| | Zielserver in `destinations` | **0** | | davon je erfolgreich kontaktiert | **0** | | fremde Nutzer in unseren Räumen | **0** | | Räume mit fremder Beteiligung | **0** | | eigene Räume | 31 | Nicht „wenig genutzt" — **null**, in vier Monaten. Damit kostet eine Schließung heute nichts Messbares; sie nimmt nur eine Möglichkeit weg, die niemand wahrgenommen hat. **Was dagegen bezahlt wird:** Die Föderations-Schnittstelle ist die größte fremdzugewandte Angriffsfläche, die Synapse hat, und historisch die, in der seine CVEs sitzen. Jeder Matrix-Server der Welt darf derzeit Beitritts- und Ereignisverkehr versuchen. ### Optionen mit ihren Folgen **A — offen lassen (Ist-Zustand).** Kein Aufwand. Wir bezahlen dauerhaft Angriffsfläche für eine Fähigkeit mit null nachgewiesenem Bedarf. **B — `federation_domain_whitelist` mit leerer Liste.** Föderation nur mit ausdrücklich genannten Servern; leer heißt: mit keinem. Eine Zeile Konfiguration, über GitOps versioniert, in Minuten rückgängig durch Eintragen einer Domain. ⚠️ **Was es NICHT tut:** Die Endpunkte antworten weiterhin (`key/v2/server`, `federation/v1/version`) — der Server ist also nicht unsichtbar, nur unbeteiligt. **C — Föderations-Listener ganz abschalten.** Kleinste Fläche, aber Eingriff in das ESS-Chart und schwerer zurückzudrehen. **Empfehlung: B.** Sie kostet heute nichts, ist eine Zeile, ist versioniert und hält die Tür offen, ohne Miete dafür zu zahlen. C lohnt erst, wenn feststeht, dass Föderation dauerhaft unerwünscht ist — dann als eigene Entscheidung mit ADR. **Getrennt davon** nennt das Issue `allow_public_rooms_without_join_rules`: Das steuert nur, ob das Raumverzeichnis über Föderation sichtbar ist, und ist unabhängig von der Grundsatzfrage. **Entscheidung sorb steht aus.** ## Entscheidung und Umsetzung 2026-08-19 **sorb: erst C, dann C verworfen — B umgesetzt.** Beim Bauen von C zeigte sich, dass ein Pfad-Block die Gruppen-Calls zerstört hätte: `lk-jwt-service` prüft OpenID-Tokens über `/_matrix/federation/v1/openid/userinfo` und ruft ihn über den **öffentlichen** Namen auf (keine `hostAliases`, `dnsPolicy: ClusterFirst`), also über Traefik. Ein Block auf `/_matrix/federation/` hätte denselben Ausfall erzeugt wie der gelöschte `mrtc`-Record. Festgehalten als [ADR-0021](../adr/0021-foederation-geschlossen.md), inklusive der Begründung, warum C nicht nachträglich „noch schnell" nachgeholt werden sollte. `federation_domain_whitelist: []` steht in `gitops:apps/production/custom-configs/synapse-values.yaml` (Commit `3935f35`). **Zwei Fallen beim Umsetzen, beide vor dem Ausrollen bemerkt:** 1. Der erste Einschub **zerschnitt den `auto_join`-Block** — `auto_join_rooms_for_guests` landete unter `federation`. Nach dem Zusammenführen der Fragmente funktional identisch, zu lesen falsch; korrigiert, der Diff ist jetzt 20 Zeilen Zugewinn und nichts Verschobenes. 2. **Flux hat angewandt, Synapse lief weiter mit der alten Konfiguration.** Die ConfigMap trug die Zeile, der laufende Pod nicht — er stammte vom 2026-08-01. Die Konfiguration wird beim Pod-Start gerendert; ohne Neustart ist die Änderung wirkungslos. Dieselbe Klasse wie #0044. Neustart per `rollout restart statefulset/matrix-stack-synapse-main` angestoßen. **Zur Hetzner-Port-Sperre:** Sie kann diese Trennung nicht leisten. 8448 ist bereits zu, und die Delegation führt die Föderation über **443** — denselben Port wie alle Clients. Die Synapse-Konfiguration ist die einzige Stelle, an der Föderation und Client-Verkehr überhaupt trennbar sind. ### Abnahme nach dem Neustart (2026-08-19, Synapse-Start 11:13 UTC) | Prüfung | Ergebnis | |---|---| | `federation_domain_whitelist: []` **im laufenden Prozess** (nicht nur in der ConfigMap) | ✅ vorhanden | | `/_matrix/federation/v1/openid/userinfo` — die Element-Call-Abhängigkeit | ✅ HTTP 401 (bedient, verlangt Token) | | `/_matrix/client/versions` — Client-Verkehr | ✅ HTTP 200 | | `/_matrix/federation/v1/version` | HTTP 200 — **erwartet** | Der letzte Punkt ist kein Mangel, sondern die bewusste Grenze von Option B: Die Endpunkte antworten weiterhin, der Server ist **unbeteiligt, nicht unsichtbar**. Was sich geändert hat, ist nicht die Sichtbarkeit, sondern dass Synapse mit keinem fremden Server mehr Ereignisse austauscht. **Noch offen: die Abnahme im echten Gruppen-Call.** `curl` belegt, dass der OpenID-Endpunkt antwortet — nicht, dass die vollständige Token-Prüfung durchläuft. Für Änderungen im Call-Pfad gilt hier die Regel aus #0054: Abnahme im echten Call ist Rollout-Voraussetzung, nicht Nacharbeit.