Files
management/verfahren/aar/2026-08-01-cve-pipeline-gitops47.md
T
Thore CimbalandClaude Opus 5 3e81f40178 verfahren: Deploy-Uebergabe als Standardverfahren, AAR zu gitops#47
Nach dem Deploy der CVE-Pipeline (gitops#47) als Verfahren festgehalten. Der
Stand war korrekt und gelintet; der Blocker entstand erst aus der Datenmenge,
gegen die er lief -- eine Alarm-Instanz pro CVE, real 126 CRITICAL und 1222
HIGH. So etwas faellt in keinem Diff auf, nur beim Messen vor dem Deploy.

Neu:
- .gitea/ISSUE_TEMPLATE/deploy-uebergabe.yaml -- Uebergabe-Issue mit
  Pflichtfeldern Mengengeruest, vollstaendiges Deploy-Kommando, Verifikation
  im laufenden Dienst, Aussenwirkung samt Not-Aus, Rollback
- verfahren/deploy-uebergabe.md -- Ablauf und Pruefliste
- verfahren/aar-vorlage.md -- AAR-Vorlage
- verfahren/aar/2026-08-01-cve-pipeline-gitops47.md -- der ausloesende AAR

Abgrenzung im README ergaenzt: hosts/ und shared/ halten offene Punkte,
verfahren/ haelt, wie wir arbeiten. Die Uebergabe-Issues laufen bewusst hier
statt im Projekt-Repo, weil das Verfahren repo-uebergreifend gilt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-01 12:00:00 +00:00

4.3 KiB

AAR — CVE-Pipeline gitops#47

Datum: 2026-08-01 · Host/Stack: CFGMON, /opt/threadnet-operating/monitoring Auftrag: Deploy eines gebauten, als UNGETESTET übergebenen Stands (Trivy-Scanner, Exporter, Alert-Regeln, Grafana-Dashboard)

1. Ergebnis

Live und verifiziert: Scanner (29/29 Images gescannt), Exporter, Prometheus-Job cve_exporter, Regelgruppe axion-cve, Grafana-Ordner Security mit CVE-Dashboard.

Bewusst nicht live: die Alarm-Zustellung nach Matrix. room="security" routet in alertmanager.yml auf einen Null-Receiver (Commit 2b715ca in sorb/threadnet-operating). Grund siehe Befund 1.

2. Befunde

# Befund Schwere Status
1 Eine Matrix-Nachricht pro CVE. 126 CRITICAL landen in einer Alertmanager-Gruppe, nach 24 h kommen 1222 HIGH dazu. Dazu steht save_state() in do_POST hinter der Sende-Schleife: bricht ein Send ab (Synapse rate-limitet nach ~10 mit 429), wird kein State gespeichert, der Receiver antwortet 502, Alertmanager wiederholt die komplette Gruppe — mit leerer Deduplizierung HIGH abgefangen, gitops#51
2 docker compose up -d aktiviert geänderte Configs nicht. Einzeldatei-Mounts hängen am Inode, git pull benennt um. Prometheus lief nach dem Deploy mit alten Regeln — promtool fand 9, Prometheus kannte 6, kein Fehler im Log MEDIUM behoben via --force-recreate, gitops#52
3 TrivyScanStale kann ein nie erfolgreich gescanntes Image nicht melden — ohne ersten Report existiert keine Serie, an der time() - trivy_last_scan_timestamp hängen könnte LOW notiert in gitops#51
4 Der Exporter prunt den First-Seen-State bei jedem Scrape. Ein transienter Lesefehler (except: continue) löscht die Erstfund-Zeitstempel des Targets dauerhaft LOW notiert in gitops#51
5 Grafana-Provisioning für den Security-Ordner fehlte — das Dashboard wäre nie erschienen vom Autor selbst behoben (cdfadc0), bevor ausgerollt wurde

Gemessene Gesamtlage über alle 29 Images: 126 CRITICAL, 1222 HIGH, 2710 MEDIUM, 1316 LOW. Spitzenreiter goauthentik/server:2026.2.3 mit 369 CRITICAL+HIGH.

3. Verdachtsfälle mit Entwarnung

Vermutung Messung Ergebnis
Exporter parst 29 JSONs je Scrape → Timeouts bei 15 s Intervall collect() gegen echte Reports 0,4 s für 29 Reports, ~3100 Zeilen — unkritisch
Private Registry rohana.axion1337.de braucht Credentials für Trivy Anonymer Pull zieht anonym, keine Credentials nötig
Zwei down-Targets könnten Folge des Deploys sein avg_over_time(up[3h]) 0.00 — schon 3 h vorher tot, in hosts/game.md erfasst

promtool check rules, amtool check-config, amtool config routes test, docker compose config und py_compile liefen alle sauber.

4. Was die Befunde ermöglicht hat

Befund 1 wäre in keinem Lint aufgefallen — der Code ist korrekt, das Problem entsteht erst aus der Datenmenge, gegen die er läuft. Sichtbar wurde er durch Messen vor dem Deploy: Trivy lokal über drei repräsentative Images ergab 27 CRITICAL / 126 HIGH auf 3 von 29, also die richtige Größenordnung. Die spätere Realität (126 CRITICAL) bestätigte die Entscheidung. amtool config routes test belegte danach, dass die Stummschaltung nur room=security trifft und den normalen Alarmweg unangetastet lässt.

Befund 2 wurde nur sichtbar, weil die Config im Container geprüft wurde (docker exec prometheus grep …) statt auf der Platte. Auf der Platte sah alles richtig aus, up -d meldete Running, und ein SIGHUP-Reload lud klaglos den alten Inhalt.

Diese beiden Punkte sind als Verfahren festgehalten: ../deploy-uebergabe.md.

5. Offen

Richtungsentscheidung zu gitops#51, bevor die Alarme scharf gehen: entweder matrix-alerts.py auf eine Sammelnachricht pro Webhook-Batch umbauen (die fünf Pflichtfelder je CVE als eine Zeile, bleibt vollständig), oder die Regeln auf count by (target, severity) aggregieren und die CVE-Details im Dashboard lassen. In beiden Fällen zusätzlich: State inkrementell speichern, 429 mit Retry-After behandeln. Danach die room="security"-Route entfernen.

Nebenbefund ohne Handlungsbedarf von hier: coturn/coturn:latest ist das einzige ungepinnte Image (bereits in gitops#47 notiert).