01.1 Wazuh Installation
Einleitung
Wazuh ist mit einem einzigen Herstellerkommando erstaunlich schnell installiert. Das heißt aber noch lange nicht, dass daraus automatisch ein gut betriebener Security-Server wird. Die eigentliche Arbeit steckt in der VM, den Dateisystemen, der Zeitsynchronisation, den Netzgrenzen und einer Installation, die sich später noch nachvollziehen lässt.
Diese Seite enthält deshalb beides:
- die Rahmenbedingungen, mit denen sich Architektur und Größe sinnvoll planen lassen;
- eine echte Schritt-für-Schritt-Anleitung auf Basis meiner Installation im Homelab.
Mein Ergebnis ist eine native All-in-one-Installation von Wazuh 4.14.7 auf Rocky Linux 10.2. Manager, Indexer, Dashboard und Filebeat laufen gemeinsam auf einer Proxmox-VM. Die Anleitung ist absichtlich so geschrieben, dass man sie für eine neue Umgebung wiederverwenden kann. Interne Namen und Adressen sind als Beispiel erkennbar; Passwörter, Schlüssel und andere Secrets fehlen natürlich vollständig.
Kurz erklärt: Welche Komponenten werden installiert?
Wazuh besteht zentral aus drei Komponenten:
- Wazuh Server: nimmt Agentendaten an, dekodiert Ereignisse, wertet Regeln aus und verwaltet die Agents;
- Wazuh Indexer: indexiert und speichert Alerts und weitere sicherheitsrelevante Daten;
- Wazuh Dashboard: stellt Suche, Visualisierung und Administration bereit.
Auf den überwachten Systemen läuft normalerweise ein Wazuh-Agent. Filebeat transportiert die vom Manager erzeugten Alerts zum Indexer.
Welche Bauform passt?
| Modell | Aufbau | Geeignet für | Wesentliche Grenze |
|---|---|---|---|
| All-in-one | Server, Indexer und Dashboard auf einem Host | Labor, Homelab, kleine Umgebung | gemeinsamer Ausfallpunkt, konkurrierende Ressourcen |
| Getrennter Single-Node-Aufbau | Komponenten auf getrennten Hosts | mittlere Umgebung oder klare Ressourcentrennung | noch keine Hochverfügbarkeit |
| Multi-Node | Server- und Indexer-Cluster, optional mehrere Dashboards | hohe Ereignisrate, hohe Verfügbarkeit, große Umgebung | deutlich mehr Betriebs- und Zertifikatsaufwand |
Für zuhause oder eine kleine, kontrollierte Umgebung ist All-in-one meistens genau richtig. Man muss daraus nicht künstlich einen Cluster bauen. Allerdings sitzt dann alles in derselben VM: Ist sie weg oder die Platte voll, ist auch die komplette Sicherheitsoberfläche weg. Backup, Retention und Kapazitätsüberwachung gehören deshalb von Anfang an dazu.
Mein Aufbau im Homelab
Die folgende Installation ist kein ausgedachtes Beispiel, sondern mein konkret betriebener Aufbau. Interne Namen, IDs und Adressen sind für die öffentliche Fassung durch neutrale Dokumentationswerte ersetzt:
| Baustein | Homelab-Wert | Für eine eigene Umgebung |
|---|---|---|
| Architektur | native All-in-one-Installation | für ungefähr 1 bis 25 Agents ein guter Start |
| Hypervisor | Proxmox VE | jeder sauber unterstützte Hypervisor funktioniert |
| VM | wazuh01 |
eigene ID und eigenen Namen verwenden |
| CPU | 4 vCPU | 4 vCPU als sinnvoller kleiner Startwert |
| RAM | 12 GiB | mindestens 8 GiB; für etwas Reserve 12 GiB |
| Systemdisk | 40 GiB auf schnellem Storage | Rocky, Pakete und temporäre Updates |
| Managerdisk | 50 GiB, davon 40 GiB als LV | /var/ossec |
| Indexerdisk | 150 GiB, davon 120 GiB als LV | /var/lib/wazuh-indexer |
| Betriebssystem | Rocky Linux 10.2 Minimal | Rocky 10 war der von mir getestete RHEL-kompatible Weg |
| Hostname | wazuh01.example.internal |
dauerhaften FQDN vorab festlegen |
| Management-IP | 192.0.2.10/24 |
Beispielwert; feste Adresse oder feste DHCP-Reservierung verwenden |
| Dashboard | interner TLS-Reverse-Proxy | alternativ zunächst Wazuh-eigenes HTTPS verwenden |
| Indexer-Heap | 2 GiB fest | für diese kleine 12-GiB-All-in-one-VM bewusst gewählt |
| Zeit | drei PTB-Server mit NTS | eigene vertrauenswürdige NTS-Quellen sind ebenfalls möglich |
Eine getrennte Testumgebung wird bewusst nicht überwacht. Erwartet werden damit grob 15 bis 20 bekannte Systeme statt eines unkontrollierten Agenten-Wachstums.
Wazuh nennt für die zentralen Komponenten aktuell unter anderem RHEL 10 und CentOS Stream 10, Rocky Linux 10 aber nicht separat. Rocky 10.2 war bei mir deshalb ein bewusster Kompatibilitätstest. Pakete, Dienste, API, Indexer und SELinux funktionierten ohne distributionsspezifischen Workaround. Wer strikt innerhalb der ausdrücklich genannten Systeme bleiben möchte, verwendet für dieselben Schritte RHEL 10 oder CentOS Stream 10.
Sizing: Was empfiehlt Wazuh?
Wazuh nennt für eine All-in-one-Installation mit etwa 90 Tagen durchsuchbarer Alert-Historie folgende Richtwerte:
| Anzahl Agents | vCPU | RAM | Speicher für 90 Tage |
|---|---|---|---|
| 1–25 | 4 | 8 GiB | 50 GB |
| 25–50 | 8 | 8 GiB | 100 GB |
| 50–100 | 8 | 8 GiB | 200 GB |
Die Tabelle ist ein Startpunkt, keine Garantie. Ein einziger sehr gesprächiger Agent kann mehr Last verursachen als zwanzig ruhige Systeme. Das habe ich mit ungefiltertem Journald und Docker-Healthchecks schon recht anschaulich ausprobiert :D
Für den Wazuh Server allein nennt der Hersteller kleinere Komponentenwerte. Diese dürfen nicht mit dem Bedarf eines All-in-one-Systems verwechselt werden: Der Indexer ist der deutlich speicherhungrigere Teil.
Meine praktische Planungshilfe
| Umgebung | Architektur | Startwert CPU/RAM | Nutzbarer Datenspeicher | Hinweise |
|---|---|---|---|---|
| Labor, 1–10 Agents | All-in-one | 4 vCPU / 8 GiB | 80–150 GiB | kurze Aufbewahrung, keine HA-Anforderung |
| Homelab oder klein produktiv, 10–25 Agents | All-in-one | 4–8 vCPU / 12–16 GiB | 150–300 GiB | getrennte virtuelle Disks und tägliches Backup |
| Kleine Firma, 25–50 Agents | kräftiges All-in-one oder getrennte Komponenten | 8 vCPU / 16 GiB beim All-in-one | 250–500 GiB | Last- und Wiederherstellungstest vor Produktivstart |
| Mittel, 50–250 Agents | Server, Indexer und Dashboard trennen | komponentenbezogen ab 4–8 vCPU / 8–16 GiB | ab 500 GiB, nach Messwert | Indexer zuerst skalierbar planen |
| Groß oder hochverfügbar | Multi-Node | mindestens drei Indexer-Nodes und mehrere Server-Nodes nach Lasttest | nach APS, Replikation und Aufbewahrung | Load Balancer, Quorum, Zertifikats- und DR-Konzept erforderlich |
Spätestens in der Pilotphase sollte man Alerts und Events pro Sekunde, tägliches Indexwachstum, FIM-Umfang, Vulnerability Detection, Syscollector und laute Logquellen messen. Für Datenträger plane ich zusätzlich mindestens 20 bis 30 Prozent freie Betriebsreserve ein.
Warum drei virtuelle Disks und LVM?
Mein Layout trennt Betriebssystem, Managerdaten und Indexerdaten:
| Disk | Volume Group / Logical Volume | Mount | Brutto / LV | Reserve |
|---|---|---|---|---|
| Systemdisk | rl_wazuh/root |
/ |
40 / 30 GiB | 6,41 GiB plus Bootbereiche |
| Managerdisk | vg_wazuh_manager/lv_var_ossec |
/var/ossec |
50 / 40 GiB | knapp 10 GiB |
| Indexerdisk | vg_wazuh_indexer/lv_wazuh_indexer |
/var/lib/wazuh-indexer |
150 / 120 GiB | knapp 30 GiB |
Jede virtuelle Disk besitzt ihre eigene VG. Keine VG spannt mehrere
Proxmox-Disks auf. Damit bleiben Backup-, Fehler- und Wachstumsgrenzen
sichtbar. Wird eine Disk später in Proxmox vergrößert, folgen im Gast
pvresize und lvextend --resizefs; ext4 wächst dabei online.
/var/ossec darf nicht mit noexec gemountet werden, weil dort Wazuh-Binaries
und Active-Response-Skripte liegen. Ein bereits mit noexec gehärtetes /tmp
braucht für die Indexerinstallation außerdem die von Wazuh dokumentierte
Sonderbehandlung. Ich habe /tmp deshalb erst nach der Installation weiter
gehärtet.
Vor dem Start festlegen
Bevor die erste VM bootet, sollten diese Werte auf einem Zettel stehen:
- dauerhafter FQDN und IP-Adresse;
- Gateway und DNS-Server;
- Admin- und VPN-Netze;
- gegebenenfalls Adresse des Reverse-Proxys;
- erwartete Agentennetze;
- gewünschte Aufbewahrungsdauer;
- Speicherort für Installerarchiv, Passwörter und private Schlüssel;
- Backup- und Rückweg für die frische VM.
Die öffentliche Anleitung verwendet bewusst reservierte Beispielnetze. Wer sie nachbaut, ersetzt diese Werte durch die eigenen:
FQDN: wazuh01.example.internal
IPv4: 192.0.2.10/24
Gateway: 192.0.2.1
DNS: 192.0.2.53, 192.0.2.54
Admin-LAN: 192.0.2.0/24
VPN: 198.51.100.0/24
Reverse-Proxy: 192.0.2.20/32
Dashboard-Name: wazuh.example.internal
Schritt 1: Die Proxmox-VM anlegen
Die VM wurde mit diesen Einstellungen erstellt:
- Q35-Maschine mit OVMF/UEFI;
- Secure-Boot-Schlüssel und EFI-Disk;
- 4 vCPU und 12 GiB RAM;
- VirtIO SCSI Single;
- VirtIO-Netzwerkkarte;
- QEMU Guest Agent in der VM-Konfiguration aktiviert;
- SSD-Flag, Discard und I/O-Thread für die virtuellen Datendisks;
- 40-GiB-Systemdisk, 50-GiB-Managerdisk und 150-GiB-Indexerdisk;
- Rocky-Linux-Minimal-ISO als virtuelles DVD-Laufwerk.
Die System- und Managerdisk liegen bei mir auf dem schnellen NVMe-Storage, die größere Indexerdisk auf einem separaten SSD-Mirror. Das ist kein Muss. Für den Indexer zählt vor allem verlässliche Latenz und genügend freie Kapazität.
Ballooning ist für einen Indexer keine besonders schöne Überraschung. Wenn der Hypervisor RAM aggressiv zurückholt, konkurriert die JVM mit Manager und Dashboard. Für einen stabilen Betrieb sollte der zugesagte RAM deshalb fest oder zumindest verlässlich reserviert sein.

