Wazuh indexiert AWS Client VPN-Logs nicht: Mapping-Konflikt bei data.port beheben

Einleitung

Bei der Integration von AWS Client VPN-Verbindungsprotokollen in Wazuh kann ein irreführendes Fehlerbild entstehen: Der Decoder verarbeitet das Ereignis korrekt, die benutzerdefinierte Regel erzeugt einen Alert und der Eintrag erscheint sowohl in alerts.json als auch in alerts.log. Im Wazuh Dashboard bleibt das Ereignis jedoch unsichtbar.

In diesem Fall liegt das Problem nicht bei der AWS-Logerfassung, dem Decoder oder der Wazuh-Regel. Der Fehler tritt erst im letzten Teil der Verarbeitungskette auf:

AWS Client VPN
        |
        v
AWS-Loggruppe / CloudWatch Logs
        |
        v
Wazuh Manager
        |
        +--> Decoder und Regeln
        |
        +--> /var/ossec/logs/alerts/alerts.json
                     |
                     v
                  Filebeat
                     |
                     v
              Ingest Pipeline
                     |
                     v
               Wazuh Indexer
                     |
                     v
              Wazuh Dashboard

Der Wazuh Manager erzeugt den Alert ordnungsgemäß. Filebeat liest ihn anschließend aus alerts.json, kann ihn aufgrund eines Mapping-Konflikts aber nicht im Wazuh Indexer speichern. Da das Dashboard ausschließlich auf die indexierten Dokumente zugreift, wird der Alert dort nicht angezeigt. Wazuh verwendet Filebeat standardmäßig für die Weiterleitung der vom Manager erzeugten Alerts an den Wazuh Indexer.

Ausgangslage / Problemstellung

Betroffen war ein AWS Client VPN-Verbindungsereignis mit unter anderem folgenden Feldern:

{
  "connection-log-type": "connection-reset",
  "connection-id": "cvpn-connection-0b23f3a4cxxxxxxx",
  "client-vpn-endpoint-id": "cvpn-endpoint-0a33f70c7xxxxxxx",
  "transport-protocol": "udp",
  "client-ip": "1.1.1.1",
  "device-ip": "2.2.2.2",
  "port": "60901",
  "ingress-bytes": "1540516",
  "egress-bytes": "4478621",
  "connection-duration-seconds": "3952"
}

Der JSON-Decoder übernahm die Felder in das data-Objekt des Wazuh Alerts. Aus dem ursprünglichen Feld port wurde dadurch:

{
  "data": {
    "port": "60901"
  }
}

Eine benutzerdefinierte Regel ordnete das Ereignis der Gruppe awsclientvpn zu und erzeugte einen Alert der Stufe 3:

{
  "rule": {
    "level": 3,
    "description": "AWS Client VPN Connection Log",
    "id": "100071",
    "groups": [
      "awsclientvpn"
    ]
  }
}

Die einzelnen Prüfungen ergaben zunächst ein widersprüchliches Bild:

  • wazuh-logtest meldete, dass ein Alert erzeugt wird.
  • Das Ereignis war bei aktivierter Archivierung in archives.json vorhanden.
  • Der Alert erschien in alerts.log und alerts.json.
  • Im Wazuh Dashboard fehlte der Alert.
  • Filebeat protokollierte einen HTTP-Status 400 mit einer mapper_parsing_exception.

Der entscheidende Teil der Fehlermeldung lautete:

object mapping for [data.port] tried to parse field [port]
as object, but found a concrete value

Damit war klar, dass der Alert den Wazuh Manager erfolgreich durchlaufen hatte, vom Wazuh Indexer jedoch zurückgewiesen wurde.

Technische Analyse

Der Fehler liegt hinter der Wazuh-Regelverarbeitung

wazuh-logtest prüft Decoder und Regeln. Ein erfolgreiches Testergebnis bestätigt daher, dass das Rohereignis korrekt dekodiert und einer Regel zugeordnet werden kann.

Auch ein Eintrag in /var/ossec/logs/alerts/alerts.json bestätigt lediglich, dass der Wazuh Manager den Alert erzeugt hat. Erst danach liest Filebeat das JSON-Dokument ein, verarbeitet es über die Wazuh-Ingest-Pipeline und sendet es an den Indexer.

Ein Alert kann deshalb gleichzeitig:

  • korrekt dekodiert,
  • von einer Regel erkannt,
  • in alerts.json gespeichert,
  • aber trotzdem nicht indexiert werden.

