docs: Gate 1 for closing the outbound traffic (#0088), taken in progress

Assigned by sorb. Size L: fifteen workloads, a real decision per service,
and mistakes land in production.

The acceptance criteria are counted in the running cluster rather than read
off the manifests - that distinction is what produced this undertaking in
the first place, since the issue's own remaining list was a week out of
date. Zero workloads without an egress rule, every exception naming where
and why with evidence that the service fails without it, a pre-agreed
smoke list, and a demonstration from inside a pod that a forbidden target
actually fails.

Non-goals name the temptations: no ingress changes, no new model or tool,
and no switching a feature off to save a rule. Synapse needs broad egress
for URL previews and already has the right control in
url_preview_ip_range_blacklist; disabling the feature would be the wrong
lever, as the issue has said since the 20th. flux-system is excluded too -
it pulls from the network and is the thing that rolls this change out, so
cutting its ground is a separate act with its own fallback.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F2Q4Ri8NGwyTZzScvKnWFM
This commit is contained in:
Thore Cimbal
2026-08-21 12:00:00 +00:00
co-authored by Claude Opus 5
parent 94f0308c08
commit 04b1b84da7
4 changed files with 120 additions and 4 deletions
+5 -3
View File
@@ -14,7 +14,7 @@ Bedeutung der Meilensteine: siehe [roadmap.md](roadmap.md).
|---|---|---|---|
| [0056](docs/issues/0056-gitops-9-external-postgresql-migration-cloudnativepg-o.md) | high | open | External PostgreSQL Migration: CloudNativePG or Hetzner |
| [0078](docs/issues/0078-gitops-45-cve-meldeweg-v2-metriken-grafana-dashboard-al.md) | medium | open | CVE-Meldeweg v2: Metriken, Grafana-Dashboard, Alerts in eigenen Matrix-Raum |
| [0088](docs/issues/0088-gitops-56-networkpolicy-ausgehender-verkehr-ist-unbesch.md) | medium | open | NetworkPolicy: 15 Arbeitslasten haben noch freien Ausgang, zwei Namespaces ganz |
| [0088](docs/issues/0088-gitops-56-networkpolicy-ausgehender-verkehr-ist-unbesch.md) | medium | in-progress | NetworkPolicy: 15 Arbeitslasten haben noch freien Ausgang, zwei Namespaces ganz |
| [0004](docs/issues/0004-overmind-02-e1000e-nic-hang-beobachtung-nach.md) | low | waiting | OVERMIND-02: e1000e-NIC-Hang — Beobachtung nach EEE-Fix + Firmware-Update |
| [0072](docs/issues/0072-gitops-34-dsgvo-datenschutz-compliance-konkretisieren.md) | low | open | DSGVO/Datenschutz-Compliance konkretisieren |
@@ -85,9 +85,11 @@ Bedeutung der Meilensteine: siehe [roadmap.md](roadmap.md).
| [0090](docs/issues/0090-gitops-59-kein-kubernetes-audit-log-zugriffe-an-der-api.md) | low | open | Kein Kubernetes-Audit-Log — Zugriffe an der API werden nicht protokolliert |
## Active design docs (0)
## Active design docs (1)
_none active_
| Design | Gate | Title |
|---|---|---|
| [2026-08-21-egress-vollstaendig](docs/design/2026-08-21-egress-vollstaendig.md) | gate-1 | Design: Den ausgehenden Verkehr zu Ende schließen (#0088) |
## ADRs (24)
@@ -0,0 +1,83 @@
---
type: design
status: gate-1
date: 2026-08-21
size: L
related:
- "docs/issues/0088-gitops-56-networkpolicy-ausgehender-verkehr-ist-unbesch.md"
---
# Design: Den ausgehenden Verkehr zu Ende schließen (#0088)
## Gate 1 — Product
**Problem.** Eingehend ist der Cluster dicht — 13 Ingress-Regeln, dazu
`default-deny-ingress` in beiden Namespaces. Ausgehend ist er es nicht.
Gemessen am 2026-08-21:
| | |
|---|---|
| auf internen Verkehr eingeschränkt | **10** Arbeitslasten in `matrix` |
| weiterhin freier Ausgang, laufend | **7** — `synapse-main`, `matrix-authentication-service`, `matrix-rtc-sfu`, `matrix-rtc-authorisation-service`, `coturn`, `clamav`, `wikijs` |
| weiterhin freier Ausgang, Job-artig | **8** — `synapse-backup`, `wikijs-backup`, `wikijs-config`, `turn-secret-rotation`, `init-secrets`, `synapse-check-config`, `deployment-markers-pre`/`-post` |
| Namespaces ohne jede Ausgangsregel außer der Metadaten-Sperre | **2** — `authentik`, `monitoring` |
Die Job-artigen sind nicht harmloser, nur seltener: Ihr Ausgang gilt beim
nächsten Lauf. Und `wikijs` ist unbeschränkt, während seine Datenbank und
seine Gruppenprüfung es nicht sind — das war nicht beabsichtigt und stand
nirgends.
Warum das mehr ist als Hygiene: Ein Dienst mit freiem Ausgang kann nach
einer Kompromittierung nachladen, abfließen lassen und sich melden. Die
Ingress-Härtung schützt gegen den Einstieg, nicht gegen das, was danach
kommt. Der Metadaten-Dienst ist seit dem 2026-08-20 gesperrt — das war der
schärfste Einzelfall, nicht das Ende der Aufgabe.
**Acceptance criterion.** Zählbar, im laufenden Cluster gemessen, nicht am
Manifest gelesen:
1. **Null Arbeitslasten ohne Ausgangsregel.** In `matrix`, `authentik` und
`monitoring` ist jede Arbeitslast von genau einer Egress-Policy erfasst;
die Zahl derer, für die nur `egress-block-metadata` gilt, ist **0**.
Nachgewiesen mit demselben Skript wie die Bestandsaufnahme, nach
`status.phase` getrennt.
2. **Jede Ausnahme ist benannt und begründet.** Wo ein Dienst nach draußen
darf, steht im Manifest **wohin und warum** — nicht „braucht Internet".
Für jede Ausnahme existiert der Beleg, dass der Dienst ohne sie
scheitert.
3. **Kein Dienstausfall.** Eine vorab festgelegte Abnahmeliste läuft nach
dem Umbau durch: Föderation, Anmeldung über Authentik, ein Call, ein
Backup-Lauf, ClamAV-Signaturen, Wiki-Zugriff. Jede Zeile mit Messung,
nicht mit „sieht gut aus".
4. **Die Sperre ist gegengeprüft.** Für mindestens eine eingeschränkte
Arbeitslast wird gezeigt, dass ein Ziel außerhalb der Erlaubnis
**tatsächlich** scheitert — aus dem Pod heraus, mit einem Werkzeug, das
im Container existiert.
**Non-goals.**
- **Keine Ingress-Änderungen.** Eingehend ist dicht; daran wird nicht
gerührt.
- **Kein Umbau des Modells.** Es bleibt bei Policies je Namespace im
bestehenden Stil — kein Service-Mesh, keine Cilium-Policies, kein neues
Werkzeug.
- **Kein Abschalten von Funktionen**, um eine Regel zu sparen. Bei Synapse
ist die URL-Vorschau der Grund für breiten Ausgang, und sie hat mit
`url_preview_ip_range_blacklist` bereits die richtige Kontrolle — sie
abzuschalten wäre der falsche Hebel, das steht seit dem 20.08. im Issue.
- **Nicht `game-operating`, `gameserver`, Homelab.** Außerhalb des Umfangs.
- **Keine Egress-Regeln für `flux-system`.** Flux zieht aus dem Netz und
ist die Instanz, die diese Änderung ausrollt; sich selbst den Boden
wegzuziehen ist ein eigener Vorgang mit eigener Rückfallebene.
**Announcement.** Der Cluster ist eingehend seit Monaten dicht und
ausgehend offen — jeder Dienst darf ins Internet, in fremde Namespaces und
zu beliebigen Zielen. Diese Etappe schließt das für die verbliebenen
fünfzehn Arbeitslasten und die zwei bisher gar nicht erfassten Namespaces.
Danach hat jeder Dienst genau die Ausgänge, die er nachweislich braucht,
jede Ausnahme trägt ihren Grund im Manifest, und dass die Sperre wirkt, ist
aus einem Pod heraus gezeigt statt aus dem Manifest geschlossen.
**Mockups.** Keine Oberfläche beteiligt.
> **STOP — Freigabe für Gate 1.**
@@ -1,7 +1,7 @@
---
type: issue
id: "0088"
status: open
status: in-progress
created: 2026-08-06
milestone: M1
priority: medium
@@ -0,0 +1,31 @@
---
type: ledger
date: 2026-08-21
size: L
status: open
related:
- "docs/design/2026-08-21-egress-vollstaendig.md"
- "docs/issues/0088-gitops-56-networkpolicy-ausgehender-verkehr-ist-unbesch.md"
---
# Ledger: Den ausgehenden Verkehr zu Ende schliessen (#0088)
## Gates
| gate | commit | approval | status | note |
|---|---|---|---|---|
## Ladder
| searched | found | outcome | commit |
|---|---|---|---|
| `apps/production/networkpolicy.yaml` und die beiden anderen Namespaces, bevor ein Modell entworfen wird | 18 Policies, davon drei Egress; `authentik` und `monitoring` haben je eine eigene Datei mit nur der Metadaten-Sperre | reused: bestehender Stil je Namespace, kein neues Modell und kein Werkzeug | |
| die Bestandsaufnahme aus der Vormessung, statt neu zu zaehlen | 10 eingeschraenkt, 7 laufend offen, 8 Job-artig offen, 2 Namespaces gar nicht erfasst | reused: die Zahlen aus #0088 vom selben Tag, samt Methodik | |
## Notes
**Der Zustand ist gemessen, nicht aus den Manifesten gelesen.** Beim
Nachmessen fielen zwei Dinge auf, die in keinem Manifest stehen: `wikijs`
ist unbeschraenkt, waehrend seine Datenbank und seine Gruppenpruefung es
nicht sind, und die Namespaces `authentik` und `monitoring` kamen im Issue
ueberhaupt nicht vor.