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
textgemappt ist, nicht alskeyword.
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-Mappings → manager.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 Legacywazuh-Template manager.namewird korrekt alskeywordangelegt- Aggregationen auf
manager.namefunktionieren 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:
- Feld in Template korrigieren / Standard-Wazuh-Template aktivieren
- 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" } } - Mapping des neuen Index prüfen
- 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
- Templates immer im Indexer prüfen, nicht nur in der lokalen JSON-Datei:
GET /_template/wazuh GET /_cat/templates?v GET /_index_template/* - Kein eigenes Template auf
wazuh-alerts-*legen, ohne genau zu wissen, was du tust. - Retention/ISM nach Wazuh-Doku umsetzen, z. B.:
- Wazuh Doku zu Index Lifecycle Management
- OpenSearch Dokumentation zu ISM Policies
- 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.namewurde alstextangelegt - 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