Diese Unterscheidung ist für die Fehlersuche entscheidend.

Objekt und Einzelwert verwenden denselben Feldpfad

Im betroffenen Index war data.port bereits als Objekt definiert. Ein Objekt könnte beispielsweise eine Struktur wie diese enthalten:

{
  "data": {
    "port": {
      "source": "60901",
      "destination": "443"
    }
  }
}

Das AWS Client VPN-Ereignis lieferte unter demselben Feldpfad dagegen einen einzelnen Wert:

{
  "data": {
    "port": "60901"
  }
}

Für den Wazuh Indexer sind dies zwei inkompatible Datentypen:

data.port = Objekt

und:

data.port = String

Ein Feld kann innerhalb desselben Index-Mappings nicht gleichzeitig ein Objekt und ein konkreter Einzelwert sein. OpenSearch speichert Objektfelder mit eigenen Unterfeldern. Der Datentyp eines bereits verwendeten Feldes lässt sich außerdem nicht nachträglich in einen inkompatiblen Typ ändern; dafür wäre ein neuer Index mit passendem Mapping erforderlich.

Dass der Port im AWS-Ereignis als String statt als Zahl vorliegt, ist dabei nicht die eigentliche Ursache. Auch eine Umwandlung von "60901" in 60901 würde den Konflikt zwischen Objekt und Einzelwert nicht beheben.

Generische Feldnamen erhöhen das Konfliktrisiko

Wazuh verarbeitet zahlreiche unterschiedliche Datenquellen in gemeinsamen täglichen Alert-Indizes. Das dynamische data-Objekt kann dadurch Felder aus Betriebssystemen, Cloud-Diensten, Anwendungen, Netzwerkgeräten und benutzerdefinierten Integrationen enthalten.

Ein generischer Feldname wie:

data.port

ist deshalb konfliktanfällig. Je nach Datenquelle kann „port“ Folgendes bedeuten:

  • einen Client-Port,
  • einen Quell-Port,
  • einen Ziel-Port,
  • ein Objekt mit mehreren Port-Angaben,
  • einen numerischen Wert,
  • einen als String übertragenen Wert.

Selbst ein neuer täglicher Index löst dieses grundlegende Problem nicht zuverlässig. Wird dort zuerst der AWS-Wert indexiert, könnte data.port als konkretes Feld angelegt werden. Später eintreffende Ereignisse, die data.port als Objekt verwenden, würden dann in umgekehrter Richtung scheitern.

Die Daten müssen daher vor der Indexierung auf einen eindeutigen Feldnamen normalisiert werden.

Die Reihenfolge der Ingest-Prozessoren ist entscheidend

Der Wazuh-Alert liegt für Filebeat zunächst als JSON-String im Feld message vor. Am Anfang der Wazuh-Ingest-Pipeline wird dieser String mit einem JSON-Prozessor verarbeitet:

{
  "json": {
    "field": "message",
    "add_to_root": true
  }
}

Erst nach diesem Schritt existieren Felder wie:

rule.groups
data.port

als strukturierte Felder im Dokument.

Der Rename-Prozessor muss deshalb direkt nach dem JSON-Prozessor ausgeführt werden. Wird er davor eingefügt, kann er data.port nicht finden.

Lösung / Best Practices

Die minimalinvasive Lösung besteht darin, data.port ausschließlich für AWS Client VPN-Alerts in data.clientPort umzubenennen. Dadurch bleibt der Port durchsuchbar, kollidiert aber nicht mehr mit dem bereits vorhandenen Objekt-Mapping.

1. Bestehende Pipeline sichern

Vor der Änderung sollte eine Sicherung der ausgelieferten Pipeline erstellt werden:

cp /usr/share/filebeat/module/wazuh/alerts/ingest/pipeline.json \
   /tmp/wazuh-alerts-pipeline.json.backup

Optional kann zusätzlich ein Vergleich mit der später geänderten Version vorbereitet werden:

sha256sum \
  /usr/share/filebeat/module/wazuh/alerts/ingest/pipeline.json \
  /tmp/wazuh-alerts-pipeline.json.backup

2. Rename-Prozessor einfügen

Die folgende Datei wird auf dem Wazuh-Server bearbeitet:

/usr/share/filebeat/module/wazuh/alerts/ingest/pipeline.json

Der Rename-Prozessor wird direkt hinter dem bestehenden JSON-Prozessor eingefügt:

