ADR-0012 made docs/issues/ canonical for the management scope only and left gitops, ThreadNet-Web and threadnet-call on GitLab "until the component adopts". That split produced exactly what it invited: two numbering worlds where management#20 and gitops#20 are different issues, drift nobody had to answer for (gitops#61 carried no milestone since 2026-08-11), and component backlogs that host sessions without lab access cannot read at all. The 46 open component issues are now files 0056-0101. The file id is the group-wide identifier; provenance lives in the frontmatter (new field `projekt` plus gitlab_iid) and in the filename, so "gitops#61" still finds 0091. Bodies are copied verbatim; comments and history stay on GitLab, as with the 2026-08-11 management import. Both scripts learned the second dimension: spiegel_issues.py routes each file to its origin project, reopens issues that are open in the repo but closed on the board, and writes the new iid back after creating one; gruppenpruefung.py checks drift across all four trackers instead of management alone. What the mirror cannot decide stays a finding, not a silent state. Two things needed a hand, both recorded in the files: gitops#61 had no milestone (M1 - it is a live account-takeover path) and carried two area labels where the schema holds one. The Gitea migration footers in the imported bodies point at decommissioned trackers; their links are removed, the provenance sentence stays. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
56 lines
3.1 KiB
Markdown
56 lines
3.1 KiB
Markdown
---
|
|
type: issue
|
|
id: "0082"
|
|
status: open
|
|
created: 2026-08-01
|
|
milestone: M1
|
|
priority: high
|
|
projekt: gitops
|
|
gitlab_iid: "49"
|
|
related: []
|
|
---
|
|
# CVE-Alarme: eine Matrix-Nachricht pro CVE flutet den Security-Raum -- Zustellung derzeit stumm
|
|
|
|
> Adoptiert aus [gitops#49](https://git.lab/axion1337.chat/axion1337.chat-gitops/-/issues/49) (2026-08-18, ADR-0019). Kommentare und Verlauf bleiben dort; kanonisch ist ab jetzt diese Datei.
|
|
|
|
Aus dem Deploy von #47 (2026-08-01). Die Pipeline sammelt Daten, **die Alarm-Zustellung ist aber abgeklemmt**: in `monitoring/alertmanager/alertmanager.yml` routet `room="security"` auf einen Null-Receiver (Commit `2b715ca`).
|
|
|
|
## Warum
|
|
|
|
`TrivyCriticalVuln` und `TrivyHighVuln` erzeugen eine Alarm-Instanz **pro CVE pro Image**. Gemessen am ersten Scan-Durchlauf, bei 14 von 29 Images:
|
|
|
|
| | Anzahl |
|
|
|---|---|
|
|
| CRITICAL (feuert sofort, kein `for:`) | 59 |
|
|
| HIGH (`for: 24h`) | 445 |
|
|
|
|
Hochgerechnet auf alle 29 Images grob 120 CRITICAL / 900 HIGH.
|
|
|
|
`group_by: [alertname, instance]` legt alle in *eine* Gruppe -> ein Webhook-POST mit ~120 Alarmen. `matrix-alerts.py` schickt daraus **eine Matrix-Nachricht pro Alarm**, sequenziell.
|
|
|
|
## Was es zur Schleife macht
|
|
|
|
`save_state()` steht in `do_POST` **hinter** der Sende-Schleife. Sobald ein Send fehlschlaegt -- Synapse rate-limitet `rc_message` per Default nach ~10 Nachrichten mit 429 -- fliegt die Exception, der State wird **nicht** gespeichert, der Receiver antwortet 502. Alertmanager wiederholt daraufhin die komplette Gruppe, und die Fingerprint-Deduplizierung (`if fp in state: continue`), die genau das verhindern soll, ist beim Retry noch leer. Das wiederholt sich, statt einmalig durchzulaufen.
|
|
|
|
## Zum Scharfschalten noetig
|
|
|
|
1. **Zustellung buendeln.** Entweder `matrix-alerts.py` auf eine Sammelnachricht pro Webhook-Batch umbauen (die fuenf Pflichtfelder je CVE als eine Zeile -- bleibt vollstaendig), oder die Regeln auf `count by (target, severity)` aggregieren und die CVE-Details im Dashboard lassen.
|
|
2. **State inkrementell speichern**, nach jedem erfolgreichen Send, plus 429-Behandlung mit `Retry-After`.
|
|
|
|
Danach die `room="security"`-Route aus `alertmanager.yml` entfernen.
|
|
|
|
## Kleinere Punkte aus demselben Review
|
|
|
|
- `TrivyScanStale` kann ein Image, das **nie** erfolgreich gescannt wurde, nicht melden: ohne ersten Report gibt es keine Serie, an der `time() - trivy_last_scan_timestamp` haengen koennte. Ein dauerhaft fehlschlagendes Image bleibt still; `TargetDown` deckt nur den toten Exporter ab.
|
|
- Der Exporter prunt den First-Seen-State bei **jedem** Scrape. Ein transienter Lesefehler (`except: continue`) loescht die Erstfund-Zeitstempel des betroffenen Targets dauerhaft.
|
|
- `coturn/coturn:latest` ist als einziges Image ungepinnt (schon in #47 notiert).
|
|
|
|
## Nicht betroffen
|
|
|
|
Scanner, Exporter, Scrape-Job und Dashboard laufen und sind verifiziert -- Exporter-Last 0,4 s pro Scrape fuer 29 Reports, unkritisch bei 15 s Intervall. Details im `monitoring/README.md`.
|
|
|
|
|
|
---
|
|
*Migriert aus Gitea `sorb/axion1337.chat-gitops#51` — dort erstellt am 2026-08-01 von sorb.*
|
|
<!-- gitea-migration: sorb/axion1337.chat-gitops#51 -->
|