Einleitung (Einordnung, Relevanz für Security/SIEM/Wazuh)
Beim Bau eigener Wazuh-Regeln kommt es oft zu einem Missverständnis, das in SIEM-Setups schnell zu falschen Alarmen oder – schlimmer – zu verdeckten Erkennungsregeln führt: Rule-IDs steuern keine Priorität. Entscheidend sind die Matching-Logik, die Regelhierarchie und die Severity/Level-Semantik in Kombination mit der Alert-Schwelle des Managers.
Dieser Beitrag zeigt anhand eines Mikrotik-Firewall-Beispiels, warum eine allgemeine Audit-Regel alle spezifischen Regeln „überfährt“ und wie man das korrekt löst – inklusive einer praxistauglichen Konfiguration, die Zählregeln für Korrelation (if_matched_sid) ermöglicht, ohne das Wazuh-Dashboard mit Low-Value-Alerts zu fluten.
Ausgangslage / Problemstellung (Zusammenfassung, Symptome, Umgebung)
Ein Regelset für Mikrotik-Firewall-Logs besteht aus:
- einer Basisregel (
decoded_as=firewall-base) - drei spezifischen Child-Regeln für Traffic-Flows (
LAN→WAN,LAN→LAN,WAN→LAN) - einer allgemeinen Catch-all-Regel (Audit), die alles erfassen soll, was nicht in die spezifischen Fälle fällt
Trotzdem wird in der Praxis immer die Audit-Regel ausgelöst – obwohl ihre Rule-ID „höher“ ist:
- Spezifische Regeln:
100002,100003,100004(level 1) - Catch-all:
120000(level 3)
Beispiel-Log:
firewall,info [ANTENNA01]: [ANTENNA01] forward: in:LAN out:WAN2, connection-state:established,snat ... 192.168.3.253:53012->150.184.160.48:8080 ...
Zusätzlich existieren Korrelationsregeln wie:
<rule id="100014" level="12" frequency="20" timeframe="60">
<if_matched_sid>100004</if_matched_sid>
<same_srcip />
<same_dstip />
<different_dstport />
<description>Port scan detected: IP $(srcip) scan $(dstip).</description>
</rule>
Dafür müssen die Basis-Child-Regeln mindestens Level 1 haben, da if_matched_sid auf vorherige Matches aufsetzt und typischerweise mit Frequency/Timeframe genutzt wird.
Technische Analyse (Ursachen, betroffene Komponenten, Architekturbezug, Stolpersteine)
1) Rule-ID ist keine Priorität
Wazuh verwendet Rule-IDs als Identifikatoren, nicht als Prioritätsmechanismus. Priorität entsteht durch Regelstruktur (Parent/Child über if_sid) und durch Level/Severity-Konzept sowie Matching-Kriterien. (Die Regeln selbst sind über XML-Syntax und Klassifikation definiert.)
2) Warum die Catch-all-Regel alles „schluckt“
Deine Audit-Regel:
<rule id="120000" level="3">
<if_sid>100000</if_sid>
<description>Firewall audit logs</description>
</rule>
hat keine einschränkenden Bedingungen (keine <field>, kein <match>). Damit matcht sie praktisch jeden Event, der den Parent 100000 erreicht.
Kritisch ist dabei der Level-Unterschied:
- Spezifische Regeln: Level 1
- Catch-all: Level 3
Wazuh speichert standardmäßig Alerts erst ab einer gewissen Schwere. Standardmäßig liegt die Alert-Schwelle bei Level 3 (<log_alert_level>3</log_alert_level>).
Heißt: Level-1-Regeln können zwar matchen, aber nicht als Alert erscheinen – während Level 3 als Alert durchgeht.
In der Praxis führt das häufig zu der Wahrnehmung: „Immer triggert 120000.“ Tatsächlich passiert meist beides:
- Spezifische Rules matchen (Level 1 → kein Alert)
- Catch-all matcht ebenfalls (Level 3 → Alert sichtbar)
3) Warum „alles auf Level 0“ die falsche Abkürzung ist
Level 0 ist „Ignored/No action“ und wird typischerweise zum Unterdrücken genutzt.
Damit zerstörst du aber deine Korrelation: Viele Konstrukte rund um if_matched_sid setzen voraus, dass die Vorregel sinnvoll matcht (und in der Praxis zumindest >0 ist), sonst fehlt dir die stabile Basis für Zähl-/Eskalationsregeln.
Lösung / Best Practices (konkrete Schritte, Konfigurationen, Reihenfolge, Side-Effects)
Zielbild
- Spezifische Traffic-Regeln sollen matchen und als Basis für
if_matched_siddienen. - Sie sollen nicht automatisch Alerts erzeugen.
- Eine Catch-all-Regel soll nur dann greifen, wenn keine spezifische Regel greift.
- Optional: Eine zweite Stufe soll bei Bedarf Alerts erzeugen, aber kontrolliert.
Schritt 1: Basisregeln auf Level 2 statt Level 1 setzen
Wenn du das Default-Setup nutzt (Alert-Schwelle 3), sind Level-2-Regeln weiterhin nicht alertend, aber „stärker“ als Level 1 für die interne Priorisierung und als solide Grundlage für Korrelation.
Die Default-Alertschwelle (log_alert_level=3) ist dokumentiert; ebenso, dass per Default erst ab Level 3 Alerts ausgelöst/gespeichert werden.
Schritt 2: Catch-all zweistufig bauen (Stage 1 nicht alertend, Stage 2 optional alertend)
Die entscheidende Idee: Catch-all zuerst nicht alertend, und falls du wirklich auditierbare Alerts willst, baust du eine zweite Stufe, die du später gezielt aktivieren/steuern kannst.
Hier ist eine praxistaugliche Version (direkt einsetzbar):
<group name="mikrotik,">
<!-- Base rule -->
<rule id="100000" level="0">
<decoded_as>firewall-base</decoded_as>
<description>Logs Firewall</description>
</rule>
<!-- LAN -> WAN* (countable, but not alerting if log_alert_level is 3) -->
<rule id="100002" level="2">
<if_sid>100000</if_sid>
<field name="in">LAN</field>
<field name="out">WAN|WAN2|WAN3</field>
<description>Outbound stream detected: $(in) to $(out).</description>
</rule>
<!-- LAN -> LAN -->
<rule id="100003" level="2">
<if_sid>100000</if_sid>
<field name="in">LAN</field>
<field name="out">LAN</field>
<description>Internal traffic detected at the antenna.</description>
</rule>
<!-- WAN* -> LAN -->
<rule id="100004" level="2">
<if_sid>100000</if_sid>
<field name="in">WAN|WAN2|WAN3</field>
<field name="out">LAN</field>
<description>External traffic detected at the antenna.</description>
</rule>
<!-- Stage 1: non-alerting catch-all (still matchable for chaining) -->
<rule id="120000" level="1">
<if_sid>100000</if_sid>
<description>Firewall audit logs (catch-all, non-alerting)</description>
<group>audit,</group>
</rule>
<!-- Stage 2: optional alerting catch-all -->
<rule id="120001" level="3">
<if_sid>120000</if_sid>
<description>Firewall audit logs (catch-all, alerting)</description>
<group>audit,</group>
</rule>
</group>
Warum das funktioniert:
- Die spezifischen Regeln (
100002–100004) sind Level 2 → sie bleiben bei Default-Alertschwelle 3 leise, sind aber als „Basis-Events“ sauber nutzbar. 120000ist der Catch-all als Level 1 → ebenfalls leise, aber als „Stage 1“ für Ketten nutzbar.120001erzeugt Alerts (Level 3) nur, wenn120000matched – und du kannst ihn jederzeit anpassen, z. B. mit weiteren Bedingungen oder Gruppen, um die Audit-Flut zu kontrollieren.
Schritt 3: Korrelation mit if_matched_sid sauber auf Level-2-Regeln aufsetzen
Dein Portscan-Beispiel kann so bleiben – es setzt auf 100004 auf und feuert erst bei Frequency/Timeframe, was genau dem Zweck entspricht. Die Syntax und der Einsatz von if_matched_sid sind in der Rules-Syntax dokumentiert.
Side-Effects und Betriebsregeln
- Wenn du
<log_alert_level>imossec.confverändert hast (z. B. auf 2), dann würden Level-2-Regeln plötzlich Alerts erzeugen. Prüfe daher die Alert-Schwelle auf dem Manager. - Level 0 sollte nicht als „Zählregel“ missbraucht werden; es ist primär zum Ignorieren gedacht.
Lessons Learned / Best Practices (präventive Maßnahmen, Betrieb, Skalierung)
- Nie mit Rule-ID argumentieren: IDs sind nur Identifikatoren, keine Priorität.
- Baue Regeln immer als Hierarchie:
decoded_as→ Parent (Basis) → spezifische Child-Rules → Catch-all als letztes Sicherheitsnetz. - Nutze das Level-Konzept strategisch:
- Level 1–2: „zählbar, aber leise“ (bei Default log_alert_level=3)
- Level ≥3: „alertend“
- Level 0: „ignorieren“
- Korrelation (
if_matched_sid+ frequency/timeframe) braucht eine stabile, wiedererkennbare Basisregel – idealerweise nicht Level 0. - Dokumentiere in Runbooks immer die Alert-Schwelle (
log_alert_level) – sie ist der häufigste Grund, warum „Regeln scheinbar nicht triggern“.
Fazit (knappe Zusammenfassung mit Mehrwert)
Wenn eine Catch-all-Regel deine spezifischen Regeln „überfährt“, ist fast nie die Rule-ID schuld – sondern eine Kombination aus fehlenden Bedingungen, Level/Severity und der Alert-Schwelle des Managers. Mit Level-2-Basisregeln (für Korrelation ohne Alert-Flut) und einer zweistufigen Catch-all-Strategie bekommst du beides: saubere Abdeckung aller Mikrotik-Firewall-Logs und belastbare if_matched_sid-Korrelation, ohne das SIEM mit Low-Value-Alerts zu überladen.
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/C07CCCCGHHP/p1769030097566099