{
  "description": "Wazuh alerts pipeline",
  "processors": [
    {
      "json": {
        "field": "message",
        "add_to_root": true
      }
    },
    {
      "rename": {
        "field": "data.port",
        "target_field": "data.clientPort",
        "ignore_missing": true,
        "if": "def g = ctx?.rule?.groups; g != null && ((g instanceof List && g.contains(\"awsclientvpn\")) || (g instanceof String && g == \"awsclientvpn\"))"
      }
    },
    {
      "set": {
        "field": "data.aws.region",
        "value": "{{data.aws.awsRegion}}",
        "override": false,
        "ignore_failure": true,
        "ignore_empty_value": true
      }
    }
  ]
}

Der OpenSearch-Rename-Prozessor verschiebt den Wert vom ursprünglichen zum neuen Feldnamen. Mit ignore_missing: true bleibt die Pipeline auch dann funktionsfähig, wenn ein Dokument kein data.port enthält. Über die if-Bedingung kann die Ausführung auf die gewünschte Ereignisgruppe begrenzt werden.

Die Bedingung berücksichtigt zwei mögliche Darstellungen von rule.groups:

"groups": [
  "awsclientvpn"
]

sowie:

"groups": "awsclientvpn"

In regulären Wazuh Alerts ist groups üblicherweise eine Liste. Die zusätzliche String-Prüfung macht die Bedingung jedoch robuster gegenüber abweichend aufbereiteten Dokumenten.

3. JSON-Syntax validieren

Vor dem Laden der Pipeline sollte die Datei syntaktisch geprüft werden:

jq empty /usr/share/filebeat/module/wazuh/alerts/ingest/pipeline.json

Bei korrekter JSON-Syntax erzeugt der Befehl keine Ausgabe. Ein Fehler muss vor dem nächsten Schritt behoben werden.

Zusätzlich kann die Filebeat-Konfiguration geprüft werden:

filebeat test config -e

4. Pipeline in den Wazuh Indexer laden

Anschließend wird die geänderte Ingest-Pipeline neu geladen:

filebeat setup --pipelines

Danach wird Filebeat neu gestartet:

systemctl restart filebeat

Der Status lässt sich wie folgt kontrollieren:

systemctl status filebeat --no-pager

Für die laufende Protokollkontrolle eignet sich:

journalctl -u filebeat -f

Je nach Installation schreibt Filebeat außerdem in:

/var/log/filebeat/filebeat

5. Geladene Pipeline kontrollieren

Die ID der verwendeten Pipeline steht in der ursprünglichen Filebeat-Fehlermeldung. Im beschriebenen Fall lautete sie:

filebeat-7.10.2-wazuh-alerts-pipeline

Über die Dev Tools des Wazuh Dashboards kann die aktive Pipeline geprüft werden:

GET _ingest/pipeline/filebeat-7.10.2-wazuh-alerts-pipeline

Bei einer anderen Filebeat-Version muss die Pipeline-ID entsprechend angepasst werden.

In der Antwort sollte der neue Rename-Prozessor enthalten sein. Dadurch wird überprüft, dass nicht nur die lokale Datei geändert, sondern die Konfiguration tatsächlich in den Indexer geladen wurde.

6. Ergebnis kontrollieren

Ein neu eintreffender AWS Client VPN-Alert sollte anschließend nicht mehr dieses Feld enthalten:

{
  "data": {
    "port": "60901"
  }
}

Stattdessen wird das Dokument vor der Indexierung folgendermaßen umgeschrieben:

{
  "data": {
    "clientPort": "60901"
  }
}

Geeignete Kontrollen sind:

grep -E 'mapper_parsing_exception|Cannot index event|status=400' \
  /var/log/filebeat/filebeat

Im Wazuh Dashboard kann zusätzlich nach der Regelgruppe gesucht werden:

rule.groups: awsclientvpn

Oder direkt nach dem neuen Feld:

data.clientPort: *

7. Historische Ereignisse richtig behandeln

Die Pipeline-Änderung wirkt auf neu verarbeitete Dokumente. Bereits mit HTTP-Status 400 abgelehnte Alerts befinden sich nicht im Zielindex.

Eine Reindexierung des bestehenden Wazuh-Index kann diese fehlenden Dokumente deshalb nicht wiederherstellen: _reindex kann nur Dokumente kopieren, die im Quellindex tatsächlich vorhanden sind.

