2026-08-21 12:00:00 +00:00
# Regeltests fuer die Deckungs-Alarme (#0106) und die Entscheidungs-Alarme (#0051).
2026-08-21 12:00:00 +00:00
# docker run --rm --entrypoint promtool -v "$PWD/prometheus:/p:ro" \
2026-08-21 12:00:00 +00:00
# prom/prometheus:v3.14.0 test rules /p/alerts_test.yml
2026-08-21 12:00:00 +00:00
#
# ⚠️ ZWECK: Eine Regel, die nur je gruen war, ist eine Vermutung. In diesem
# Projekt ist "meldet Erfolg, ist aber blind" die haeufigste Fehlerklasse
# (AAR 2026-08-01, Befund 1 und 3). Deshalb steht zu jeder Regel ein Fall, in
# dem sie feuern MUSS, und einer, in dem sie schweigen MUSS - sonst laesst sich
# eine Regel, die immer feuert, von einer richtigen nicht unterscheiden.
#
# Erste Regeltests in diesem Stack ueberhaupt; die uebrigen 16 Regeln sind
# bewusst nicht mit abgedeckt (Nicht-Ziel von #0106).
rule_files :
- alerts.yml
evaluation_interval : 1m
tests :
# --- CveTargetsMissing ----------------------------------------------------
- interval : 1m
name : "Luecke in der Deckung feuert nach 6h"
input_series :
- series : 'cve_targets_missing'
values : '24+0x480' # 8h lang 24 fehlende Images
alert_rule_test :
- eval_time : 5h
alertname : CveTargetsMissing
exp_alerts : [] # noch in der Karenz - eine volle Runde darf dauern
- eval_time : 7h
alertname : CveTargetsMissing
exp_alerts :
- exp_labels :
severity : warning
room : security
exp_annotations :
summary : "24 laufende Images werden NICHT auf CVEs geprueft — die Schwachstellen-Sicht hat ein Loch, das sie selbst nicht zeigt. Details: https://selendis.axion1337.de/d/cve-overview"
- interval : 1m
name : "Volle Deckung schweigt"
input_series :
- series : 'cve_targets_missing'
values : '0+0x480'
alert_rule_test :
- eval_time : 7h
alertname : CveTargetsMissing
exp_alerts : []
# --- CveTargetsOrphaned ---------------------------------------------------
- interval : 1m
name : "Berichte ohne laufendes Image feuern"
input_series :
- series : 'cve_targets_orphaned'
values : '2+0x480'
alert_rule_test :
- eval_time : 7h
alertname : CveTargetsOrphaned
exp_alerts :
- exp_labels :
severity : info
room : security
exp_annotations :
summary : "2 CVE-Bericht(e) betreffen Images, die nirgends laufen — Befunde, auf die niemand handeln kann (Rauschen, das wie Signal aussieht)"
# --- CveTargetSourceStale (die wichtigste) --------------------------------
- interval : 1m
name : "Eine eingefrorene Quelle faellt auf"
input_series :
# Die Registry-Quelle altert, die anderen beiden bleiben frisch.
- series : 'cve_target_source_stale{quelle="registry"}'
values : '0+60x400' # waechst um 60s je Minute -> nach 180 min > 10800
- series : 'cve_target_source_stale{quelle="cluster"}'
values : '30+0x400'
- series : 'cve_target_source_stale{quelle="operating"}'
values : '30+0x400'
alert_rule_test :
- eval_time : 2h
alertname : CveTargetSourceStale
exp_alerts : [] # 7200s < 10800s - noch in Ordnung
- eval_time : 5h
alertname : CveTargetSourceStale
exp_alerts :
- exp_labels :
severity : warning
room : security
quelle : registry # ⚠️ NUR die eingefrorene, nicht alle drei
exp_annotations :
summary : "Die Quelle 'registry' der CVE-Zielmenge ist seit 18000s nicht erneuert worden — die Zielmenge schrumpft still, und die Deckung sieht dadurch BESSER aus statt schlechter"
# --- CveTargetsNoneDesired ------------------------------------------------
# Der Fall, den die drei anderen NICHT sehen: alle Quellen antworten sauber,
# aber leer. missing = 0, stale frisch - und es wird nichts mehr geprueft.
- interval : 1m
name : "Leere Zielmenge trotz gesunder Quellen"
input_series :
- series : 'cve_targets_desired_total'
values : '0+0x120'
- series : 'cve_targets_missing'
values : '0+0x120'
- series : 'cve_target_source_stale{quelle="cluster"}'
values : '5+0x120'
alert_rule_test :
- eval_time : 20m
alertname : CveTargetsNoneDesired
exp_alerts : [] # Karenz 30m
- eval_time : 40m
alertname : CveTargetsNoneDesired
exp_alerts :
- exp_labels :
severity : critical
room : security
exp_annotations :
summary : "Die CVE-Zielmenge ist LEER — es wird nichts mehr geprueft, obwohl keine Quelle einen Fehler meldet"
# Gegenprobe im selben Lauf: die anderen drei schweigen hier, obwohl die
# Lage schlecht ist. Genau deshalb braucht es die vierte Regel.
- eval_time : 40m
alertname : CveTargetsMissing
exp_alerts : []
- eval_time : 40m
alertname : CveTargetSourceStale
exp_alerts : []
# --- Gegenprobe: gesunder Zustand loest KEINEN der vier Alarme aus --------
- interval : 1m
name : "Alles in Ordnung bleibt still"
input_series :
- series : 'cve_targets_missing'
values : '0+0x480'
- series : 'cve_targets_orphaned'
values : '0+0x480'
- series : 'cve_targets_desired_total'
values : '65+0x480'
- series : 'cve_target_source_stale{quelle="cluster"}'
values : '120+0x480'
- series : 'cve_target_source_stale{quelle="operating"}'
values : '120+0x480'
- series : 'cve_target_source_stale{quelle="registry"}'
values : '900+0x480'
alert_rule_test :
- eval_time : 7h
alertname : CveTargetsMissing
exp_alerts : []
- eval_time : 7h
alertname : CveTargetsOrphaned
exp_alerts : []
- eval_time : 7h
alertname : CveTargetsNoneDesired
exp_alerts : []
- eval_time : 7h
alertname : CveTargetSourceStale
exp_alerts : []
2026-08-21 12:00:00 +00:00
# --- CveCriticalOffen (#0051) ---------------------------------------------
- interval : 1m
name : "Ein CRITICAL ohne Entscheidung faellt nach 24h auf"
input_series :
- series : 'cve_critical_offen'
values : '3+0x1800'
alert_rule_test :
- eval_time : 20h
alertname : CveCriticalOffen
exp_alerts : [] # Karenz: ein frisch entdeckter Befund darf
# einen Arbeitstag lang unentschieden sein
- eval_time : 26h
alertname : CveCriticalOffen
exp_alerts :
- exp_labels :
severity : warning
room : security
exp_annotations :
summary : "3 CRITICAL auf laufenden Images ohne Entscheidung — weder behoben noch mit Begruendung und Pruefdatum in cve/entscheidungen.json. Details: https://selendis.axion1337.de/d/cve-overview"
# --- CveEntscheidungAbgelaufen --------------------------------------------
# ⚠️ Der eigentliche Zweck der Entscheidungsdatei. Ohne diese Regel wuerde
# aus "wir haben uns das angesehen und es ist vertretbar" nach ein paar
# Monaten still "das steht halt so in der Datei".
- interval : 1m
name : "Ein ueberschrittenes Pruefdatum meldet sich"
input_series :
- series : 'cve_entscheidungen_abgelaufen'
values : '0+0x60 1+0x600' # erst alles gueltig, dann laeuft eine ab
alert_rule_test :
- eval_time : 1h
alertname : CveEntscheidungAbgelaufen
exp_alerts : [] # noch nichts abgelaufen
- eval_time : 8h
alertname : CveEntscheidungAbgelaufen
exp_alerts :
- exp_labels :
severity : warning
room : security
exp_annotations :
summary : "1 CVE-Entscheidung(en) haben ihr Pruefdatum ueberschritten — die Begruendung von damals gilt bis zum Gegenbeweis nicht mehr"
# --- CveEntscheidungenUnlesbar --------------------------------------------
- interval : 1m
name : "Eine kaputte Entscheidungsdatei nennt sich selbst"
input_series :
- series : 'cve_entscheidungen_lesefehler'
values : '1+0x120'
# Gleichzeitig zaehlt alles als offen - so ist der Exporter gebaut.
- series : 'cve_critical_offen'
values : '63+0x120'
alert_rule_test :
- eval_time : 15m
alertname : CveEntscheidungenUnlesbar
exp_alerts : [] # Karenz 30m
- eval_time : 45m
alertname : CveEntscheidungenUnlesbar
exp_alerts :
- exp_labels :
severity : warning
room : security
exp_annotations :
summary : "cve/entscheidungen.json ist nicht lesbar — bis das behoben ist, zaehlt jeder CRITICAL als unentschieden"
# ⚠️ Gegenprobe zum Zusammenspiel: CveCriticalOffen schweigt hier noch
# (Karenz 24h). Ohne die Regel darueber bliebe der wahre Grund also
# einen ganzen Tag lang unsichtbar.
- eval_time : 45m
alertname : CveCriticalOffen
exp_alerts : []
# --- Gegenprobe: entschiedener Bestand bleibt still ------------------------
- interval : 1m
name : "Alles entschieden und gueltig bleibt still"
input_series :
- series : 'cve_critical_offen'
values : '0+0x1800'
- series : 'cve_critical_entschieden'
values : '63+0x1800'
- series : 'cve_entscheidungen_abgelaufen'
values : '0+0x1800'
- series : 'cve_entscheidungen_ohne_befund'
values : '0+0x1800'
- series : 'cve_entscheidungen_lesefehler'
values : '0+0x1800'
alert_rule_test :
- eval_time : 26h
alertname : CveCriticalOffen
exp_alerts : []
- eval_time : 26h
alertname : CveEntscheidungAbgelaufen
exp_alerts : []
- eval_time : 26h
alertname : CveEntscheidungOhneBefund
exp_alerts : []
- eval_time : 26h
alertname : CveEntscheidungenUnlesbar
exp_alerts : []