diff --git a/STATUS.md b/STATUS.md index f75445b..5573432 100644 --- a/STATUS.md +++ b/STATUS.md @@ -91,7 +91,7 @@ Bedeutung der Meilensteine: siehe [roadmap.md](roadmap.md). |---|---|---| | [2026-08-21-egress-vollstaendig](docs/design/2026-08-21-egress-vollstaendig.md) | gate-4 | Design: Den ausgehenden Verkehr zu Ende schließen (#0088) | -## ADRs (24) +## ADRs (25) | ADR | Status | Title | |---|---|---| @@ -119,6 +119,7 @@ Bedeutung der Meilensteine: siehe [roadmap.md](roadmap.md). | [0022](docs/adr/0022-upstream-anschluss-durch-einmaligen-merge.md) | accepted | ADR-0022: Anschluss an Upstream durch einen einmaligen Merge, nicht durch einen geteilten Graft | | [0023](docs/adr/0023-fremdhistorie-von-der-git-hygiene-ausnehmen.md) | accepted | ADR-0023: Fremde Historie von der Git-Hygiene ausnehmen — erklärt, nicht global | | [0024](docs/adr/0024-drei-framework-dateien-erklaert-erweitert.md) | accepted | ADR-0024: Drei Framework-Dateien sind erklärt erweitert — Diff-Referenz statt Byte-Vergleich | +| [0025](docs/adr/0025-egress-ausnahmen-als-cidr-ausser-hinter-cdn.md) | proposed | ADR-0025: Egress-Ausnahmen werden als CIDR gepinnt — außer hinter einem CDN | ## Open AARs (6) diff --git a/docs/adr/0025-egress-ausnahmen-als-cidr-ausser-hinter-cdn.md b/docs/adr/0025-egress-ausnahmen-als-cidr-ausser-hinter-cdn.md new file mode 100644 index 0000000..61258b1 --- /dev/null +++ b/docs/adr/0025-egress-ausnahmen-als-cidr-ausser-hinter-cdn.md @@ -0,0 +1,92 @@ +--- +type: adr +id: "0025" +status: proposed +date: 2026-08-21 +supersedes: null +superseded_by: null +related: + - "docs/issues/0088-gitops-56-networkpolicy-ausgehender-verkehr-ist-unbesch.md" + - "docs/design/2026-08-21-egress-vollstaendig.md" +--- + +# ADR-0025: Egress-Ausnahmen werden als CIDR gepinnt — außer hinter einem CDN + +## Kontext + +Der Cluster war eingehend dicht und ausgehend offen. Beim Schließen (#0088) +stellte sich dieselbe Frage bei jeder Arbeitslast: Wohin darf sie, und wie +schreibt man das auf? + +Zwei Randbedingungen sind nicht verhandelbar. **NetworkPolicies kennen nur +CIDRs** — k3s setzt Standard-Policies durch, es gibt keine DNS- oder +FQDN-Regeln. Und **ein Ziel hinter einem CDN hat keine feste Adresse**: +`database.clamav.net` löst auf Cloudflare auf, mit wechselnden Adressen. + +Daraus entsteht ein Konflikt, der sich nicht wegentscheiden lässt: Die +einzige ausdrückbare Regel ist eine Adressliste, und für manche Ziele gibt +es keine haltbare. + +## Optionen + +**A: Alles pinnen, auch CDN-Ziele.** Konsequent und einheitlich. Der Preis +ist die Ausfallart: Rotiert der Anbieter, bricht der Zugriff — und zwar +**still**. Bei ClamAV hieße das: Signaturen veralten, der Dienst läuft +weiter, kein Alarm. Genau die Fehlerklasse, gegen die dieses Projekt seine +Prüflandschaft gebaut hat. + +**B: Für CDN-Ziele den Anbieterbereich erlauben.** Keine stille Ausfallart. +Cloudflare steht aber vor einem erheblichen Teil des Internets — die Regel +sähe nach Einschränkung aus und wäre praktisch keine. Eine Regel, die +Sicherheit vortäuscht, ist schlechter als eine erklärte Ausnahme. + +**C: CDN-Ziele intern spiegeln.** Technisch das Beste: der Dienst bekommt +ein festes, internes Ziel. Kostet eigene Infrastruktur mit eigenem Betrieb +und eigener Ausfallart, und die will erst gebaut sein. + +**D: Pinnen, wo es hält — sonst Ausgang offen lassen und begründen.** +Ehrlich und ohne stille Ausfallart. Der Preis ist Ungleichbehandlung: Einige +Arbeitslasten bleiben offen, und das muss aushaltbar begründet sein. + +## Entscheidung + +**Option D.** + +- **Ein Ziel mit haltbarer Adresse wird gepinnt**, so eng wie möglich — + Host und Port. Beispiele aus #0088: Storage Box als `/32:23`, der + operating-Host als `/32` auf zwei Ports. +- **Ein privater Weg schlägt einen öffentlichen.** Ist ein Ziel intern + erreichbar und dort TLS-sauber, zeigt der Name intern dorthin und die + Regel erlaubt die private Adresse. So geschehen bei rohana. +- **Ein kleiner Anbieterbereich ist zulässig**, wo eine Handvoll Adressen + desselben Betreibers rotiert und ein `/32` sonst still bräche — + `smtp.ionos.de` als `/27`. Die Grenze ist Größenordnung **und** Zweck: die + Mail-Infrastruktur eines Anbieters ja, ein CDN vor dem halben Internet + nein. +- **Hinter einem CDN bleibt der Ausgang offen, mit Begründung im Manifest.** + Nicht in einem Issue, nicht in einer ADR allein: **an der Regel selbst**, + wo der nächste Leser sie sucht. +- **Nicht tragende Ziele werden nicht erlaubt**, und dass sie scheitern, + steht dabei. Beispiel: Authentiks Versionsprüfung. + +## Konsequenzen + +*Einfacher.* Jede Ausnahme trägt ihren Grund dort, wo sie steht. Wer eine +Regel liest, muss nicht raten, ob sie Absicht oder Rest ist. Und keine +Ausnahme hat eine stille Ausfallart — was bricht, bricht sichtbar. + +*Schwerer.* Die Regeln sind nicht einheitlich, und Einheitlichkeit ist das, +was man beim Überfliegen sucht. Wer nur die Manifeste zählt, sieht offene +Ausgänge und hält sie für Nachlässigkeit; die Begründung muss er lesen. + +*Was offen bleibt.* Ein interner Spiegel für Signaturen (Option C) bleibt +der bessere Weg für ClamAV und ist ausdrücklich **nicht** verworfen, nur +vertagt. Wer ihn baut, löst die einzige verbliebene breite Ausnahme, die +kein Dienstmerkmal ist. + +⚠️ *Was diese Entscheidung nicht leistet.* Verkehr zur eigenen +Knoten-Adresse unterliegt der Policy nicht — am 2026-08-21 aus zwei +eingeschränkten Arbeitslasten gemessen. Jede „nur intern" laufende +Arbeitslast erreicht weiterhin, was über den Ingress veröffentlicht ist. +Das ist eine Eigenschaft der Durchsetzung, mit einer NetworkPolicy nicht zu +schließen, und gehört zu jeder Aussage über diese Regeln dazu. diff --git a/docs/design/2026-08-21-egress-vollstaendig.md b/docs/design/2026-08-21-egress-vollstaendig.md index cf176fe..cb1d0f7 100644 --- a/docs/design/2026-08-21-egress-vollstaendig.md +++ b/docs/design/2026-08-21-egress-vollstaendig.md @@ -521,4 +521,45 @@ das sind genau die fünf der Klasse C. **Status:** `DONE` +> **STOP — Slice-Review.** Freigegeben durch sorb, 2026-08-21. + +### Slice 4 — Klasse C begründen, und MAS geklärt + +- [x] **Gründe an die Regel schreiben** — files: + `apps/production/networkpolicy.yaml` — action: für jede der fünf offenen + Arbeitslasten steht am Selektor, warum — done. +- [x] **Die Richtung entscheiden** — files: + `docs/adr/0025-egress-ausnahmen-als-cidr-ausser-hinter-cdn.md` — done, + `status: proposed`. +- [x] **MAS klären** — action: Konfiguration aus dem laufenden Prozess lesen + — done, Ergebnis unten. + +**Warum die Gründe ins Manifest gehören und nicht ins Issue:** Ein offener +Ausgang, den niemand erklärt, liest sich als Nachlässigkeit. Wer die Regel +liest, soll nicht raten müssen, ob sie Absicht oder Rest ist. + +**MAS ist geklärt — und einschränkbar.** Der Container ist distroless, die +Konfiguration steht nicht im Repo; gelesen wurde sie über einen ephemeren +Container durch `/proc//root` des laufenden Prozesses: + +``` +http://matrix-stack-synapse-main.matrix.svc.cluster.local.:8008 +https://auth.axion1337.chat/application/o/matrix/ +``` + +Der Homeserver über den **internen** Service-Namen, Authentik über den +**öffentlichen** — und der löst auf die Knoten-Adresse auf, die der Policy +ohnehin nicht unterliegt (Gate-3-Fund). Damit fällt der Grund weg, aus dem +MAS in Klasse C stand. + +⚠️ **Trotzdem nicht eingebaut.** Gate 3 hat MAS „aus Vorsicht" dort +belassen, weil ein Irrtum die Anmeldung trifft. Die Vorsicht ist durch die +Messung kleiner geworden, aber nicht gegenstandslos: Die Abnahme dafür ist +ein echter Login, und den kann diese Sitzung nicht durchführen. Das Manifest +sagt jetzt genau das — offen ist die **Abnahme**, nicht die Analyse. + +**Status:** `DONE_WITH_CONCERNS` — der geplante Umfang ist fertig; eine +Arbeitslast ist nachweislich einschränkbar und bleibt es aus einem Grund, +den nur sorb ausräumen kann. + > **STOP — Slice-Review.** \ No newline at end of file