Für die Wiederherstellung abgewiesener AWS Client VPN-Ereignisse wird eine weiterhin verfügbare Quelle benötigt, beispielsweise:

  • die ursprüngliche AWS-CloudWatch-Loggruppe,
  • eine aufbewahrte alerts.json,
  • eine aktivierte archives.json,
  • ein externes Logarchiv,
  • ein Object-Storage- oder SIEM-Export.

Nach der Pipeline-Korrektur können die betreffenden Ereignisse aus dieser Quelle erneut eingelesen werden. Dabei sollte nicht davon ausgegangen werden, dass Filebeat bereits gelesene Zeilen automatisch noch einmal verarbeitet.

Eine Reindexierung ist dagegen sinnvoll, wenn bereits indexierte Dokumente in ein neues Schema überführt werden sollen. Wazuh beschreibt dafür die Nutzung der _reindex-API. Aus Sicherheitsgründen sollte zunächst immer in einen neuen Zielindex geschrieben, das Ergebnis geprüft und der Quellindex erst danach entfernt werden.

Ein bestehender Produktionsindex sollte nicht vorschnell gelöscht werden. Vor einer Migration sind mindestens folgende Punkte zu prüfen:

GET /wazuh-alerts-4.x-2026.07.24/_count
GET /wazuh-alerts-4.x-2026.07.24/_mapping
GET /wazuh-alerts-4.x-2026.07.24/_settings

Nach der Migration müssen Dokumentanzahl, Mapping, Zeitbereich und Suchbarkeit mit dem Quellindex verglichen werden.

8. Archivierung nur kontrolliert aktivieren

Mit logall_json kann Wazuh alle eingehenden Ereignisse in folgender Datei speichern:

/var/ossec/logs/archives/archives.json

Das ist bei der Fehlersuche hilfreich, weil dort auch Ereignisse enthalten sind, die keinen Alert erzeugen. Die Archivierung ist standardmäßig deaktiviert und kann erheblichen Speicherplatz beanspruchen. Sie sollte in Produktivumgebungen daher nur mit ausreichender Kapazitätsplanung, Rotation und Aufbewahrungsstrategie aktiviert werden.

Eine mögliche Konfiguration in /var/ossec/etc/ossec.conf lautet:

<ossec_config>
  <global>
    <logall_json>yes</logall_json>
  </global>
</ossec_config>

Nach der Änderung ist der Wazuh Manager neu zu starten:

systemctl restart wazuh-manager

Für eine kurzfristige Fehleranalyse sollte die Option nach Abschluss der Untersuchung wieder deaktiviert werden, sofern keine fachliche oder regulatorische Anforderung für eine vollständige Rohdatenarchivierung besteht.

Lessons Learned / Best Practices

Alert-Erzeugung und Indexierung getrennt überwachen

Ein Eintrag in alerts.json bedeutet nicht automatisch, dass der Alert im Dashboard verfügbar ist. Eine vollständige Überwachung der Verarbeitungskette sollte mindestens folgende Komponenten umfassen:

Wazuh Manager
Filebeat
Ingest Pipeline
Wazuh Indexer
Wazuh Dashboard

Besonders relevant sind Filebeat-Fehler mit:

status=400
mapper_parsing_exception
Cannot index event

Diese Fehler können zu einer stillen Sichtbarkeitslücke führen: Die Erkennungsregel funktioniert, der Alert erreicht aber weder Dashboards noch indexbasierte Benachrichtigungen, Reports oder Threat-Hunting-Abfragen.

Datenquellen eindeutig benennen

Generische Felder wie data.port, data.id, data.name oder data.status sollten bei benutzerdefinierten Integrationen vermieden werden.

Für AWS Client VPN wären langfristig eindeutigere Strukturen sinnvoll:

{
  "data": {
    "awsclientvpn": {
      "clientPort": "60901",
      "connectionId": "cvpn-connection-0b23f3a4cxxxxxxx",
      "endpointId": "cvpn-endpoint-0a33f70c7xxxxxxx"
    }
  }
}

Dadurch werden Konflikte mit anderen Logquellen deutlich unwahrscheinlicher.

Die im Praxisfall eingesetzte Umbenennung nach data.clientPort ist eine funktionierende und risikoarme Korrektur. Bei neu entwickelten Integrationen ist ein eigener Namensraum wie data.awsclientvpn.* jedoch besser skalierbar.

Pipeline-Änderungen möglichst eng begrenzen

Eine globale Umbenennung von data.port könnte andere Integrationen beeinflussen. Die Einschränkung über:

rule.groups: awsclientvpn

