Files
management/docs/wiki/admin/cve-durchgang.md
T
Thore Cimbal cdcb33fb4c 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.
2026-08-21 12:00:00 +00:00

6.4 KiB

type, area, related
type area related
wiki-page admin
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.52.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:

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).

⚠️ „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:

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).
  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).

⚠️ 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:

{ "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), eine Netzregel, die ein Chart-Sprung überholt hat (#0108), 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.