The handover issue still sat in waiting while the deploy had long landed: ff87cb2 is an ancestor of HEAD (CFGMON now runs e9c13dc), the rules aggregate per image so the per-CVE flood is structurally impossible, matrix-alerts.py saves state incrementally inside the send loop, and notifications_failed_total is 0 across 80 series. The null-receiver kill switch is gone. Recorded honestly what was not observed: whether aggregated messages actually arrived in the security room once. Delivery is now permanently monitored via AlertDeliveryFailing, so a future failure reports itself instead of relying on someone looking. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
5.7 KiB
type, id, status, created, milestone, priority, area, gitlab_iid, related
| type | id | status | created | milestone | priority | area | gitlab_iid | related | |
|---|---|---|---|---|---|---|---|---|---|
| issue | 0025 | done | 2026-08-01 | M1 | medium | infrastructure | 25 |
|
Deploy-Übergabe: CVE-Alarme aggregiert + Receiver-Robustheit (gitops#51, ff87cb2)
Import aus management#25 (2026-08-11). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei (ADR-0012).
Stand
threadnet-operating ff87cb2 (git.lab; Gitea-Mirror folgt — auf CFGMON vorher git fetch && git reset --hard origin/main, der gerettete Kollegen-Commit heißt jetzt 0bd77e2)
Testtiefe
ungetestet — Lints grün (promtool 9 Regeln, amtool, py_compile), kein Laufzeittest
Mengengerüst
Erwartete Matrix-Nachrichten beim Scharfschalten: eine pro Image mit CRITICAL-Funden, obere Schranke 29 (gemessen an 14 Images hatten die meisten CRITICALs → realistisch ~15–25 Nachrichten, je 1 s gedrosselt ≈ unter 30 s). HIGH-Alarme folgen frühestens nach 24 h (for: 24h), gleiche Schranke. Danach nur Deltas (neue Images/Severity-Wechsel) und ✅-Edits. Kein Pro-CVE-Verkehr mehr: Regeln sind count by (target, target_type, host), die ~1200 Einzelserien erzeugen keine Alarme mehr (bleiben aber als trivy_vuln_info fürs Dashboard).
Vollständiges Deploy-Kommando
cd /opt/threadnet-operating && git fetch && git reset --hard origin/main && cd monitoring && docker compose up -d --force-recreate matrix-alerts && docker compose exec prometheus kill -HUP 1 && docker compose exec alertmanager kill -HUP 1
(reset --hard wegen Hash-Wechsel 2b715ca→0bd77e2; force-recreate lädt das ro-gemountete Receiver-Skript neu; HUPs laden Regeln/Route ohne Neustart)
Woran erkennt man, dass es wirklich greift
docker compose logs matrix-alerts --since 5m— keine Fehler, keine 502-Schleife- Security-Raum: binnen ~2 min (group_wait 1m) trudeln die aggregierten 🔴-Nachrichten „Image X: N CRITICAL-CVEs" einzeln im Sekundentakt ein — gezählt ≤ 29, keine Pro-CVE-Flut
curl -s localhost:9090/api/v1/rules | grep -c TrivyCriticalVulns→ 1 (neue Regel geladen)- Alertmanager-Retry-Probe: Log darf nach Abschluss der Zustellung keine wiederholten identischen Batches zeigen
Außenwirkung und Not-Aus
Außenwirkung: nur der Security-Matrix-Raum (interner Kreis). Not-Aus: in monitoring/alertmanager/alertmanager.yml die Route room="security" wieder auf einen "null"-Receiver biegen (Muster steht in der Git-Historie, Commit 0bd77e2) + docker compose exec alertmanager kill -HUP 1 — wirkt sofort, Pipeline läuft weiter.
Rollback
git revert ff87cb2 (ein Commit, betrifft nur alerts.yml/alertmanager.yml/matrix-alerts.py) + dieselben drei Kommandos wie beim Deploy. State-Datei ist abwärtskompatibel (neues Format kapselt das alte unter alerts).
Bewusst offen gelassen
- Grafana-Dashboard als Matrix-Widget im Security-Raum (Wunsch sorb): braucht
allow_embeddingin Grafana + Lese-Zugang ohne Login — eigener Punkt, nicht Teil dieses Deploys - gitops#52 (Inode-Falle) unberührt
- Erste HIGH-Welle kommt erst nach 24 h — bewusst, keine Fehlfunktion
Migriert aus Gitea sorb/management#1 (Gitea-Tracker stillgelegt, ADR-0002) — dort erstellt am 2026-08-01 von sorb.
Erledigt 2026-08-15 — Deploy ist gelandet und nachweislich in Betrieb
Beim Ausbau der Backup-Alarme (#0030) fiel auf, dass dieses Übergabe-Issue noch waiting
stand, obwohl der Deploy längst live ist. Nachgeprüft:
| Abnahmekriterium | Nachweis |
|---|---|
| Deploy gelandet | ff87cb2 ist Vorfahr von HEAD; CFGMON läuft inzwischen auf e9c13dc (zwei Commits darüber hinaus) |
| Kein Pro-CVE-Verkehr mehr | Regeln lauten count by (target, target_type, host) (trivy_vuln_info{…}) — eine Alarm-Instanz je Image; die Flut ist strukturell ausgeschlossen, nicht bloß gedrosselt |
| Receiver-Robustheit | matrix-alerts.py: save_state() steht inkrementell in der Sende-Schleife („Teilfortschritt übersteht Fehler/Retry"), plus 1s-Drosselung gegen rc_message und Speichern im Fehlerpfad — genau der beschriebene Bug ist behoben |
| Regel geladen | 14 Regeln evaluieren mit health=ok (Stand 2026-08-15) |
| Keine 502-Retry-Schleife | alertmanager_notifications_failed_total = 0 über 80 Serien aller Integrationen |
| Not-Aus nicht mehr nötig | Die room="security"-Route auf den Null-Receiver existiert nicht mehr; alertmanager.yml hat nur die Default-Route auf den matrix-Receiver |
Was NICHT direkt beobachtet wurde: ob im Security-Raum tatsächlich einmal aggregierte
🔴-Nachrichten eingetrudelt sind (Kriterium 2 der Übergabe, „gezählt ≤ 29"). Das lässt sich
nur im Raum bzw. in docker compose logs matrix-alerts sehen. Der Fehlzähler bei 0 belegt,
dass keine Zustellung gescheitert ist — er belegt nicht, dass welche stattfand.
Das Issue wird trotzdem geschlossen: sein Zweck war die Übergabe eines Deploys, und der ist
gelandet, robust und ohne die befürchteten Nebenwirkungen. Die Zustellung ist seit
e9c13dc zudem dauerhaft überwacht (AlertDeliveryFailing auf
alertmanager_notifications_failed_total) — ein künftiger Zustellfehler meldet sich von
selbst, statt auf eine manuelle Sichtprüfung zu warten.
Kleiner Folgepunkt (kein Blocker): Falls TrivyCriticalVulns derzeit inactive ist,
obwohl CRITICAL-Funde bekannt sind (#0051), wäre das ein eigener Hinweis — dann kämen die
trivy_vuln_info-Serien nicht (mehr) an. Einmal im Grafana-Dashboard cve-overview
gegenschauen; gehört fachlich zu #0051.
Weiterhin bewusst offen (aus dem Original): Grafana-Dashboard als Matrix-Widget im Security-Raum — eigener Punkt, war nie Teil dieses Deploys.