Einleitung (Einordnung, Relevanz für Security/SIEM/Wazuh)
Zeitbasierte Korrelation gehört zu den häufigsten Anforderungen in SIEM- und HIDS-Umgebungen: Mehrere fehlgeschlagene VPN-Logins sollen zunächst als Verdachtsmoment erkannt und bei wiederholtem Auftreten zu einem höher priorisierten Alarm eskaliert werden. In Wazuh wird das oft mit frequency/timeframe und „Composite Rules“ (if_matched_sid) umgesetzt. In der Praxis scheitert genau diese Eskalationslogik jedoch häufig – nicht wegen falscher Syntax, sondern wegen architekturbedingter Grenzen der Stream-Analyse in wazuh-analysisd.
Dieser Beitrag erklärt, warum eine Regel „auf Regel“ über große Zeitfenster unzuverlässig ist, und zeigt robuste Best Practices für produktionsfähige Eskalation.
Ausgangslage / Problemstellung (Zusammenfassung, Symptome, Umgebung)
Es existieren zwei Regeln:
- 120000 (Level 10) triggert wie erwartet, wenn ein Basis-SID (z. B. VPN-Fehllogin) innerhalb kurzer Zeit häufig genug auftritt (
frequency="10" timeframe="300"). - 120001 (Level 11) soll trigggern, wenn 120000 fünfmal innerhalb von 60 Minuten ausgelöst wurde (
frequency="5" timeframe="3600"), wird aber nie ausgelöst – obwohl 120000 in der Stunde deutlich öfter erscheint.
Das typische Erwartungsbild: „Wenn 120000 mindestens 5× in 1h feuert, muss 120001 feuern.“ – tatsächlich ist diese Schlussfolgerung in Wazuh nicht immer gültig.
Technische Analyse (Ursachen, betroffene Komponenten, Architekturbezug, Stolpersteine)
1) Composite Rules korrelieren nicht „beliebig weit zurück“, sondern in einem Event-Cache
Wazuhs Event-Analyse (wazuh-analysisd) arbeitet streambasiert: Jede neue Event-Zeile wird dekodiert, gegen Regeln gematcht und ggf. korreliert. Composite Rules (if_matched_sid + frequency/timeframe) „blicken“ dafür nicht in ein beliebig großes Zeitfenster zurück, sondern in einen begrenzten Cache vergangener analysierter Events. Historisch ist dieser Cache in Wazuh/OSSEC standardmäßig 8192 Events groß – unabhängig davon, wie groß timeframe gesetzt ist.
Konsequenz: Bei hoher Eventrate kann die effektive Rückschauzeit drastisch schrumpfen. Wenn auf einem Manager z. B. 100 Events/s analysiert werden (Alerts und Nicht-Alerts), entsprechen 8192 Events nur ~82 Sekunden „Rückblick“. Das erklärt, warum eine „1h“-Korrelation in Composite Rules in stark frequentierten Umgebungen praktisch nicht erreicht wird.
2) „Regel auf Regel“ verstärkt die Problematik
Regel 120001 korreliert nicht Rohereignisse, sondern Alerts von Regel 120000. Damit entsteht eine zweistufige Korrelation:
- Stufe A: Viele Roh-Events → 120000 erzeugt Alerts (aber ggf. gedrosselt durch
ignore) - Stufe B: Viele 120000-Alerts → 120001 soll daraus wieder eine Korrelation bilden
Wenn zwischen den 120000-Alerts viele andere Events liegen (normal in SIEM-Umgebungen), „rutschen“ die relevanten 120000-Alerts leicht aus dem 8192-Event-Fenster heraus, bevor 120001 seine frequency=5 zusammenbekommt. Das ist ein typischer Grund, warum 120001 nie feuert, obwohl 120000 sichtbar oft triggert.
3) ignore beeinflusst die Zählbasis – und kann unerwartete Effekte haben
Die Attribute frequency, timeframe und ignore sind in Wazuh-Regeln zentrale Mechanismen, um Flooding zu vermeiden; ignore unterdrückt nach einem Treffer weitere Alerts dieser Regel für eine definierte Zeit.
In deinem Beispiel hat 120000 ignore="500". Das heißt: Selbst wenn Rohereignisse weiterhin matchen, produziert 120000 nicht unbegrenzt viele Alerts, sondern nur so häufig, wie es ignore zulässt. Dadurch kann die Annahme „ich sehe 120000 zehnmal“ je nach Zeitraum und Sicht (Dashboard/Index) täuschen – insbesondere wenn mehrere Quellen/Manager/Indexer beteiligt sind oder wenn Aggregation/Refresh-Intervalle eine Rolle spielen.
4) Korrelation ohne „Gleichheitsanker“ (same_source_ip/same_id) kann „verwaschen“
Wenn die Eskalation pro Benutzer/IP/Session gelten soll, braucht die Composite Rule einen Anker wie same_source_ip, same_id oder passende Felder – sonst korreliert sie potenziell quer über verschiedene Clients/Benutzer hinweg. OSSEC/Wazuh beschreibt diese Mechanik im Kontext von if_matched_sid ausdrücklich als Kombi mit frequency/timeframe und optionalen „same_*“-Bedingungen.
Das ist nicht zwingend der Grund fürs „nie triggern“, aber ein häufiger Stolperstein bei Brute-Force-/VPN-Regeln: Ohne Anker ist das Ergebnis entweder zu laut oder inkonsistent.
Lösung / Best Practices (konkrete Schritte, Konfigurationen, Reihenfolge, Side-Effects)
Best Practice 1: Keine „Composite-of-Composite“-Eskalation – stattdessen direkt auf das Basissignal korrelieren
Wenn 120001 semantisch „50 Fehllogins in 1h“ bedeutet (weil 120000 = 10 Fehllogins in 5 Min, und 120001 = 5× davon), ist die stabilere Lösung:
- 120001 korreliert direkt den Basis-SID (z. B. 64018) mit entsprechend angepasster Frequenz.
Beispiel (Prinzip, Werte an deine Logik anpassen):
<rule id="120001" level="11" frequency="50" timeframe="3600" ignore="3600">
<if_matched_sid>64018</if_matched_sid>
<same_source_ip />
<description>VPN multiple failed logins (>=50 in 1h, same source)</description>
</rule>
Warum das besser ist: Du vermeidest die zweite Stufe „Alert zählt Alerts“ und reduzierst die Abhängigkeit vom Cache-Verhalten, weil nur eine Korrelationsebene nötig ist. Die Syntax- und Attributlogik ist in der Wazuh Ruleset XML Syntax beschrieben.
Side-Effect: Du musst sauber definieren, was „gleich“ bedeutet (same_source_ip, same_id etc.), sonst korrelierst du über unterschiedliche Quellen.
Best Practice 2: Für große Zeitfenster Query-basierte Detection verwenden (Wazuh Alerting / OpenSearch Alerting)
Für Muster über längere Fenster (z. B. 60 Minuten oder mehr) ist ein query-basierter Ansatz deutlich robuster: Du lässt periodisch eine Suche über bereits indexierte Alerts laufen und erzeugst daraus Benachrichtigungen/Alarme.
Wazuh beschreibt genau diese „Alerting-Optionen“ als Ergänzung zur streambasierten Erkennung.
Der Ansatz wird in der Praxis häufig über das (aus OpenSearch stammende) Alerting/Monitor-Konzept umgesetzt: Query auf wazuh-alerts* → Bedingung „count(rule.id:120000) >= 5 in last 60m“ → Trigger. Das Prinzip wird auch in technischen Deep-Dive-Beiträgen zur Wazuh Alerting Plugin Nutzung erläutert.
Vorteile:
- Zeitfenster wirklich „1h“, unabhängig von Eventrate/Cache.
- Korrelation kann flexibel nach Feldern (Agent, srcip, user, VPN-Gateway) gruppieren.
- Eskalation und Suppression lassen sich im Alerting sauber modellieren.
Side-Effect: Du betreibst eine zweite Detection-Schicht im Indexer/Dashboard-Kontext; Governance (wer pflegt Regeln wo) sollte klar geregelt sein.
Best Practice 3: Wenn Composite Rules zwingend sind: Zeitfenster kurz halten und Eventrate berücksichtigen
Wenn du unbedingt mit if_matched_sid + frequency/timeframe arbeiten willst:
- Nutze Composite Rules primär für kurze Zeitfenster (Sekunden bis wenige Minuten).
- Stelle sicher, dass die Korrelation einen Anker hat (
same_source_ip,same_id), um das Matching zu stabilisieren. - Prüfe, ob dein Use Case bei hoher Eventrate überhaupt in den Cache passt (8192 Events Limit als harte praktische Grenze).
Lessons Learned / Best Practices (präventive Maßnahmen, Betrieb, Skalierung)
timeframeist keine Garantie für „historische Rückschau“: Stream-Korrelation ist durch interne Caches begrenzt; bei hoher Last schrumpft das effektive Fenster drastisch.- Vermeide „Rule-on-Rule“-Kaskaden für lange Zeitfenster. Stattdessen entweder direkt auf das Basissignal korrelieren oder query-basiert im Index arbeiten.
- Trenne Echtzeit-Detektion und Retrospektiv-Detektion:
- Echtzeit (Sekunden/Minuten): Wazuh Ruleset (analysisd)
- Retrospektiv (Stunden/Tage, komplexe Pattern): Alerting/Query-basierte Monitore
- Korrelation immer mit Identitätsanker designen (z. B. gleiche Source-IP/gleicher User), sonst wird Eskalation unzuverlässig oder fachlich falsch.
Fazit (knappe Zusammenfassung mit Mehrwert)
Wenn eine Wazuh-Regel wie „120001 triggert nach 5× 120000 in 1h“ nie auslöst, liegt das häufig nicht an der Reihenfolge oder Syntax, sondern an der Architektur der streambasierten Composite Rules: Sie korrelieren nur über einen begrenzten Event-Cache (praktisch 8192 Events) – und bei hoher Eventrate ist ein „1h“-Fenster damit nicht erreichbar.
Für produktionssichere Eskalation gibt es zwei belastbare Wege: Entweder du korrelierst direkt das Basissignal mit der gewünschten Stunden-Frequenz (keine Kaskade), oder du setzt für große Zeitfenster auf query-basierte Alerting-Regeln im Indexer/Dashboard-Kontext.
Mehr zu Wazuh …
https://wazuh.com/?utm_source=ambassadors&utm_medium=referral&utm_campaign=ambassadors+program
Mehr zum Wazuh Ambassador Program …
https://wazuh.com/ambassadors-program/?utm_source=ambassadors&utm_medium=referral&utm_campaign=ambassadors+program
https://wazuh.slack.com/archives/C0A933R8E/p1768044763683569