Der echte Start meiner Rocky-Installation – für die öffentliche Fassung auf das Installerfenster zugeschnitten.
Schritt 2: Rocky Linux Minimal installieren
Im Installer habe ich bewusst nur eine schlanke Serverbasis gewählt:
- Sprache und Tastatur kontrollieren – in der Proxmox-Konsole war bei mir
zwischenzeitlich
YundZvertauscht. Minimal Installauswählen, keine Desktopoberfläche.- Zeitzone
Europe/Berlinsetzen. - Netzwerkschnittstelle aktivieren, statische Adresse und FQDN eintragen.
- Einen persönlichen Admin-Benutzer anlegen und der Gruppe
wheelhinzufügen. - Root-Login nicht als normalen Administrationsweg verwenden.
- Nur die 40-GiB-Systemdisk für das Betriebssystem auswählen.
- Benutzerdefiniertes LVM-Layout anlegen.
Das Systemlayout bestand aus:
- EFI-Systempartition: 600 MiB, vfat;
/boot: 1 GiB, ext4;- Root-LV: 30 GiB, ext4;
- Swap-LV: 2 GiB;
- verbleibende 6,41 GiB als freie Extents in der Root-VG.
Die Manager- und Indexerdisk wurden im Installer nicht formatiert. Das kam erst nach dem ersten Boot mit zusätzlichen Sicherheitsprüfungen.

