Einleitung
Wenn Wazuh Dashboard in Modulen wie Threat Hunting, Vulnerabilities und Inventory „No data“ anzeigt, obwohl die zugehörigen wazuh-states-*-Indizes im Indexer nachweislich Dokumente enthalten, liegt das Problem fast nie an der Datenerhebung. In der Praxis sind es typischerweise Kommunikations- und Integrationsprobleme zwischen Dashboard ↔ Indexer (OpenSearch) und Dashboard ↔ Wazuh API – besonders häufig im Kontext von TLS-Zertifikaten, Zertifikatsketten und ClientAuth/mTLS. Dieser Beitrag verdichtet den Fall zu einer belastbaren Troubleshooting- und Fix-Strategie.
Ausgangslage / Problemstellung
Umgebung (wie im Thread):
- Installation: All-in-One
- Wazuh Dashboard: 4.14.1
- Wazuh Indexer (OpenSearch-basiert): 7.10.2
- Single-Node-Cluster, Cluster-Health GREEN, Shards aktiv
- Dashboard per HTTPS auf Port 443 erreichbar
- Indizes existieren und sind gefüllt, z. B.
wazuh-states-vulnerabilities-<node>(Tausende Dokumente)wazuh-states-inventory-packages-<node>(Tausende Dokumente)
- Nicht funktional im UI: Threat Hunting, Vulnerabilities, Inventory → „No data“
- Zusätzlich: Saved Objects (Searches/Visualizations/Dashboards) sind leer (API
_findlieferttotal: 0)
Zentraler Hinweis aus den Logs und Tests:
- Dashboard-Logs zeigen wiederholt TLS-Fehler wie
ERR_SSL_SSLV3_ALERT_CERTIFICATE_UNKNOWN openssl s_clientvom Dashboard-Host zum Indexer meldet u. a.:unable to get local issuer certificateunable to verify the first certificate
Damit ist die entscheidende Aussage: Daten sind da, aber Dashboard kann sie nicht zuverlässig „konsumieren“ (TLS-Handshake/Trust bricht).
Technische Analyse
1) Warum „Indices haben Daten“ und „Dashboard zeigt No data“ gleichzeitig möglich ist
Direkte OpenSearch-API-Queries (curl -k ... https://localhost:9200/<index>/_count) belegen lediglich:
- Indexer läuft
- Indizes existieren
- Daten können abgefragt werden – für genau diesen Client/Request-Pfad
Das Dashboard hingegen nutzt einen eigenen TLS-Client (Node/OpenSearch-Dashboards Runtime) und zusätzlich plugin-spezifische Requests. Wenn dort Trust/CA-Kette oder ClientAuth-Anforderungen nicht stimmen, kann das Dashboard:
- keine oder nur sporadische Abfragen ausführen,
- Requests in Teilpfaden failen (z. B. Saved Objects, Plugin-APIs, Hintergrundjobs),
- UI-Module als „leer“ darstellen, obwohl Indizes gefüllt sind.
2) „certificate_unknown“ deutet häufig auf mTLS/Client-Zertifikate oder untrusted CA hin
Der Fehler sslv3 alert certificate unknown kommt typischerweise zustande, wenn die Gegenseite (Server) ein Zertifikat nicht akzeptiert. Das passiert z. B. bei:
- Untrusted CA / fehlende Intermediate-CA (unvollständige Kette)
- mTLS aktiviert (Server erwartet ein Client-Zertifikat; Dashboard liefert keines oder falsches)
- Zertifikat passt nicht zu Hostname/IP (SAN fehlt), was je nach Library/Setting ebenfalls zu Hard-Fails führen kann
Der openssl s_client Output „unable to get local issuer certificate“ und „unable to verify the first certificate“ ist ein klassisches Signal: Die Zertifikatskette ist nicht vollständig vertrauenswürdig aus Sicht des Clients (Dashboard-Host) – entweder weil die CA-Datei nicht stimmt oder weil der Server kein vollständiges Chain-Zertifikat präsentiert.
3) Saved Objects „leer“: nicht zwingend „Plugin fehlt“, sondern „Plugin kann nicht initialisieren“
Der Reflex „Saved Objects fehlen im Dateisystem“ ist nachvollziehbar, greift aber häufig zu kurz:
- Das Plugin ist installiert (Plugin-Liste zeigt
wazuh@4.14.1-02etc.). - Saved Objects werden nicht immer als „sichtbares Verzeichnis“ erwartet; sie können als Assets im Plugin-Paket liegen und beim Start/Init via API importiert werden.
- Wenn TLS/Authentisierung in genau diesem Init-Pfad scheitert, bleiben Saved Objects leer – und die UI wirkt „nackt“/unvollständig.
4) Multitenancy/„Tenant“-Header: kann zusätzlich irritieren, ist hier aber sekundär
Im Thread ist opensearch_security.multitenancy.enabled: false gesetzt. Das reduziert Tenant-Komplexität (nur ein Space), dennoch kann es zu Missverständnissen kommen, wenn Requests Tenant-Header tragen oder UI/Plugin tenant-basiert denkt. Entscheidend bleibt aber: Ohne stabile TLS-Verbindung sind Tenant-Fragen nur Nebengeräusche.
Lösung / Best Practices
Die nachhaltige Lösung ist: TLS sauber machen (Kette, SAN, optional mTLS), dann Saved Objects/Module neu initialisieren.
Schritt 1: Zertifikatskette zwischen Dashboard und Indexer korrekt herstellen
Ziel: openssl s_client -connect <indexer>:9200 -showcerts darf nicht mehr mit „unable to verify …“ enden (zumindest nicht, wenn du mit der richtigen CA prüfst).
Prüfpunkte:
- Server präsentiert vollständige Kette
- Das Indexer-HTTP-Zertifikat sollte idealerweise die Chain liefern (Server-Zertifikat + Intermediates).
- Wenn du eine eigene PKI nutzt: sicherstellen, dass das Zertifikat, das der Indexer ausliefert, die Kette korrekt abbildet.
- CA-Bundle auf Dashboard-Seite ist vollständig
/etc/wazuh-dashboard/certs/root-ca.pemmuss die korrekte Root-CA enthalten – und falls relevant auch Intermediate-CAs (als Bundle).- Ein häufiger Fehler: root-ca.pem enthält nicht die CA, die das Indexer-Zertifikat tatsächlich signiert hat (oder es fehlen Intermediates).
- Hostname/SAN konsistent
- In der Konfiguration steht
opensearch.hosts: ["https://127.0.0.1:9200"]. - Das Indexer-Zertifikat muss SAN=127.0.0.1 oder SAN=localhost enthalten, abhängig davon, wie du verbindest.
- Best Practice:
https://localhost:9200verwenden und Zertifikat mit SAN=localhost (und ggf. zusätzlich 127.0.0.1) ausstellen.
- In der Konfiguration steht
Schritt 2: mTLS-ClientAuth im Indexer prüfen (und ggf. entschärfen)
Wenn der Indexer auf der HTTP-Schicht Client-Zertifikate fordert, scheitert das Dashboard ohne korrekt konfiguriertes Client-Zertifikat.
Prüfe im Indexer (typisch in opensearch.yml / Security-Konfig):
- Ist HTTP ClientAuth auf REQUIRE oder OPTIONAL gesetzt?
- Erwartet der Indexer ein Client-Zertifikat, das gegen eine bestimmte CA validiert wird?
Best Practice-Entscheidung:
- Einfach/robust: kein mTLS zwischen Dashboard und lokalem Indexer (nur serverseitiges TLS + Basic Auth), wenn die Kommunikation lokal/vertrauenswürdig segmentiert ist.
- Strenger: mTLS aktiv lassen, dann aber Dashboard mit Client-Zertifikat + Key ausstatten und CA-Trust sauber konfigurieren.
Schritt 3: Dashboard-Konfiguration konsolidieren (keine „halben“ TLS-Setups)
Im Thread ist opensearch.ssl.verificationMode: none gesetzt, gleichzeitig aber opensearch.ssl.certificateAuthorities konfiguriert. Das ist operativ oft ein „Zwischenzustand“, der Fehlerbilder verschleiert.
Empfehlung:
- Für einen sauberen Betrieb:
verificationMode: fulloder mindestenscertificate(je nach Hostname/SAN-Situation) und eine korrekte CA-Kette. verificationMode: nonenur als sehr kurzfristiger Debug-Schritt – nicht als Endzustand, weil du damit echte Trust-Probleme überdeckst (und manche TLS-Probleme wie ClientAuth trotzdem nicht löst).
Schritt 4: Wazuh API TLS/Trust ebenfalls prüfen
Das Plugin zeigt auf:
https://localhost:55000(Wazuh API)
Wenn Dashboard der API ebenfalls nicht traut oder die API ein Zertifikat ohne passende Chain/SAN liefert, können Module ebenfalls „leer“ wirken (vor allem Status-/Inventar-Workflows, die API-Calls benötigen).
Prüfe analog:
openssl s_client -connect localhost:55000 -showcerts- CA-Vertrauen (Dashboard-Host) und Zertifikatskette
Schritt 5: Nach TLS-Fix Saved Objects / Assets neu laden (ohne Neuinstallation-„Blindflug“)
Wenn TLS stabil ist, kommen Saved Objects in der Regel wieder, entweder weil:
- Plugin-Initialisierung wieder erfolgreich läuft, oder
- du die Objekte gezielt neu importierst.
Best Practice für reproduzierbaren Betrieb:
- Dashboard stoppen → Cache/State nicht unkontrolliert löschen, sondern gezielt prüfen, ob es eine definierte Asset-Import-Mechanik des Plugins gibt (je nach Paket/Version).
- Dashboard starten und Logs auf erfolgreiche Plugin-Init prüfen (keine TLS-Alerts, keine Auth-Fehler, keine Saved Objects Errors).
Lessons Learned / Best Practices
- „Index enthält Daten“ beweist nicht, dass Dashboard die Module rendern kann. Entscheidend ist die vollständige Request-Kette inkl. TLS/Trust.
- TLS-Kette schlägt alles: fehlende Intermediate-CAs sind einer der häufigsten Gründe für „UI leer, Daten da“.
- mTLS ist eine häufige versteckte Ursache für
certificate_unknown– besonders wenn Sicherheitsrichtlinien oder Hardening nachträglich geändert wurden. - SAN/Hostname-Konsistenz ist Pflicht, insbesondere wenn du 127.0.0.1 statt localhost verwendest.
- Vermeide Dauerbetrieb mit
verificationMode: none: Das kaschiert Ursachen und erzeugt schwer reproduzierbare Fehlerbilder.
Fazit
In diesem Fehlerbild ist nicht die Datenerhebung das Problem, sondern die sichere Kommunikation: Dashboard kann aufgrund einer defekten/inkompletten Zertifikatskette und/oder mTLS-ClientAuth-Anforderungen nicht zuverlässig mit Indexer/API sprechen. Das führt dazu, dass Module „No data“ zeigen und Saved Objects nicht geladen/initialisiert werden. Sobald du TLS (Chain + SAN + ggf. ClientAuth) konsistent reparierst, normalisieren sich die Wazuh-Module typischerweise ohne invasive Neuinstallationen – und die UI füllt sich wieder.
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/p1765813454617399