docs: #0051 closes with two criteria it did not quite meet
Zero criticals without a decision across all fifty-four targets, every one of them actually measured. What could not be fixed is decided instead: twenty-seven entries, ninety-two CVE ids, each with a reason and a review date that a rule watches. Criterion 2 ends at one rather than zero, because the image that runs nowhere is the rollback target for the one that does, and prefering it unscanned to keep a number clean would be the wrong trade. Criterion 3 lags until the next scan round, since the scanner runs daily and today is the day everything moved. Both are written down as misses rather than redefined into hits. The closing numbers are hand-computed against the live inventory, not read off the dashboard. That is how the six criticals in the new synapse surfaced at all — the pipeline still holds the report for the version we replaced this evening. A runbook goes with it, because the expensive parts of this pass were never trivy: a delivery path that does not report its own halt, a network rule a chart jump outran, and three indentations I assumed instead of measuring.
This commit is contained in:
@@ -2,9 +2,9 @@
|
||||
|
||||
<!-- Generated by scripts/gen_status.py — do not edit. -->
|
||||
|
||||
## Issues (50 open, 53 closed)
|
||||
## Issues (49 open, 54 closed)
|
||||
|
||||
Verteilung: M2 16 · M3 4 · M4 11 · M5 18 · M6 1
|
||||
Verteilung: M2 16 · M3 4 · M4 11 · M5 17 · M6 1
|
||||
|
||||
Bedeutung der Meilensteine: siehe [roadmap.md](roadmap.md).
|
||||
|
||||
@@ -54,11 +54,10 @@ Bedeutung der Meilensteine: siehe [roadmap.md](roadmap.md).
|
||||
| [0100](docs/issues/0100-threadnet-web-13-asset-pfade-tragen-weiterhin-element-themes-e.md) | low | open | Asset-Pfade tragen weiterhin "element" (themes/element/…) |
|
||||
| [0101](docs/issues/0101-threadnet-call-4-kaputtes-paket-0-19-2-threadnet-6-in-der-regi.md) | low | open | Kaputtes Paket 0.19.2-threadnet.6 in der Registry — Herkunft ungeklärt |
|
||||
|
||||
### M5 (18)
|
||||
### M5 (17)
|
||||
|
||||
| Issue | Priorität | Status | Title |
|
||||
|---|---|---|---|
|
||||
| [0051](docs/issues/0051-cve-remediation-pass.md) | high | in-progress | CVE-Remediation-Pass: Schwachstellen-Report abarbeiten |
|
||||
| [0065](docs/issues/0065-gitops-25-k3s-api-security-hardening.md) | high | open | K3s API security hardening |
|
||||
| [0109](docs/issues/0109-der-weg-vom-commit-ins-cluster-meldet-seinen-stillstand-nicht.md) | high | open | Der Weg vom Commit ins Cluster meldet seinen Stillstand nicht |
|
||||
| [0058](docs/issues/0058-gitops-14-web-application-firewall-waf.md) | medium | open | Web Application Firewall (WAF) |
|
||||
@@ -84,11 +83,9 @@ Bedeutung der Meilensteine: siehe [roadmap.md](roadmap.md).
|
||||
| [0072](docs/issues/0072-gitops-34-dsgvo-datenschutz-compliance-konkretisieren.md) | low | open | DSGVO/Datenschutz-Compliance konkretisieren |
|
||||
|
||||
|
||||
## Active design docs (1)
|
||||
## Active design docs (0)
|
||||
|
||||
| Design | Gate | Title |
|
||||
|---|---|---|
|
||||
| [2026-08-21-cve-remediation](docs/design/2026-08-21-cve-remediation.md) | gate-4 | Design: Den CVE-Bestand abarbeiten (#0051) |
|
||||
_none active_
|
||||
|
||||
## ADRs (27)
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ type: aar
|
||||
status: open
|
||||
date: 2026-08-21
|
||||
related:
|
||||
- "docs/design/2026-08-21-cve-remediation.md"
|
||||
- "docs/design/done/2026-08-21-cve-remediation.md"
|
||||
- "docs/issues/0051-cve-remediation-pass.md"
|
||||
- "docs/issues/0088-gitops-56-networkpolicy-ausgehender-verkehr-ist-unbesch.md"
|
||||
---
|
||||
|
||||
@@ -3,7 +3,7 @@ type: aar
|
||||
status: open
|
||||
date: 2026-08-21
|
||||
related:
|
||||
- "docs/design/2026-08-21-cve-remediation.md"
|
||||
- "docs/design/done/2026-08-21-cve-remediation.md"
|
||||
- "docs/issues/0051-cve-remediation-pass.md"
|
||||
---
|
||||
|
||||
|
||||
+143
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
type: design
|
||||
status: gate-4
|
||||
status: done
|
||||
date: 2026-08-21
|
||||
size: L
|
||||
related:
|
||||
@@ -742,3 +742,145 @@ nur ihr Symptom.
|
||||
|
||||
⚠️ **Unterbrochen von einem Ausfall der Anmeldung**, den ich selbst verursacht
|
||||
habe — siehe `docs/aar/2026-08-21-mas-haproxy-netzregel.md`.
|
||||
|
||||
---
|
||||
|
||||
## Gate 5 — Abnahme
|
||||
|
||||
### Haufen A, sechster Posten: die zwei Releases mit schwebendem Fassungsbereich
|
||||
|
||||
⚠️ **Der Fund dieses Schritts ist kein CVE, sondern eine Form.** In diesem Repo
|
||||
pinnt **jeder** HelmRelease eine feste Fassung — mit genau **zwei** Ausnahmen,
|
||||
`alloy` (`0.x`) und `kube-state-metrics` (`5.x`). Und genau diese zwei waren die
|
||||
zurückgefallenen: `0.12.6` ist die letzte 0er-Fassung des alloy-Charts, `5.37.0`
|
||||
die letzte 5er von kube-state-metrics. Der Bereich sah aus wie „bleibt aktuell"
|
||||
und war eine **Decke**.
|
||||
|
||||
Die feste Nummer ist hier die ehrlichere: sie veraltet **sichtbar**.
|
||||
|
||||
Vor dem Ausrollen — die Lehre aus dem ESS-Ausfall wenige Stunden zuvor — wurden
|
||||
beide Fassungen mit den echten Werten gerendert und **die internen Ziele**
|
||||
verglichen, nicht nur unsere Anpassungen:
|
||||
|
||||
| | alloy 0.12.6 → 1.9.0 | kube-state-metrics 5.37.0 → 8.4.0 |
|
||||
|---|---|---|
|
||||
| Objekte | identisch | identisch |
|
||||
| Selektoren | identisch | identisch |
|
||||
| Dienst/Ports | unverändert | `targetPort 8080` → benannt `http`, selber Port |
|
||||
| RBAC | `nodes/proxy` → `nodes/pods` | `endpoints` → `endpointslices` |
|
||||
| Image | v1.7.5 → **v1.16.3** | v2.15.0 → **v2.20.0** |
|
||||
|
||||
`nodes/proxy` fällt weg — unsere alloy-Konfiguration benutzt es nicht (geprüft,
|
||||
nicht angenommen). Ergebnis nach dem Ausrollen: beide `Ready=True`, Pods laufen,
|
||||
und — der Punkt, der zählt — **die Metriken kommen weiter an**: `kube_node_info`
|
||||
und `kube_pod_container_info` 62 s alt, 56 Container-Serien. Ein Pod, der läuft,
|
||||
ist noch kein Exporter, der liefert.
|
||||
|
||||
**−4 CRITICAL** (alloy 2, config-reloader 1, kube-state-metrics 1), dazu
|
||||
`nginx:1.26-alpine` → `1.31.4-alpine` im Docs-Server (**−2**, gemessen 0/0).
|
||||
|
||||
### ⚠️ Ein Beiwagen wäre eine Stunde später still aus der Prüfung gefallen
|
||||
|
||||
Das alloy-Chart 1.x nagelt seinen `config-reloader` **per Digest** fest. Bei so
|
||||
einem Container führt `kube_pod_container_info` unter `image` nur noch den
|
||||
nackten `sha256:…`; die brauchbare Referenz steht allein in `image_spec` — und
|
||||
die Herleitung las `image`.
|
||||
|
||||
Zwei Schäden auf einmal, beide behoben und beide mit Gegenprobe abgesichert:
|
||||
|
||||
1. Der Beiwagen wäre **ungescannt** gewesen — genau das Loch, gegen das #0106
|
||||
gebaut wurde, wieder aufgerissen durch ein Upgrade statt durch Nachlässigkeit.
|
||||
2. Der nackte Digest rutschte durch die Normalisierung als Repository `sha256`
|
||||
mit dem Hex als Tag, landete in `targets.txt`, wäre nie ziehbar gewesen und
|
||||
hätte `cve_targets_missing` **dauerhaft** um eins erhöht — eine Lücke, die auf
|
||||
nichts zeigt.
|
||||
|
||||
**Gefunden durch Nachmessen, nicht durch Nachdenken.** Der Chart-Sprung war
|
||||
vorher geprüft, gerendert und verglichen; sichtbar wurde das erst, als die
|
||||
Zielmenge gegen den *laufenden* Cluster neu gebildet wurde.
|
||||
|
||||
### Haufen B: 27 Entscheidungen, 92 CVE-Kennungen
|
||||
|
||||
Die Abnahme verlangt „behoben **oder** Eintrag mit Begründung **und**
|
||||
Review-Datum". Umgesetzt als `monitoring/cve/entscheidungen.json`, nicht als
|
||||
`.trivyignore` — **eine bewusste Abweichung vom Wortlaut des Kriteriums**, mit
|
||||
Grund:
|
||||
|
||||
> Trivy ließe unterdrückte Befunde einfach weg. Danach sähe „0 CRITICAL, weil
|
||||
> behoben" **genauso aus** wie „0 CRITICAL, weil weggeschaut". Die Absicht des
|
||||
> Kriteriums — eine Entscheidung ist etwas, das man später wieder prüft — trägt
|
||||
> nur, solange die Befunde sichtbar bleiben.
|
||||
|
||||
Deshalb: jeder Befund bleibt in `trivy_vuln_info`; die Entscheidungen stehen
|
||||
daneben und werden **gezählt**. Neue Zahlen: `cve_critical_offen`,
|
||||
`cve_critical_entschieden`, `cve_entscheidungen_abgelaufen`,
|
||||
`cve_entscheidungen_ohne_befund`, `cve_entscheidungen_lesefehler`, dazu
|
||||
`cve_entscheidung_gueltig_bis` je Paar. Vier Alarmregeln, mit Regeltests.
|
||||
|
||||
Drei Eigenschaften, die nicht wegzukürzen sind:
|
||||
|
||||
- **CVE-Kennungen einzeln, keine Pauschale je Image.** Sonst verschluckte eine
|
||||
einmal getroffene Entscheidung auch jeden **neuen** Befund am selben Image.
|
||||
Der Lader weist einen Eintrag ohne Kennungen ab.
|
||||
- **Eine unlesbare Datei lässt alles als OFFEN zählen**, nicht als entschieden.
|
||||
Andersherum sähe ein Tippfehler aus wie „alles erledigt".
|
||||
- ⚠️ **Eine leere Soll-Menge ist nicht leer, sondern unbekannt.** Beim Bauen
|
||||
zuerst falsch herum: Fiel die Herleitung aus, ging `cve_critical_offen` auf 0
|
||||
— Entwarnung ausgerechnet im Ausfall. Aufgefallen erst beim
|
||||
Ende-zu-Ende-Lauf, nicht beim Lesen des eigenen Codes.
|
||||
|
||||
### Abnahmekriterien
|
||||
|
||||
| | Kriterium | Ergebnis |
|
||||
|---|---|---|
|
||||
| 1 | Kein CRITICAL auf laufendem Image ohne Entscheidung | ✅ **0 offen** von 92 auf 54 Zielen; **alle 54 gemessen**, keines unbekannt |
|
||||
| 2 | Haufen C entschieden, nicht gepatcht | ⚠️ **1 statt 0** — siehe unten |
|
||||
| 3 | Am Dashboard ablesbar | ⚠️ **noch nicht** — siehe unten |
|
||||
| 4 | Die Methode steht als Runbook | ✅ `docs/wiki/admin/cve-durchgang.md` |
|
||||
| 5 | Kein Suppress ohne Ablauf | ✅ 27 von 27 Einträgen mit Pruefdatum, per Test und per Alarm erzwungen |
|
||||
|
||||
**Zu 2:** Übrig bleibt **ein** CRITICAL auf einem Image, das nirgends läuft:
|
||||
`axion-backup:v1`. Das ist kein Rest der Aufräumarbeit, sondern Absicht — die
|
||||
Vorgängerfassung ist das **Rückfallziel** zu v2 und gehört deshalb geprüft. Die
|
||||
62 aus Gate 1 sind weg. Das Kriterium war zu scharf formuliert; die Abweichung
|
||||
steht hier, statt die Zahl passend zu rechnen.
|
||||
|
||||
**Zu 3:** Die Anlage scannt **einmal am Tag**, die Herleitung läuft stündlich.
|
||||
Nach einer Update-Welle hängen die Zahlen also bis zu 24 h hinterher: alte
|
||||
Berichte melden weiter (`cve_targets_orphaned`), neue Ziele haben noch keinen
|
||||
(`cve_targets_missing`). Beides **meldet sich selbst** — genau dafür sind die
|
||||
Regeln aus #0106 da. Die Zahlen oben sind deshalb gegen den **laufenden**
|
||||
Bestand gerechnet: Zielmenge live aus Cluster und Betriebs-Host neu gebildet,
|
||||
Befunde aus der Anlage plus den lokalen Vorab-Scans der noch ungescannten
|
||||
Ziele. ⚠️ Ohne diese Handrechnung wären die sechs CRITICAL in Synapse v1.158
|
||||
**unbemerkt geblieben** — die Anlage hält noch den Bericht zu v1.151.
|
||||
|
||||
### Was der Durchgang gebracht hat
|
||||
|
||||
| Posten | CRITICAL | HIGH |
|
||||
|---|---|---|
|
||||
| Authentik 2026.2.3 → 2026.8.0 | −22 | −456 |
|
||||
| cert-manager v1.14.0 → v1.21.1 (7 Stufen) | −8 | −104 |
|
||||
| Flux → v2.9.4-Satz | −14 | −183 |
|
||||
| ESS 26.4.0 → 26.8.0 | −11 | −97 |
|
||||
| alloy, kube-state-metrics, config-reloader, nginx | −6 | — |
|
||||
| Haufen C aus der Zielmenge (#0106) | −61 | — |
|
||||
| Betriebs-Stack + Python-Basis **(ausstehend)** | −18 | −278 |
|
||||
|
||||
⚠️ **Die letzte Zeile wirkt erst nach dem Ausrollen auf dem Betriebs-Host.**
|
||||
Diese 18 CRITICAL stehen als `art: geplant` mit Pruefdatum **2026-08-28** in der
|
||||
Entscheidungsdatei — bleibt das Ausrollen aus, meldet sich
|
||||
`CveEntscheidungAbgelaufen`. Die Entscheidung verfällt, nicht die Erinnerung.
|
||||
|
||||
### Nicht erreicht, ausdrücklich
|
||||
|
||||
- **HIGH.** Dieser Durchgang war CRITICAL-first, so beschlossen in Gate 1. Der
|
||||
Bestand ist im Zuge der Updates von 2688 auf rund 1500 gefallen, aber das ist
|
||||
Beifang, keine Bearbeitung.
|
||||
- **Die k3s-Komponenten.** 15 CRITICAL auf sechs `rancher/*`-Images sind
|
||||
entschieden, nicht behoben: sie kommen mit k3s und gehen nur mit einem
|
||||
k3s-Upgrade. Pruefdatum 2026-09-21.
|
||||
- **Eigene Images.** `clamav-http-scanner:v1.0.0` und `axion-backup` tragen
|
||||
Befunde, die ein Neubau auf schlankerer Basis wegnimmt — dieselbe Umstellung,
|
||||
die die drei Python-Dienste heute auf alpine gebracht hat. Als `geplant`
|
||||
vermerkt, nicht als erledigt behauptet.
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
type: issue
|
||||
id: "0051"
|
||||
status: in-progress
|
||||
status: done
|
||||
created: 2026-08-14
|
||||
milestone: M5
|
||||
priority: high
|
||||
area: security
|
||||
related: [docs/issues/0025-deploy-uebergabe-cve-alarme-aggregiert-receiver.md, docs/aar/2026-08-01-cve-pipeline-gitops47.md, docs/issues/0106-cve-scan-deckt-nur-die-haelfte-zielliste-ist-handgepflegt.md, docs/design/2026-08-21-cve-remediation.md]
|
||||
related: [docs/issues/0025-deploy-uebergabe-cve-alarme-aggregiert-receiver.md, docs/aar/2026-08-01-cve-pipeline-gitops47.md, docs/issues/0106-cve-scan-deckt-nur-die-haelfte-zielliste-ist-handgepflegt.md, docs/design/done/2026-08-21-cve-remediation.md]
|
||||
gitlab_iid: "37"
|
||||
---
|
||||
# CVE-Remediation-Pass: Schwachstellen-Report abarbeiten
|
||||
@@ -61,3 +61,17 @@ harmloseren.
|
||||
betrieben — er steht nur in der Zielmenge, weil die Registry-Auswahl „die
|
||||
letzten drei Fassungen je Repo" nimmt und das Repo nur zwei hat. Ein
|
||||
Registry-Aufräumen wäre hier die billigere Antwort als ein Update.
|
||||
|
||||
## Abgeschlossen 2026-08-21
|
||||
|
||||
**0 CRITICAL ohne Entscheidung** auf 54 Zielen, alle 54 gemessen. 92 CVE-Kennungen
|
||||
in 27 Entscheidungen mit Begruendung und Pruefdatum; der Rest ueber Updates
|
||||
behoben (Authentik, cert-manager, Flux, ESS, alloy, kube-state-metrics, nginx,
|
||||
Betriebs-Stack). Gate 5 samt der beiden nicht sauber erreichten Kriterien:
|
||||
[Entwurf](../design/done/2026-08-21-cve-remediation.md). Methode als Runbook:
|
||||
[CVE-Durchgang](../wiki/admin/cve-durchgang.md).
|
||||
|
||||
⚠️ **Die letzten 18 CRITICAL wirken erst nach dem Ausrollen auf dem
|
||||
Betriebs-Host** (`516641b`, `44cc030`, `422b651`). Sie stehen als `art: geplant`
|
||||
mit Pruefdatum 2026-08-28 in der Entscheidungsdatei — bleibt das Ausrollen aus,
|
||||
meldet sich `CveEntscheidungAbgelaufen`.
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
type: ledger
|
||||
date: 2026-08-21
|
||||
size: L
|
||||
status: open
|
||||
status: closed
|
||||
related:
|
||||
- "docs/design/2026-08-21-cve-remediation.md"
|
||||
- "docs/design/done/2026-08-21-cve-remediation.md"
|
||||
- "docs/issues/0051-cve-remediation-pass.md"
|
||||
- "docs/aar/2026-08-21-spiegel-ausfall.md"
|
||||
---
|
||||
@@ -26,6 +26,7 @@ Nachfrage erfuellt wurde (`docs/wiki/stolpersteine/aar-pflicht-ohne-werkzeug.md`
|
||||
| 1 | 24ae5b9 | sorb | DONE | Drei Haufen statt eines Vorhabens; Reichweite Haufen C = einengen auf Betriebenes. |
|
||||
| 2 | 80ee448 | sorb | DONE | Gestufter Authentik-Weg belegt; die Pflicht-Zwischenstufe traegt den ganzen CRITICAL-Gewinn. |
|
||||
| 3+4 | 70823b4 | sorb | DONE | Zusammengelegt (eine Datei, eine Zeile, keine Signaturen); Fund: Flux haette selbsttaetig zurueckgerollt. |
|
||||
| 5 | 669e24c | sorb | DONE_WITH_CONCERNS | 0 CRITICAL ohne Entscheidung auf 54 gemessenen Zielen; ⚠️ Kriterium 2 endet bei 1 statt 0 und Kriterium 3 haengt bis zur naechsten Scan-Runde nach - beides im Entwurf begruendet statt passend gerechnet. |
|
||||
|
||||
## Slices
|
||||
|
||||
@@ -41,6 +42,9 @@ Nachfrage erfuellt wurde (`docs/wiki/stolpersteine/aar-pflicht-ohne-werkzeug.md`
|
||||
| Flux | fcf3169 | DONE | Vier Controller auf den v2.9.4-Satz; 14 CRITICAL -> 0, 231 HIGH -> 48. |
|
||||
| Betriebs-Stack | 516641b | DONE_WITH_CONCERNS | Fuenf Fassungszeilen, -14 CRITICAL / -278 HIGH; ⚠️ wirkt erst nach Ausrollen auf dem Betriebs-Host. |
|
||||
| ESS 26.8.0 | 07ffd0e, 533fcde | DONE | Alle acht Abnahmepunkte belegt, inkl. Call gegen LiveKit v1.12.0 und EICAR-Abweisung; ⚠️ Anmelde-Ausfall durch eigene Netzregel, eigener AAR. |
|
||||
| alloy + kube-state-metrics + nginx | 6cd6ee6 | DONE | Beide Chart-Bereiche waren Decken, nicht Aktualitaet; vorher gerendert und interne Ziele verglichen, nachher Metrik-Frische geprueft. -6 CRITICAL. |
|
||||
| Entscheidungen | 44cc030, 422b651 | DONE | 27 Eintraege / 92 CVE-Kennungen, 15 Zusicherungen + 4 Alarmregeln mit Regeltests; ⚠️ bewusst KEINE Trivy-Ignore-Datei, Abweichung im Entwurf begruendet. |
|
||||
| Digest-Luecke | d5e2995 | DONE | Ein per Digest festgenagelter Beiwagen waere still aus der Zielmenge gefallen - gefunden beim Nachmessen, eine Stunde nach dem Chart-Sprung, der ihn hereinbrachte. |
|
||||
|
||||
## Ladder
|
||||
|
||||
@@ -57,13 +61,18 @@ Nachfrage erfuellt wurde (`docs/wiki/stolpersteine/aar-pflicht-ohne-werkzeug.md`
|
||||
| ob die neueste Fassung wirklich die beste ist, bevor sie gesetzt wird | Grafana 13.2.0 raeumt 7 CRITICAL ab, treibt HIGH aber 70 -> 162; 12.4.9 macht 7 -> 1 und 70 -> 3 | reused: die 12er-Reihe statt des Major-Sprungs — gemessen, nicht nach Nummer gewaehlt | 516641b |
|
||||
| ein Manifest fuer genau unseren Flux-Komponentensatz, statt das Release-Manifest zu nehmen | `install.yaml` traegt 7 Deployments, wir betreiben 4 — das CLI erzeugt den passenden Satz | reused: `flux install --export --components=...` statt Handfilterung von 270 kB YAML | fcf3169 |
|
||||
| eine Quelle fuer die Einengung von Haufen C, statt einer Ausschlussliste | die Herleitung bildet den laufenden Bestand ohnehin | reused: dieselbe Menge als Filter — keine zweite Liste (ADR-0026) | 4758e35 |
|
||||
| ob Trivy Ausnahmen mit Ablaufdatum selbst kann, bevor etwas Eigenes entsteht | `.trivyignore.yaml` kennt `statement` und `expired_at` - genau die zwei geforderten Felder | built: trotzdem etwas Eigenes. Trivy LOESCHT unterdrueckte Befunde aus dem Bericht, danach ist "0, weil behoben" von "0, weil weggeschaut" nicht mehr zu unterscheiden. Die Absicht des Kriteriums traegt nur mit sichtbaren Befunden. | 44cc030 |
|
||||
| ein Format fuer die Entscheidungen, das der Exporter lesen kann | PyYAML gibt es im Exporter-Image nicht (stdlib-only, python:3.13-alpine) - JSON schon | reused: `json` aus der stdlib statt einer neuen Abhaengigkeit; die Randbedingung hat das Format entschieden, nicht der Geschmack | 44cc030 |
|
||||
| ob die beiden Chart-Bereiche wirklich aktuell sind, statt es anzunehmen | `0.x` deckelt bei Chart 0.12.6 (App v1.7.5), `5.x` bei 5.37.0 (App 2.15.0); aktuell sind 1.9.0 und 8.4.0 | reused: der Pin-Stil, den alle 20 uebrigen Releases dieses Repos schon haben - kein neues Muster, sondern das Ende einer Ausnahme | 6cd6ee6 |
|
||||
| welche internen Ziele ein Chart-Sprung verschiebt, DIESMAL vorher | beide Renderings verglichen: Objekte und Selektoren gleich, `targetPort` benannt statt beziffert, RBAC endpoints -> endpointslices | reused: `helm template` - dieselbe Methode wie beim ESS-Sprung, aber mit der Frage, die dort gefehlt hat | 6cd6ee6 |
|
||||
|
||||
## Notes
|
||||
|
||||
**Gate 5 steht aus und hat deshalb KEINE Zeile.** Die Vorlage sagt „one row per
|
||||
gate as it closes" — eine Zeile fuer ein nicht geschlossenes Gate waere eine
|
||||
Behauptung ohne Commit, und genau das faengt der Richter ab. Was fehlt: Haufen B
|
||||
(68 CRITICAL ohne Fix-Version, auf acht Images) und der Rest von Haufen A.
|
||||
**Gate 5 geschlossen.** Haufen B ist nicht gepatcht, sondern entschieden: 27
|
||||
Eintraege mit Begruendung und Pruefdatum, 92 CVE-Kennungen. Der Rest von Haufen A
|
||||
ist gefahren; was im Repo liegt, aber noch nicht ausgerollt ist, steht als
|
||||
`art: geplant` mit kurzem Datum drin und meldet sich selbst, wenn es liegen
|
||||
bleibt.
|
||||
|
||||
⚠️ **Der erste Commit der Haufen-C-Einengung war ungetestet, und die Gegenprobe
|
||||
hat es gefangen.** Nach dem Abschalten des Filters blieben alle 22 Zusicherungen
|
||||
@@ -100,3 +109,23 @@ Vormittag noch direkt auf `synapse-main` zeigte. ESS 26.8.0 stellte den Endpunkt
|
||||
auf haproxy um. Beide Renderings lagen mir vor — ich hatte sie nur auf unsere
|
||||
Anpassungen hin verglichen, nicht auf verschobene interne Ziele. Eigener AAR:
|
||||
`docs/aar/2026-08-21-mas-haproxy-netzregel.md`.
|
||||
|
||||
⚠️ **Zwei Kriterien sind NICHT sauber erreicht, und das steht so im Entwurf.**
|
||||
Kriterium 2 endet bei 1 statt 0 (`axion-backup:v1` laeuft nirgends, ist aber
|
||||
absichtlich als Rueckfallziel in der Menge), Kriterium 3 haengt bis zur
|
||||
naechsten Scan-Runde nach. Beides waere leicht wegzurechnen gewesen - die Zahl
|
||||
passend zu definieren ist in diesem Projekt die teurere Gewohnheit.
|
||||
|
||||
⚠️ **Die Zahlen des Abschlusses sind von Hand gegen den LAUFENDEN Bestand
|
||||
gerechnet**, nicht aus der Anlage abgelesen: Zielmenge live neu gebildet,
|
||||
Befunde aus der Anlage plus den lokalen Vorab-Scans. Ohne das waeren die sechs
|
||||
CRITICAL in Synapse v1.158 unbemerkt geblieben - die Anlage haelt noch den
|
||||
Bericht zu v1.151. Ein Werkzeug, das nur einmal am Tag misst, ist am Tag der
|
||||
Aenderung das schlechteste Auskunftsmittel ueber diesen Tag.
|
||||
|
||||
⚠️ **Der Beiwagen-Fund gehoert in die Reihe der eigenen Fehlerklassen.** #0106
|
||||
wurde gebaut, damit nichts mehr still aus der Pruefung faellt. Vier Stunden
|
||||
spaeter hat ein Chart-Sprung genau das wieder erzeugt - nicht durch
|
||||
Nachlaessigkeit, sondern weil eine Upstream-Entscheidung (Digest statt Tag) die
|
||||
Form der Daten aenderte. Eine Herleitung ist kein Dauerzustand; sie ist eine
|
||||
Annahme ueber fremde Datenformate.
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
---
|
||||
type: wiki-page
|
||||
area: admin
|
||||
related:
|
||||
- "docs/issues/0051-cve-remediation-pass.md"
|
||||
- "docs/adr/0026-pruefziele-werden-abgeleitet-nicht-gepflegt.md"
|
||||
---
|
||||
|
||||
# Runbook: einen CVE-Durchgang machen
|
||||
|
||||
Wie ein Durchgang durch den Schwachstellen-Bestand abläuft, damit der nächste
|
||||
nicht wieder bei der Sortierung anfängt. Aufgeschrieben nach dem ersten
|
||||
vollständigen Durchgang am 2026-08-21 (#0051), 245 CRITICAL am Anfang.
|
||||
|
||||
## 0. Die eine Regel
|
||||
|
||||
⚠️ **Vor jedem Update das Zielimage scannen.** Das ist der Unterschied zwischen
|
||||
„ein Update hilft vermutlich" und einer Zahl. Am 2026-08-21 hat diese eine
|
||||
Gewohnheit **drei** Updates verhindert, die den Bestand verschlechtert hätten:
|
||||
|
||||
| Kandidat | erwartet | gemessen |
|
||||
|---|---|---|
|
||||
| Wiki.js `2.5` → `2.5.277` | besser | **12 → 40 CRITICAL** |
|
||||
| Grafana 12 → 13.2.0 | besser | CRITICAL 7 → 0, aber **HIGH 70 → 162** |
|
||||
| cAdvisor v0.49.1 → v0.55.1 | 0 | 5 → 4 |
|
||||
|
||||
Der Aufruf, wie ihn die Anlage selbst macht:
|
||||
|
||||
```sh
|
||||
docker run --rm -v "$PWD/trivycache:/root/.cache" aquasec/trivy:0.74.0 \
|
||||
image --scanners vuln --format json --quiet <image> > ziel.json
|
||||
```
|
||||
|
||||
## 1. Bestand aufnehmen und in drei Haufen teilen
|
||||
|
||||
„Remediation-Pass" ist keine Aufgabe, sondern drei. Die Trennung ist das
|
||||
eigentliche Werkzeug:
|
||||
|
||||
| | was es ist | welche Arbeit |
|
||||
|---|---|---|
|
||||
| **A** | CRITICAL mit verfügbarer Fix-Fassung | ein Aktualisierungs-Vorhaben |
|
||||
| **B** | CRITICAL ohne Fix-Fassung | je Fall eine **Entscheidung** |
|
||||
| **C** | CRITICAL auf Images, die nirgends laufen | **Reichweite**, nicht Patchen |
|
||||
|
||||
⚠️ **Haufen C ist eine Falle.** Der Reflex ist, sie zu patchen. Richtig ist zu
|
||||
fragen, warum sie überhaupt geprüft werden. Am 2026-08-21 waren das 62 CRITICAL
|
||||
auf drei Bau-Artefakten — verschwunden, ohne dass ein einziger Fix nötig war,
|
||||
indem die Zielmenge auf Betriebenes eingeengt wurde
|
||||
([ADR-0026](../../adr/0026-pruefziele-werden-abgeleitet-nicht-gepflegt.md)).
|
||||
|
||||
⚠️ **„Behebbar" ist enger, als die Zahl behauptet.** Eine Fix-Fassung im Paket
|
||||
heißt nicht, dass es ein Image damit gibt. Draupnir v3.1.0 trägt fünf Befunde
|
||||
mit Fix-Fassung — und v3.1.0 ist die neueste Release. Solche Fälle gehören zu
|
||||
**B**, obwohl der Scanner sie zu A zählt.
|
||||
|
||||
Nützliche Abfragen:
|
||||
|
||||
```promql
|
||||
sort_desc(count by (target) (trivy_vuln_info{severity="CRITICAL"}))
|
||||
count by (quelle) (cve_target_desired)
|
||||
cve_critical_offen
|
||||
```
|
||||
|
||||
## 2. Haufen A: aktualisieren, gestuft
|
||||
|
||||
1. **Den dokumentierten Weg suchen, bevor gesprungen wird.** Authentik verlangt
|
||||
die Reihenfolge der Major-Releases, cert-manager „one minor at a time".
|
||||
Beides stand in der Anleitung; beides hätte ein Sprung verletzt.
|
||||
2. **Bruchstellen gegen den eigenen Bestand prüfen**, nicht fürchten. Am
|
||||
2026-08-21 waren 5 von 5 gegenstandslos — geprüft in Minuten, gefürchtet
|
||||
hätten sie einen Tag gekostet.
|
||||
3. ⚠️ **Prüfen, ob Flux beim Fehlschlag etwas Eigenes tut.**
|
||||
`upgrade.remediation.strategy` steht per Vorgabe auf `rollback`, und mit
|
||||
`retries > 0` ist auch die letzte Rückrollung scharf. Für die Dauer eines
|
||||
gestuften Sprungs `retries: 0` setzen und danach zurückstellen — sonst rollt
|
||||
Flux mitten in der Treppe zurück und die Stufen zählen nicht mehr.
|
||||
4. ⚠️ **Nicht auf Vorrat pushen.** Liegt die Ausrollstrecke, wendet Flux nach
|
||||
der Erholung nur den **letzten** Commit an und überspringt Zwischenstufen.
|
||||
Erst ausrollen und prüfen, dann die nächste Stufe pushen
|
||||
([AAR Spiegel-Ausfall](../../aar/2026-08-21-spiegel-ausfall.md)).
|
||||
5. ⚠️ **Vor einem Chart-Sprung vergleichen, welche internen Ziele sich
|
||||
verschieben** — nicht nur, ob die eigenen Anpassungen überleben. Beide
|
||||
Fassungen mit den echten Werten rendern und Dienstnamen, Selektoren und
|
||||
Ports gegeneinanderhalten. Genau das wurde beim ESS-Sprung versäumt und hat
|
||||
die Anmeldung gekostet
|
||||
([AAR MAS/haproxy](../../aar/2026-08-21-mas-haproxy-netzregel.md)).
|
||||
|
||||
⚠️ **Ein schwebender Fassungsbereich ist eine Decke, keine Aktualität.**
|
||||
`version: "0.x"` sieht aus wie „bleibt aktuell" und hält in Wahrheit unter dem
|
||||
nächsten Major fest. Am 2026-08-21 waren genau die **zwei** Releases mit einem
|
||||
Bereich die zwei, die zurückgefallen waren — alle fest gepinnten waren aktuell,
|
||||
weil eine feste Nummer sichtbar veraltet.
|
||||
|
||||
## 3. Haufen B: entscheiden, nicht verstecken
|
||||
|
||||
Jeder Fall bekommt einen Eintrag in `monitoring/cve/entscheidungen.json` im
|
||||
Betriebs-Repo:
|
||||
|
||||
```json
|
||||
{ "ziel": "coturn/coturn:4.17.2", "art": "hingenommen",
|
||||
"grund": "4.17.2 ist die neueste veroeffentlichte Fassung ...",
|
||||
"pruefen_am": "2026-11-21", "cves": ["CVE-...", "..."] }
|
||||
```
|
||||
|
||||
- `art`: `hingenommen` (es gibt nichts zu tun) oder `geplant` (die Arbeit steht
|
||||
aus). Ein `geplant` bekommt ein **kurzes** Datum.
|
||||
- `cves` **einzeln**, nie pauschal je Image — eine Pauschale verschluckt auch
|
||||
jeden neuen Befund an demselben Image. Der Lader weist einen Eintrag ohne
|
||||
Kennungen ab.
|
||||
- `grund` sagt, **warum es nichts zu tun gibt**, mit der Messung dahinter.
|
||||
„siehe oben" ist keine Begründung; der Test verlangt Substanz.
|
||||
|
||||
⚠️ **Bewusst keine Trivy-Ignore-Datei.** Trivy ließe die Befunde einfach weg —
|
||||
dann sähe „0 CRITICAL, weil behoben" genauso aus wie „0 CRITICAL, weil
|
||||
weggeschaut". Entschieden heißt **gezählt, nicht versteckt**: die Befunde
|
||||
bleiben in `trivy_vuln_info`, und `cve_critical_offen` zählt, was noch niemand
|
||||
angesehen hat.
|
||||
|
||||
## 4. Abschließen
|
||||
|
||||
- `cve_critical_offen` muss **0** sein.
|
||||
- `cve_entscheidungen_abgelaufen` muss **0** sein.
|
||||
- Vorher/Nachher mit Datum in den Abschluss, und **die Verengung benennen**:
|
||||
Dieser Durchgang war CRITICAL-first. HIGH ist kein Vorhaben, sondern eine
|
||||
Kategorie, und bekommt einen eigenen.
|
||||
- ⚠️ Nach einer Update-Welle hängen die Zahlen bis zu **24 Stunden**
|
||||
hinterher: die Scan-Runde läuft einmal am Tag, die Herleitung stündlich.
|
||||
Bis dahin melden `cve_targets_orphaned` und `cve_targets_missing` — das ist
|
||||
der Übergang, nicht ein Schaden.
|
||||
|
||||
## Was diesen Durchgang teuer gemacht hat
|
||||
|
||||
Nicht die CVEs. Teuer waren: eine Ausrollstrecke, die ihren Stillstand nicht
|
||||
meldet ([#0109](../../issues/0109-der-weg-vom-commit-ins-cluster-meldet-seinen-stillstand-nicht.md)),
|
||||
eine Netzregel, die ein Chart-Sprung überholt hat
|
||||
([#0108](../../issues/0108-erlaubnisliste-veraltet-still-wenn-das-chart-die-verdrahtung-ver.md)),
|
||||
und drei Einrückungen, die ich angenommen statt gemessen habe. Wer den nächsten
|
||||
Durchgang macht, verliert die Zeit an derselben Sorte Sache — nicht an Trivy.
|
||||
+1
-1
@@ -15,7 +15,7 @@ mit Inhalt. Projektfassung des neckbeard-Index (Original:
|
||||
|
||||
| Area | Enthält | Stand |
|
||||
|---|---|---|
|
||||
| `admin/` | Betrieb: [cfgmon](admin/cfgmon.md) · [game](admin/game.md) · [matrix](admin/matrix.md) · [overmind](admin/overmind.md) · [Refinement & Retro](admin/refinement.md) · [Stillstandsprüfung](admin/stillstandspruefung.md) · [Textbausteine](admin/textbloecke.md) | belegt |
|
||||
| `admin/` | Betrieb: [cfgmon](admin/cfgmon.md) · [game](admin/game.md) · [matrix](admin/matrix.md) · [overmind](admin/overmind.md) · [CVE-Durchgang](admin/cve-durchgang.md) · [Refinement & Retro](admin/refinement.md) · [Stillstandsprüfung](admin/stillstandspruefung.md) · [Textbausteine](admin/textbloecke.md) | belegt |
|
||||
| `deployment/` | [Deploy-Übergabe](deployment/deploy-uebergabe.md) (Definition of Done, Kanonisierungs-Verfahren) · [Wiederherstellung](deployment/restore.md) (Restore-Ablauf Matrix-Plattform) | belegt |
|
||||
| `architecture/` | [Mirror-Topologie](architecture/mirror-topologie.md) · [Lab-Netz](architecture/lab-netzwerk.md) · [DNS-Zone](architecture/zone-axion1337.md) · [Branding](architecture/branding.md) | belegt |
|
||||
| `vision/` | Eine Datei je Linie: [axion1337.chat](vision/axion1337-chat.md) · [Homelab](vision/homelab.md) · [ThreadNet](vision/threadnet.md) | belegt |
|
||||
|
||||
Reference in New Issue
Block a user