Das Root-LV belegt bewusst nicht die gesamte VG; ein kleiner Puffer bleibt für spätere Erweiterungen frei. Host- und VG-Namen sind im öffentlichen Bild neutralisiert.
Vor dem Klick auf Installation beginnen noch einmal Netzwerk, Software, Zieldisk, Zeitzone und Benutzer kontrollieren. Ein versehentlich ausgewählter Datenträger ist an dieser Stelle deutlich leichter zu korrigieren als später.

Letzter Kontrollblick vor der Installation: Software, Zieldisk, Netzwerk, Zeit und Benutzer passen zusammen.
Schritt 3: Erster Boot, Updates und Guest Agent
Nach dem ersten Login wurde Rocky vollständig aktualisiert und nur die benötigte Basis ergänzt:
sudo dnf -y update
sudo dnf -y install qemu-guest-agent lvm2 chrony curl tar
sudo systemctl enable --now qemu-guest-agent chronyd firewalld sshd
sudo reboot
Danach prüfen:
cat /etc/rocky-release
uname -r
hostnamectl
getenforce
systemctl is-active qemu-guest-agent chronyd firewalld sshd
Bei mir war das Ergebnis Rocky Linux 10.2, SELinux Enforcing und ein über die
Proxmox-API erreichbarer Guest Agent.
Das ISO wurde nach erfolgreichem Boot aus dem virtuellen CD-Laufwerk entfernt, damit die VM später nicht versehentlich wieder im Installer landet.
Schritt 4: Manager- und Indexerdisk vorbereiten
Hier bitte nicht blind /dev/sdb und /dev/sdc übernehmen. Die Zuordnung hat
sich auf meiner VM nach einem Neustart tatsächlich geändert. Vor jedem
destruktiven Schritt wurden Typ, Größe und vorhandene Signaturen geprüft:
lsblk -e7 -o NAME,PATH,SIZE,TYPE,FSTYPE,MOUNTPOINTS,MODEL,SERIAL
sudo wipefs -n /dev/sdb
sudo wipefs -n /dev/sdc
sudo blockdev --getsize64 /dev/sdb
sudo blockdev --getsize64 /dev/sdc
Erst nachdem eindeutig feststand, welche leere Disk 50 GiB und welche 150 GiB groß war, wurden PVs, VGs und LVs angelegt. In meiner Installationssitzung waren das folgende Geräte; in einer anderen VM können sie anders heißen:
sudo pvcreate /dev/sdb /dev/sdc
sudo vgcreate vg_wazuh_manager /dev/sdb
sudo vgcreate vg_wazuh_indexer /dev/sdc
sudo lvcreate --size 40G --name lv_var_ossec vg_wazuh_manager
sudo lvcreate --size 120G --name lv_wazuh_indexer vg_wazuh_indexer
sudo mkfs.ext4 -m 1 -L wazuh_ossec \
/dev/vg_wazuh_manager/lv_var_ossec
sudo mkfs.ext4 -m 1 -L wazuh_indexer \
/dev/vg_wazuh_indexer/lv_wazuh_indexer
sudo install -d -m 0755 /var/ossec /var/lib/wazuh-indexer
Die Dateisysteme wurden per UUID in /etc/fstab eingetragen. Sinngemäß sieht
das so aus:
UUID=<MANAGER-UUID> /var/ossec ext4 defaults,nodev,nosuid,x-systemd.device-timeout=30s 0 2
UUID=<INDEXER-UUID> /var/lib/wazuh-indexer ext4 defaults,nodev,nosuid,x-systemd.device-timeout=30s 0 2
Die UUIDs liefert blkid. Danach unbedingt testen:
sudo systemctl daemon-reload
sudo mount -a
sudo findmnt --verify --verbose
findmnt /var/ossec
findmnt /var/lib/wazuh-indexer
sudo pvs
sudo vgs
sudo lvs
df -hT / /var/ossec /var/lib/wazuh-indexer
Ein fehlgeschlagener Datenmount darf nicht unbemerkt dazu führen, dass Wazuh
in das Root-Dateisystem schreibt. Deshalb sind die Mounts bei mir zwingend und
nicht mit nofail versehen.
Schritt 5: SSH, Zeit und kleine OS-Baseline
Der Admin-Zugang verwendet ausschließlich SSH-Keys. Erst einen zweiten, erfolgreichen Key-Login testen und danach Passwort- und Root-Login abschalten:
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitEmptyPasswords no
X11Forwarding no
MaxAuthTries 4
LoginGraceTime 30
AllowGroups wheel
Allgemeines sudo verlangt für das menschliche Administrationskonto weiterhin
das Benutzerpasswort. Automationskonten erhalten – wenn überhaupt – nur eng
begrenzte NOPASSWD-Kommandos und kein pauschales NOPASSWD: ALL.
Für die Zeit verwende ich die ersten drei öffentlichen PTB-Server mit NTS:
server ptbtime1.ptb.de iburst nts
server ptbtime2.ptb.de iburst nts
server ptbtime3.ptb.de iburst nts
authselectmode require
ntsdumpdir /var/lib/chrony
Nach einem Chrony-Neustart prüfen:
sudo systemctl restart chronyd
chronyc tracking
chronyc sources -n
chronyc authdata
Alle drei Quellen müssen authentifiziert sein. Eine gute Uhr ist bei Wazuh kein Luxus: Zertifikate, Korrelationen und forensische Zeitlinien hängen daran.
Zusätzlich habe ich Swap nur als Notreserve konfiguriert:
vm.swappiness = 1
Die Einstellung wird beispielsweise unter /etc/sysctl.d/99-wazuh.conf
abgelegt und mit sudo sysctl --system aktiviert.
Schritt 6: Snapshot und Vorabkontrolle
Vor Wazuh wurde der Proxmox-Snapshot pre-wazuh-4_14_7 ohne RAM-Zustand
angelegt. Ein Snapshot ist kein Backup, aber für den unmittelbaren Rückweg bei
einer fehlgeschlagenen Erstinstallation sehr praktisch.
Vor dem Installer sollten diese Punkte stimmen:
hostname --fqdn
getent ahosts "$(hostname --fqdn)"
timedatectl status
getenforce
sudo findmnt --verify
df -hT / /var/ossec /var/lib/wazuh-indexer
sudo ss -lntup
Die beiden Wazuh-Datenmounts müssen wirklich aktiv und leer sein. Auf ext4 ist
ein Verzeichnis lost+found normal.
Schritt 7: Wazuh-Assistent herunterladen und festhalten
Ich habe den offiziellen Assistenten für Wazuh 4.14 verwendet:
cd /tmp
curl --fail --silent --show-error --remote-name \
https://packages.wazuh.com/4.14/wazuh-install.sh
sha256sum wazuh-install.sh
sudo install -o root -g root -m 0700 \
wazuh-install.sh /root/wazuh-install.sh
sudo /root/wazuh-install.sh --help
Der bei meinem Lauf gespeicherte SHA-256-Wert war:
8ebe9514688ace8af9445805e8887cd491dd9f95fa9d421a70f0ea012ab06f3a
Der Wert dokumentiert exakt das von mir verwendete Skript. Er ist nicht als ewiger Sollwert für jeden späteren Download gedacht – der Hersteller kann den Assistenten innerhalb eines Versionszweigs aktualisieren. Deshalb bei jeder Neuinstallation selbst herunterladen, Prüfsumme erfassen und Release Notes lesen.
Wenn
/tmpbereitsnoexecist, das Skript nicht einfach mit immer weiteren Ausnahmen irgendwie zum Laufen zwingen. Wazuh beschreibt für gehärtete Systeme eine eigene Indexer-Vorbereitung. Das Skript wurde aus/rootgestartet; die weitere Härtung von/tmpfolgte erst danach.
Schritt 8: Wazuh wirklich installieren
Der offizielle Quickstart verwendet kurz -a. Der von mir dokumentierte Aufruf war
die ausgeschriebene Variante:
sudo bash /root/wazuh-install.sh --all-in-one --overwrite
Warum --overwrite? Der Assistent wertete die bereits vorhandenen Mountpoints
/var/ossec und /var/lib/wazuh-indexer als Installationsreste, obwohl dort
nur die neuen, leeren ext4-Dateisysteme mit lost+found lagen. Ich habe vor
dem Lauf geprüft, dass es wirklich keine alte Installation und keine zu
erhaltenden Daten gab. Erst dann wurde --overwrite verwendet.
Ohne diese ganz konkrete Situation gehört --overwrite nicht gedankenlos in
jeden Installationsbefehl. Auf einem bestehenden System könnte es genau die
Daten beseitigen, die man eigentlich retten wollte.
Der Assistent installiert und verbindet:
wazuh-manager;wazuh-indexer;wazuh-dashboard;filebeat;- Zertifikate und initiale Dienstkonten.
Am Ende erscheinen Dashboard-Adresse und Admin-Passwort. Diese Ausgabe nicht in Terminalmitschnitte, Tickets oder Git kopieren.
Schritt 9: Installerarchiv und Secrets sichern
Der Assistent legt wazuh-install-files.tar an. Darin stecken Zertifikate,
private Schlüssel und Passwörter. Das Archiv ist kein gewöhnliches
Installationslog, sondern ein Secret:
sudo chown root:root wazuh-install-files.tar
sudo chmod 0600 wazuh-install-files.tar
sudo tar -O -xvf wazuh-install-files.tar \
wazuh-install-files/wazuh-passwords.txt
Die letzte Ausgabe dient nur zur einmaligen Übernahme in einen Passwort- oder Secret-Store. In meinem Projekt liegt das Archiv ausschließlich verschlüsselt außerhalb des Dokumentationsrepositorys.
Schritt 10: Pakete und Dienste kontrollieren
Direkt nach dem Assistenten:
rpm -q wazuh-manager wazuh-indexer wazuh-dashboard filebeat
systemctl is-active wazuh-indexer wazuh-manager filebeat wazuh-dashboard
systemctl is-enabled wazuh-indexer wazuh-manager filebeat wazuh-dashboard
rpm -qi wazuh-manager wazuh-indexer wazuh-dashboard filebeat \
| grep -E '^(Name|Version|Release|Signature)[[:space:]]*:'
Bei mir wurden überall Wazuh 4.14.7-Pakete installiert; alle vier Dienste waren aktiv und für den Boot aktiviert. Die RPM-Signaturen wurden ebenfalls geprüft.
Schritt 11: Indexer für die kleine All-in-one-VM einstellen
Die oft genannte Faustregel „halber RAM für den Heap“ passt schlecht, wenn
Manager, Indexer und Dashboard nur 12 GiB gemeinsam nutzen. Ich habe deshalb
im vorhandenen /etc/wazuh-indexer/jvm.options die Heap-Werte auf 2 GiB
gesetzt:
-Xms2g
-Xmx2g
In /etc/wazuh-indexer/opensearch.yml wurde Memory Lock aktiviert:
bootstrap.memory_lock: true
Der systemd-Drop-in ergänzt:
[Service]
LimitMEMLOCK=infinity
Anschließend:
sudo systemctl daemon-reload
sudo systemctl restart wazuh-indexer
systemctl show wazuh-indexer -p LimitMEMLOCK
Mit einem Indexer-Admin-Konto aus dem Secret-Store wurde danach geprüft, dass
mlockall=true und der Cluster green meldet. Das Passwort wird dabei nicht
in eine dauerhaft gespeicherte Shell-History geschrieben.
Der erste Managerstart mit Vulnerability Feed und Syscollector dauerte auf der kleinen VM etwas länger als der Paketstandard. Der von mir verwendete Drop-in setzt daher:
[Service]
TimeoutStartSec=120s
TimeoutStopSec=120s
Schritt 12: API, Indexer und Dashboard ans richtige Netz binden
In meinem All-in-one-Aufbau brauchen Wazuh-API und Indexer keine externen Listener:
127.0.0.1:55000 Wazuh Server API
127.0.0.1:9200 Wazuh Indexer API
Die API-Bindung steht in /var/ossec/api/configuration/api.yaml:
host: ['127.0.0.1']
port: 55000
https:
enabled: yes
In /etc/wazuh-indexer/opensearch.yml ist der einzelne Indexer ebenfalls an
Loopback gebunden:
network.host: 127.0.0.1
Der Browser greift bei mir über den vorhandenen internen Reverse-Proxy zu:
Browser -- HTTPS --> wazuh.example.internal / Reverse-Proxy
-- HTTP --> wazuh01.example.internal:5601
Das Dashboard lauscht deshalb intern auf 0.0.0.0:5601 ohne eigenes TLS.
Firewalld erlaubt diesen Port ausschließlich von 192.0.2.20/32. Der
Indexer bleibt auch für das Dashboard über HTTPS auf Loopback angebunden.
Die entscheidenden Dashboard-Werte in
/etc/wazuh-dashboard/opensearch_dashboards.yml lauten bei mir:
server.host: 0.0.0.0
server.port: 5601
server.ssl.enabled: false
opensearch.hosts: https://127.0.0.1:9200
opensearch_security.cookie.secure: true
Im Nginx Proxy Manager ist dazu ein Proxy Host mit diesen Werten angelegt:
| Feld | Wert bei mir |
|---|---|
| Domain | wazuh.example.internal |
| Scheme | http |
| Forward Host | wazuh01.example.internal |
| Forward Port | 5601 |
| Browserseite | HTTPS mit intern vertrauenswürdigem Zertifikat |
Nach Änderungen wurden Indexer, API beziehungsweise Dashboard gezielt neu
gestartet und die Listener erneut mit ss -lntup kontrolliert.
Wer keinen Reverse-Proxy einsetzt, lässt zunächst die vom Assistenten erzeugte HTTPS-Konfiguration des Dashboards bestehen. Niemals den unverschlüsselten Port 5601 pauschal für ein ganzes LAN oder gar das Internet öffnen.
Schritt 13: Firewalld auf die echten Wege begrenzen
Mein finaler Listener- und Firewallplan lautet:
| Zielport | Quelle | Zweck |
|---|---|---|
| 22/TCP | Admin-LAN und VPN | SSH |
| 1514/TCP | vorgesehene Agentennetze | dauerhafte Agentenkommunikation |
| 1515/TCP | nur Haupt-LAN | Enrollment |
| 5601/TCP | exakt der Reverse-Proxy | Dashboard-Backend |
| 55000/TCP | keine externe Freigabe | API bleibt lokal |
| 9200/TCP | keine externe Freigabe | Indexer bleibt lokal |
| 9300–9400/TCP | keine externe Freigabe | kein Indexer-Cluster vorhanden |
Beispiel für die Agentenkommunikation aus dem Haupt-LAN:
sudo firewall-cmd --permanent --zone=public \
--add-rich-rule='rule family="ipv4" source address="192.0.2.0/24" port port="1514" protocol="tcp" accept'
Vor dem Entfernen einer pauschalen SSH-Freigabe immer zuerst die neue, eingeschränkte Regel setzen und in einer zweiten SSH-Sitzung testen. Danach können unbenötigte Dienste wie Cockpit aus der Zone entfernt werden:
sudo firewall-cmd --permanent --zone=public --remove-service=cockpit
sudo firewall-cmd --reload
sudo firewall-cmd --zone=public --list-all
sudo ss -lntup
Cockpit selbst ist auf meiner Wazuh-VM nicht installiert.
Schritt 14: Wazuh-Repository nach der Installation deaktivieren
Wazuh empfiehlt, das Paketrepository nach erfolgreicher Installation zu deaktivieren. Damit läuft nicht versehentlich nur eine zentrale Komponente auf eine neue Version:
sudo sed -i 's/^enabled=1/enabled=0/' /etc/yum.repos.d/wazuh.repo
grep -E '^(\[|enabled=)' /etc/yum.repos.d/wazuh.repo
Wazuh-Updates finden bei mir nur in einem dokumentierten Wartungsfenster nach Backup, Release-Note-Prüfung und Funktionstest statt. Normale Rocky- Sicherheitsupdates werden davon getrennt behandelt.
Schritt 15: Neustart und erste technische Abnahme
Zum Abschluss wurde die VM kontrolliert neu gestartet. Danach liefen diese Prüfungen:
rpm -q wazuh-manager wazuh-indexer wazuh-dashboard filebeat
systemctl is-active wazuh-indexer wazuh-manager filebeat wazuh-dashboard
systemctl is-enabled wazuh-indexer wazuh-manager filebeat wazuh-dashboard
sudo /var/ossec/bin/wazuh-control status
sudo ss -lntup
sudo firewall-cmd --zone=public --list-all
sysctl vm.swappiness
systemctl show wazuh-indexer -p LimitMEMLOCK
getenforce
sudo ausearch -m AVC,USER_AVC -ts boot -i
df -hT / /var/ossec /var/lib/wazuh-indexer
Mein Sollzustand war:
- vier zentrale Dienste aktiv und beim Boot aktiviert;
- Indexer
green, ein Node, keine unzugewiesenen Shards; mlockall=trueundLimitMEMLOCK=infinity;vm.swappiness=1;- SELinux weiterhin
Enforcing, keine neuen AVC-Verweigerungen; - API und Indexer nur auf Loopback;
- Dashboard nur über den TLS-Reverse-Proxy erreichbar;
- genügend freie Blöcke und Inodes auf allen drei Dateisystemen.
Die vollständige Sammlung der Prüfkommandos steht auf der nächsten Seite: Wazuh Installation prüfen.
Was bei meinem Aufbau alles schief gelaufen ist :D
Ein paar Dinge waren erst beim echten Aufbau sichtbar:
- Der Rocky-Installer und die Proxmox-Konsole hatten zunächst ein vertauschtes Tastaturlayout. Bei Passwörtern merkt man das leider gern erst später.
- Linux vertauschte nach einem Neustart die Namen der zusätzlichen Disks.
Persistente Mounts müssen deshalb UUIDs verwenden;
/dev/sdXist keine dauerhafte Identität (sollte aber ja sowieso standard sein, oder?). - Leere, bereits gemountete ext4-Dateisysteme wurden vom Wazuh-Assistenten als
Installationsreste erkannt.
--overwritewar hier begründet, ist aber kein allgemeiner Standardparameter. - Ein 6-GiB-Indexer-Heap hätte auf der 12-GiB-All-in-one-VM Manager und Dashboard unnötig unter Druck gesetzt. Praktisch funktionieren 2 GiB für die kleine Zahl meiner Agents besser.
- Der Manager brauchte beim ersten Feed-Start mehr als 45 Sekunden. Ein dokumentiertes 120-Sekunden-Timeout ist sinnvoller als einen gesunden Start vorschnell abzubrechen.
- Das selbstsignierte Dashboard-Zertifikat war für den ersten lokalen Test okay, aber nicht für den dauerhaften Browserzugriff. Deshalb endet TLS heute am vorhandenen internen Reverse-Proxy.
Genau solche Punkte sind der Grund, warum die Installation nicht beim Assistentenkommando endet.
Danach geht es mit der Grundkonfiguration weiter
Nach der technischen Installation folgen getrennt:
- persönliche Admin-, Read-only- und Reporting-Konten;
- Agent Enrollment und Gruppen;
- Rollen für Docker, Nextcloud, Reverse-Proxy und andere Dienste;
- Alarmierung über E-Mail und weitere Kanäle;
- tägliche Betriebs- und wöchentliche Sicherheitsberichte;
- Retention, Indexer-Snapshots, Backups und Restore-Tests.
Das steht bewusst im Artikel Wazuh Grundkonfiguration, damit Installation und späterer Betrieb nicht wieder zu einem einzigen langen „müsste man mal“-Block werden.
No comments to display
No comments to display