Wenn Wazuh-Templates gegen Composable Templates verlieren – und warum ChatGPT hier (fast) alles kaputtgemacht hätte

Kevin stand vor einer typischen, aber extrem nervigen OpenSearch/Wazuh-Fehlermeldung.

Beim Aggregieren nach manager.name kam vom Wazuh-Indexer:

"reason": "Text fields are not optimised for operations that require per-document field data like aggregations and sorting...
Please use a keyword field instead. Alternatively, set fielddata=true on [manager.name] ..."

Kurz gesagt:

Du willst ein Textfeld aggregieren, das als text gemappt ist, nicht als keyword.

Im Wazuh-Kontext ist das ungewöhnlich – denn manager.name ist in der Standard-Template eigentlich schon als keyword definiert. Also: Was lief hier schief?

Was die Query eigentlich machen wollte

Die Dashboard-Abfrage sah stark vereinfacht so aus:

{
  "aggs": {
    "buckets": {
      "terms": {
        "field": "manager.name",
        "size": 5,
        "order": { "_count": "desc" }
      }
    }
  },
  "query": {
    "bool": {
      "filter": [
        { "range": { "timestamp": { "gte": "now-24h", "lte": "now" } } },
        { "range": { "rule.level": { "gte": 12, "lte": 14 } } },
        { "match_phrase": { "manager.name": { "query": "sentry" } } }
      ]
    }
  }
}

Also ganz normal: Top-Manager nach Anzahl kritischer Alerts in den letzten 24 Stunden.

Dass das scheitert, heißt:
manager.name ist im Index-Mapping kein keyword, sondern text. Und das ist der eigentliche Fehler.

Wazuh-Template vs. Composable Template – wer gewinnt?

Der erste Verdacht von Stuti:
Vielleicht ist im Template /etc/filebeat/wazuh-template.json der Typ falsch.

Dort sollte es so aussehen:

"manager": {
  "properties": {
    "name": {
      "type": "keyword"
    }
  }
}

Kevin checkt: Passt.
Also nächster Schritt: Template im Indexer-Cluster prüfen:

GET /_template/wazuh

Sieht gut aus. Das Mapping dort ist korrekt.

Dann kam der entscheidende Hinweis von Kevin Branch:

„Vielleicht wird das Wazuh-Template gar nicht verwendet.“

Die eigentliche Ursache: ein eigenes composable Template

Im Cluster existierte zusätzlich ein composable index template:

GET /_index_template/wazuh-alerts-template

Antwort:

{
  "index_templates": [
    {
      "name": "wazuh-alerts-template",
      "index_template": {
        "index_patterns": ["wazuh-alerts-*"],
        "template": {
          "settings": {
            "index": {
              "opendistro": {
                "index_state_management": {
                  "policy_id": "wazuh-alerts-retention-180d"
                }
              }
            }
          }
        },
        "composed_of": []
      }
    }
  ]
}

Was bedeutet das?

  • Dieses Template gilt für alle Indizes wazuh-alerts-*.
  • Es ist ein composable template, also „moderner“ als das klassische wazuh-Template.
  • In OpenSearch/Elasticsearch gilt: Composable Templates haben Vorrang vor Legacy Templates.

Ergebnis:

Das offizielle Wazuh-Template mit allen Mappings (inkl. manager.name = keyword) wird ignoriert.
Der Index entsteht mit den Standard-Mappingsmanager.name wird text → Aggregation schlägt fehl.

Und wie kam es dazu?

Kevin: „I did use ChatGPT to help…“
Kevin Branch: „Bingo, ChatGPT strikes again…“ 😄

ChatGPT hatte ein ILM-/ISM-Template vorgeschlagen, das nur Settings, aber kein Mapping setzt – und genau damit das Wazuh-Template überschattet.

Der Fix: Aufräumen im Template-Dschungel

Prüfen, wie manager.name aktuell gemappt ist

GET /wazuh-alerts-4.x-2025.10.31/_mapping/field/manager.name

Erwartet (korrekt):

{
  "wazuh-alerts-4.x-2025.10.31": {
    "mappings": {
      "manager.name": {
        "full_name": "manager.name",
        "mapping": {
          "name": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

Wenn dort type: text steht → Template-Konflikt.

Das falsche composable Template löschen

DELETE /_index_template/wazuh-alerts-template

Damit:

  • Neue wazuh-alerts-* Indizes verwenden wieder das Legacy wazuh-Template
  • manager.name wird korrekt als keyword angelegt
  • Aggregationen auf manager.name funktionieren wieder

Beste Wirkung ab dem nächsten Index-Rollover (z. B. tägliche Rotation).

Was ist mit den bisherigen Indizes?

Bereits existierende Indizes behalten ihre falsche Zuordnung.

Wenn du sie reparieren willst:

  1. Feld in Template korrigieren / Standard-Wazuh-Template aktivieren
  2. Index neu aufbauen (Reindexing): POST _reindex { "source": { "index": "wazuh-alerts-4.x-2025.10.31" }, "dest": { "index": "wazuh-alerts-4.x-2025.10.31-fixed" } }
  3. Mapping des neuen Index prüfen
  4. Alten Index löschen, Fixed-Index ggf. umbenennen oder Alias nutzen

Wazuh hat dazu eine eigene Doku-Seite zu Re-Indexing und Index Lifecycle Management (ILM/ISM).

Nebenkriegsschauplatz: Retention-Policies & ChatGPT

Kevin hatte mit ChatGPT ILM-/ISM-Policies gebaut, um NCSC-konforme Aufbewahrungsfristen umzusetzen.
Dabei entstand das „schädliche“ Template wazuh-alerts-template, das:

  • zwar brav eine wazuh-alerts-retention-180d-Policy setzt,
  • aber gleichzeitig das komplette offizielle wazuh-Template aushebelt.

Lektion daraus:

Nutze AI gern als Ideengeber –
aber verifiziere alles, was Templates & Cluster-Konfiguration betrifft, gegen die offizielle Wazuh- und OpenSearch-Dokumentation.

Kevin Branch hat es schön formuliert:

„I have a scar to match yours.“

Best Practices: Damit dir das nicht passiert

  1. Templates immer im Indexer prüfen, nicht nur in der lokalen JSON-Datei: GET /_template/wazuh GET /_cat/templates?v GET /_index_template/*
  2. Kein eigenes Template auf wazuh-alerts-* legen, ohne genau zu wissen, was du tust.
  3. Retention/ISM nach Wazuh-Doku umsetzen, z. B.:
    • Wazuh Doku zu Index Lifecycle Management
    • OpenSearch Dokumentation zu ISM Policies
  4. Wenn du AI benutzt:
    • Vorschläge nur als Startpunkt sehen
    • Nie blind Kommandos gegen den Cluster feuern
    • Immer prüfen: überschreibt das ein bestehendes Template?

Fazit

Die vermeintliche Fehlermeldung „Text fields are not optimised…“ war in Wirklichkeit nur die Spitze des Eisbergs:

  • Mapping war falsch → manager.name wurde als text angelegt
  • Ursache war ein manuell (bzw. per ChatGPT) erstelltes composable Template, das das offizielle Wazuh-Template überschrieben hat
  • Lösung war simpel: composable Template löschen → Wazuh-Template wieder greifen lassen → neue Indizes sind korrekt

Und ganz nebenbei ist das ein perfektes Beispiel dafür, warum man AI im Security-Stack immer mit gesundem Misstrauen benutzen sollte.

https://wazuh.slack.com/archives/C0A933R8E/p1761911994189579

Mehr zu Wazuh …

Mehr zum Wazuh Ambassador Program …