Einleitung
Wazuh-Integrationen sind ein zentrales Bindeglied zwischen Detektion und Reaktion. Ob SOAR, DFIR-Plattformen oder externe Ticket- und Alerting-Systeme – viele Umgebungen leiten sicherheitsrelevante Events automatisiert weiter. In der Praxis zeigt sich jedoch immer wieder ein unerwartetes Verhalten: Sobald mehrere Integration-Blöcke auf dasselbe Event zutreffen, gehen Alerts scheinbar „verloren“. Dieser Artikel erklärt die interne Ausführungslogik von wazuh-integratord, warum sich Probleme unter Last verstärken und welche Architekturentscheidungen für einen stabilen Betrieb entscheidend sind.
Ausgangslage / Problemstellung
In einer Wazuh-Umgebung (Version 4.14.1) existieren zwei separate <integration>-Blöcke in der ossec.conf:
- Generische Integration: Triggert auf alle Alerts mit Level ≥ 10 und sendet diese an ein externes DFIR-System (z. B. IRIS).
- Spezifische Integration: Triggert gezielt auf bestimmte EDR-Rule-IDs und sendet ebenfalls an dasselbe Ziel.
Ein EDR-Alert mit Level 12 und passender Rule-ID erfüllt somit beide Kriterien. Erwartet wird, dass beide Integrationen ausgelöst werden. In der Praxis erreichen jedoch gerade bei diesen „überlappenden“ Events nicht alle Alerts zuverlässig das Zielsystem – obwohl:
- die Skripte manuell korrekt funktionieren,
- keine Syntaxfehler geloggt werden,
- und die Konfiguration unverändert bleibt.
Technische Analyse
Serielle Ausführung im wazuh-integratord
Der Kern des Problems liegt in der internen Architektur des Integrator-Daemons. wazuh-integratord führt Integrationen nicht parallel, sondern streng seriell aus:
- Trifft ein Alert auf mehrere
<integration>-Blöcke zu, werden diese nacheinander abgearbeitet. - Die Reihenfolge entspricht der Definition in der
ossec.conf. - Erst wenn ein Integrationsskript vollständig beendet ist, startet das nächste.
Es existiert keine Parallelisierung, keine getrennten Queues pro Integration und keine Isolation zwischen einzelnen Skript-Ausführungen.
Blocking-Effekte durch langsame Skripte
Dieses Design hat weitreichende Folgen:
- Verzögert sich die erste Integration (z. B. durch Netzwerk-Latenz, API-Timeouts, DNS-Probleme oder langsame I/O-Operationen), blockiert sie alle nachfolgenden Integrationen.
- Zeitüberschreitungen oder kurzzeitige Hänger führen dazu, dass weitere Integrationen entweder verspätet oder gar nicht mehr ausgeführt werden.
- Unter Last – etwa bei vielen Alerts mit Level ≥ 10 – entsteht ein Rückstau, der sich schleichend verschärft.
Das erklärt auch, warum sich das Verhalten „über die Zeit verschlechtert“, obwohl keine Konfigurationsänderungen vorgenommen wurden: Die Integrationspipeline läuft in ein Ressourcen- und Zeitlimit.
Keine Garantie für „mindestens einmal“-Ausführung
Wichtig ist:
Während Alerts weiterhin korrekt indexiert und im Dashboard sichtbar sind, gibt es keine Garantie, dass jede qualifizierte Integration auch tatsächlich ausgeführt wird. Der Integrator priorisiert Stabilität des Managers gegenüber der Vollständigkeit externer Integrationsaufrufe.
Lösung / Best Practices
1. Integrationslogik konsolidieren
Der empfohlene Ansatz ist, nicht mehrere Integration-Blöcke für dasselbe Zielsystem zu definieren, sondern:
- einen einzigen
<integration>-Block zu verwenden, - und die Filterlogik (Rule-ID, Severity, Gruppe, etc.) im Skript selbst umzusetzen.
Vorteile:
- Keine serielle Doppelbelastung des Integrators
- Volle Kontrolle über Priorisierung und Weiterleitung
- Sauberere Fehlerbehandlung
2. Keine Integrationen auf reiner Severity-Basis
Integrationen auf Basis von „Level ≥ X“ sind extrem anfällig für Überlastung. Best Practice ist:
- Enge Filter über spezifische Rule-IDs
- Dedizierte Rule-Gruppen für Integrationen
- Klare Trennung zwischen „Visibility“ und „Automation“
Severity ist ein Reporting-Kriterium – kein stabiles Trigger-Kriterium für Automatisierung.
3. Skripte maximal kurzlebig halten
Integrationsskripte sollten:
- keine blockierenden Netzwerk-Operationen enthalten
- keine langen Sleeps oder Polling-Logik ausführen
- möglichst schnell an einen asynchronen Worker oder Message-Queue übergeben
Ein bewährtes Muster ist ein Wrapper-Skript, das:
- vom Integrator aufgerufen wird,
- sofort zurückkehrt,
- und im Hintergrund (kontrolliert) parallele Worker startet.
4. Last und Burst-Szenarien einplanen
Auch schnelle Skripte stoßen an Grenzen, wenn:
- viele Alerts in kurzer Zeit eintreffen
- mehrere Integrationen gleichzeitig getriggert werden
Eine defensive Architektur mit Rate-Limits, Queueing und klaren Trigger-Kriterien ist essenziell.
Lessons Learned / Best Practices
wazuh-integratordarbeitet strikt sequentiell, nicht parallel.- Überlappende Integration-Blöcke konkurrieren um dieselbe Ausführungs-Pipeline.
- Langsame oder blockierende Skripte verhindern nachfolgende Integrationen.
- Severity-basierte Integrationen sind betrieblich riskant.
- Integrationen sollten selten, gezielt und asynchron ausgelöst werden.
Fazit
Das beobachtete Verhalten bei überlappenden Wazuh-Integrationen ist kein Bug, sondern eine direkte Folge des seriellen Designs von wazuh-integratord. Sobald mehrere Integration-Blöcke auf dasselbe Event zutreffen, entsteht ein hohes Risiko für Blocking und verlorene Ausführungen – insbesondere unter Last. Eine stabile Lösung erfordert ein Umdenken: weniger Integrationen, klarere Trigger, konsolidierte Logik und kurze, nicht blockierende Skripte. Wer diese Prinzipien beachtet, kann Wazuh-Integrationen auch in großen und dynamischen Umgebungen zuverlässig betreiben.
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/p1767348738490889