stellt sicher, dass nur die betroffene Ereignisklasse verändert wird.

Eine solche Bedingung reduziert Nebenwirkungen und erleichtert spätere Fehleranalysen.

Änderungen auf allen Filebeat-Knoten konsistent ausrollen

In einem Wazuh-Server-Cluster können mehrere Manager-Knoten Filebeat ausführen. Die lokale Pipeline-Datei muss dann auf allen relevanten Knoten identisch gepflegt werden.

Andernfalls kann die zuletzt mit filebeat setup --pipelines geladene Version die zuvor geladene Pipeline überschreiben. Die Konfiguration sollte deshalb über ein zentrales Konfigurationsmanagement oder einen kontrollierten Deployment-Prozess verteilt werden.

Änderungen upgradesicher dokumentieren

Dateien unter:

/usr/share/filebeat/module/

gehören typischerweise zum installierten Filebeat-Modul. Paketaktualisierungen oder eine erneute Installation des Wazuh-Filebeat-Moduls können lokale Änderungen überschreiben.

Mindestens folgende Informationen sollten deshalb dokumentiert werden:

  • geänderte Datei,
  • verwendete Wazuh- und Filebeat-Version,
  • vollständiger Pipeline-Diff,
  • betroffene Regelgruppen,
  • Datum der Änderung,
  • Testereignis,
  • erwartetes Ergebnis,
  • Wiederherstellungsweg.

Nach jedem Upgrade sollte geprüft werden, ob der Rename-Prozessor weiterhin vorhanden und im Indexer geladen ist.

Repräsentative Testdaten verwenden

wazuh-logtest ist für die Entwicklung von Decodern und Regeln unverzichtbar, prüft aber nicht die vollständige Indexierungskette.

Für benutzerdefinierte Datenquellen sollte ein Integrationstest deshalb zusätzlich prüfen:

Rohereignis empfangen
        |
        v
Decoder erfolgreich
        |
        v
Regel ausgelöst
        |
        v
Alert in alerts.json
        |
        v
Filebeat ohne Fehler
        |
        v
Dokument im Wazuh Indexer
        |
        v
Dokument im Dashboard auffindbar

Erst wenn alle Schritte erfolgreich sind, ist die Integration vollständig funktionsfähig.

Fazit

Wenn AWS Client VPN-Alerts in alerts.log und alerts.json vorhanden sind, aber im Wazuh Dashboard fehlen, sollte die Fehlersuche nicht bei Decoder und Regeln enden. Eine mapper_parsing_exception im Filebeat-Protokoll zeigt, dass der Wazuh Indexer das Dokument aufgrund eines inkompatiblen Feld-Mappings abgelehnt hat.

Im beschriebenen Fall wurde data.port in einem Teil der Wazuh-Daten als Objekt erwartet, während das AWS Client VPN-Ereignis dort einen einzelnen String-Wert lieferte. Ein bedingter Rename-Prozessor in der Wazuh-Ingest-Pipeline benennt das Feld für die Regelgruppe awsclientvpn in data.clientPort um und verhindert damit den Mapping-Konflikt.

Die wichtigste betriebliche Erkenntnis lautet: Ein korrekt ausgelöster Wazuh Alert ist erst dann vollständig nutzbar, wenn er auch erfolgreich indexiert wurde. Filebeat- und Indexer-Fehler müssen deshalb ebenso konsequent überwacht werden wie Decoder, Regeln und die Logerfassung selbst.

Quellen

Wazuh – Indexer integration:
https://documentation.wazuh.com/current/user-manual/manager/indexer-integration.html

Wazuh – Alert management:
https://documentation.wazuh.com/current/user-manual/manager/alert-management.html

Wazuh – Event logging und archives.json:
https://documentation.wazuh.com/current/user-manual/manager/event-logging.html

Wazuh – Re-indexing:
https://documentation.wazuh.com/current/user-manual/wazuh-indexer/re-indexing.html

OpenSearch – Rename processor:
https://docs.opensearch.org/latest/ingest-pipelines/processors/rename/

OpenSearch – Object field type:
https://docs.opensearch.org/latest/mappings/supported-field-types/object/

OpenSearch – Index-Mappings erstellen und ändern:
https://docs.opensearch.org/latest/api-reference/index-apis/put-mapping/

Mehr zu Wazuh …

Mehr zum Wazuh Ambassador Program …

https://wazuh.slack.com/archives/C07BZJY86G3/p1784884619320289