docs: slice 4 — reasons at the rule, ADR-0025, and MAS resolved
The five remaining open workloads now carry their reason at the selector rather than in an issue. An unexplained open egress reads as neglect, and whoever reads the rule should not have to guess whether it is intent or leftover. ADR-0025 decides the direction the whole undertaking kept running into: pin what holds, prefer a private path over a public one, allow a small provider block where a /32 would break silently, and leave a CDN target open with the reason at the rule. It also records what the decision does not achieve - traffic to the node's own address escapes the policy entirely. MAS is resolved and turns out to be restrictable. Its configuration is not in the repo and its container is distroless, so it was read from the running process through /proc in an ephemeral container: the homeserver by internal service name, Authentik by public name - and public names resolve to the node address, which no policy covers. The reason for keeping it broad is therefore gone. It is still not restricted. The sign-off is a real login, which this session cannot perform, and a mistake there hits authentication. The manifest now says exactly that: what is open is the acceptance, not the analysis. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2Q4Ri8NGwyTZzScvKnWFM
This commit is contained in:
co-authored by
Claude Opus 5
parent
c7f7e73c6b
commit
4f6b8d79c3
@@ -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)
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -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/<pid>/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.**
|
||||
Reference in New Issue
Block a user