Wazuh Security Audit: 12-Punkte-Härtung der SIEM-Infrastruktur
Wazuh Security Audit: 12-Punkte-Härtung der SIEM-Infrastruktur
Inhaltsverzeichnis
- Zusammenfassung
- Ausgangslage & Audit-Ergebnis
- 1. Custom Rules Deployment
- 2. Agent Enrollment absichern
- 3. Mailcow Log-Integration
- 4. Docker Event Monitoring
- 5. Linux Audit Daemon (auditd)
- 6. SCA-Policy für Ubuntu 24.04
- 7. Active Response auf Host-Agent
- 8. Docker Daemon Log-Forwarding
- 9. Zentralisierte Agent-Konfiguration
- 10. VirusTotal Integration
- 11. Docker Socket Härtung
- Ergebnis & Baseline
- Nützliche Befehle
Zusammenfassung
Nach dem initialen Wazuh-Deployment und der ersten Hardening-Runde (Gotify-Integration, Config-Fix, Custom Rules) wurde ein umfassendes Security Audit der gesamten SIEM-Infrastruktur durchgeführt. Dabei wurden 12 Schwachstellen in den Kategorien CRITICAL, HIGH und MEDIUM identifiziert und systematisch behoben.
Ausgangslage & Audit-Ergebnis
Das Security Audit wurde auf dem Produktivserver durchgeführt. Die Prüfung umfasste:
- Laufende ossec.conf vs. Repository-Version
- Custom Rules Deployment-Status
- Agent-Konfiguration und Enrollment-Sicherheit
- Log-Quellen-Abdeckung (fehlende Quellen)
- Active Response Funktionalität
- Host-Level Security (auditd, Docker Socket, SCA)
- Integration-Status (Gotify, VirusTotal, E-Mail)
Identifizierte Schwachstellen
#1: Custom Rules nicht deployed
Die Datei matzka_rules.xml mit 28 Service-spezifischen Rules fehlte auf dem Server. Nur docker_rules.xml und traefik_rules.xml waren vorhanden. Alle Brute-Force-Erkennungen für Nextcloud, Authentik, Grafana etc. waren somit inaktiv.
#2: Active Response läuft im Container statt auf dem Host
Die firewall-drop Kommandos waren mit <location>local</location> konfiguriert. Da der Wazuh-Manager im Container ohne NET_ADMIN-Capability läuft, scheiterte jeder iptables-Aufruf. IPs wurden nie blockiert.
#3: Agent Enrollment ohne Passwort
<use_password>no</use_password> – Jeder konnte sich ohne Authentifizierung als Agent registrieren.
#4: Mailcow-Logs nicht überwacht
Postfix, Dovecot und Rspamd Logs des E-Mail-Servers wurden nicht an Wazuh weitergeleitet.
#5: Kein auditd installiert
Der Linux Audit Daemon war nicht installiert – keine Syscall-Level-Überwachung für Privilege Escalation, Dateizugriffe oder Kernel-Module.
#6: Docker Socket world-writable (666)
/var/run/docker.sock war für alle Benutzer schreibbar – ein bekannter Privilege-Escalation-Vektor.
#7-12: Weitere Findings
Docker Event Monitoring deaktiviert, keine SCA-Policy für Ubuntu 24.04, Docker Daemon Logs fehlend, keine zentralisierte Agent-Konfiguration, VirusTotal API Key in Klartext.
1. Custom Rules Deployment
matzka_rules.xml auf Server deployed
28 Custom Rules für alle matzka.cloud Services jetzt aktiv. Gesamtzahl: 47 Custom Rules.
Die Datei matzka_rules.xml war im lokalen Repository vorhanden, wurde aber
nie auf den Server übertragen. Nach dem Deployment und Neustart des Managers
wurden alle 47 Custom Rules korrekt geladen.
Abgedeckte Services
| ID-Range | Service | Erkennungstypen |
|---|---|---|
100001-100009 |
Nextcloud | Auth-Fehler, Brute-Force (5 Fehler/2 Min), Admin-Zugriff |
100010-100019 |
Grafana | Login-Fehler, Brute-Force (3 Fehler/1 Min) |
100020-100029 |
Authentik SSO | Login-Fehler, Brute-Force (3 Fehler/2 Min, CRITICAL) |
100030-100039 |
n8n | Auth-Fehler, Unauthorized API-Zugriff |
100040-100059 |
PostfixAdmin, Roundcube | Login-Fehler, Brute-Force |
100060-100069 |
WebApp | Scanner-Erkennung, SQL Injection, XSS |
100090-100099 |
Traefik (Basis) | DDoS, 5xx-Fehler, SSL-Probleme |
100300-100399 |
Docker | Container-Stops, Restart Loops, OOM, Privileged Container |
100400-100499 |
Traefik (Erweitert) | Backend-Fehler, TLS-Probleme, Path Traversal, Scanner |
Verifikation
# Rules auf Server prüfen
docker exec wazuh-manager ls /var/ossec/etc/rules/custom/
# matzka_rules.xml docker_rules.xml traefik_rules.xml
# Geladene Rules zählen
docker exec wazuh-manager /var/ossec/bin/wazuh-logtest 2>&1 | grep "rules loaded"
# INFO: 47 rules loaded (custom)
2. Agent Enrollment absichern
Enrollment-Passwort aktiviert
Agent-Registrierung erfordert jetzt ein Passwort. Unautorisierte Agents können sich nicht mehr verbinden.
Ohne Enrollment-Passwort konnte jeder, der Port 1515 erreicht, einen Agent registrieren und potentiell falsche Daten in das SIEM einspeisen. Die Absicherung erfolgte in zwei Schritten:
<use_password>no</use_password>Jeder kann Agents registrieren
<use_password>yes</use_password>Registrierung nur mit Passwort
# 1. Zufälliges Passwort generiert
openssl rand -base64 16 > /var/ossec/etc/authd.pass
chmod 640 /var/ossec/etc/authd.pass
chown root:wazuh /var/ossec/etc/authd.pass
# 2. ossec.conf angepasst
# <use_password>yes</use_password>
# 3. Agent-Registrierung erfordert jetzt:
/var/ossec/bin/agent-auth -m wazuh.manager -P "enrollment-password"
3. Mailcow Log-Integration
E-Mail-Server-Logs in Wazuh integriert
Postfix, Dovecot und Rspamd Logs werden jetzt via systemd-Service an Wazuh weitergeleitet.
Mailcow läuft als separate Docker-Compose-Instanz in /opt/mailcow-dockerized/.
Die Logs sind nicht direkt als Dateien verfügbar, sondern nur über docker logs.
Ein systemd-Service leitet sie in Dateien um, die Wazuh lesen kann.
Architektur
systemd Service
# /etc/systemd/system/mailcow-log-forward.service
[Unit]
Description=Forward Mailcow container logs to files
After=docker.service
[Service]
Type=simple
ExecStart=/bin/bash -c '\
docker logs -f postfix-mailcow 2>&1 >> /var/log/mailcow/postfix.log & \
docker logs -f dovecot-mailcow 2>&1 >> /var/log/mailcow/dovecot.log & \
docker logs -f rspamd-mailcow 2>&1 >> /var/log/mailcow/rspamd.log & \
wait'
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
ossec.conf Einträge
<!-- Mailcow email server logs -->
<localfile>
<log_format>syslog</log_format>
<location>/mailcow-logs/postfix.log</location>
</localfile>
<localfile>
<log_format>syslog</log_format>
<location>/mailcow-logs/dovecot.log</location>
</localfile>
<localfile>
<log_format>syslog</log_format>
<location>/mailcow-logs/rspamd.log</location>
</localfile>
Docker Volume Mount
# In docker-compose.yml (Wazuh Manager)
volumes:
- /var/log/mailcow:/mailcow-logs:ro
4. Docker Event Monitoring
Docker Event Listener aktiviert
Wazuh überwacht jetzt Docker-Events (Container erstellt, gestoppt, Netzwerk-Änderungen) über den Docker Socket.
Der Wazuh DockerListener Wodle benötigt das Python-Paket docker und
Zugriff auf den Docker Socket. Da Container-Dateisysteme bei Neustart verloren gehen,
wurde ein s6-Init-Script erstellt, das die Abhängigkeit automatisch installiert.
Persistente Installation via s6-overlay
# /etc/cont-init.d/99-docker-listener-init (im Container)
#!/bin/bash
# Auto-install Docker SDK for DockerListener wodle
if ! /var/ossec/framework/python/bin/python3 -c "import docker" 2>/dev/null; then
/var/ossec/framework/python/bin/pip3 install docker --quiet
fi
/etc/cont-init.d/ werden bei jedem Container-Start
ausgeführt – so geht die Docker-SDK-Installation nicht verloren.
Konfiguration
<!-- ossec.conf: Docker Event Monitoring -->
<wodle name="docker-listener">
<disabled>no</disabled>
<interval>10m</interval>
<attempts>5</attempts>
<run_on_start>yes</run_on_start>
</wodle>
# docker-compose.yml: Docker Socket Mount
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./config/wazuh_cluster/docker-listener-init.sh:/etc/cont-init.d/99-docker-listener-init:ro
5. Linux Audit Daemon (auditd)
auditd installiert mit 36 Audit-Regeln
Syscall-Level-Überwachung für Dateiänderungen, Privilege Escalation, Kernel-Module und Docker-Operationen.
Der Linux Audit Daemon (auditd) ermöglicht die Überwachung von
Systemaufrufen auf Kernel-Ebene. Dies ist eine Schicht tiefer als das, was Wazuh
alleine überwachen kann. Die Audit-Logs werden automatisch von Wazuh analysiert.
Installierte Audit-Regeln
| Kategorie | Key | Überwachung |
|---|---|---|
| Identität | identity |
/etc/passwd, /etc/shadow, /etc/group, /etc/gshadow |
| Logins | logins |
/var/log/faillog, /var/log/lastlog, /var/log/tallylog |
| Sessions | session |
/var/run/utmp, /var/log/btmp, /var/log/wtmp |
| Sudo/SSH | sudoers, sshd-config |
/etc/sudoers, /etc/sudoers.d, /etc/ssh/sshd_config |
| Netzwerk | network-config |
/etc/hosts, /etc/resolv.conf, /etc/iptables |
| Cron/Systemd | cron |
/etc/crontab, /etc/cron.d, /etc/systemd/system |
| Docker | docker-config, docker-socket, docker-command |
/etc/docker, /var/run/docker.sock, /usr/bin/docker |
| Kernel | kernel-modules |
Syscalls: init_module, delete_module, finit_module |
| Privilege Escalation | privilege-escalation |
Syscalls: setuid, setgid, setreuid, setregid |
| Root Commands | root-command |
Alle Execve-Aufrufe durch UID 0 |
| Datei-Löschung | file-deletion |
Syscalls: unlink, unlinkat, rename, renameat |
mail-config |
/etc/postfix, /etc/aliases, /etc/ssmtp |
Installation und Konfiguration
# Installation
apt install -y auditd audispd-plugins
# Regeln deployen
cat > /etc/audit/rules.d/wazuh.rules << 'EOF'
# Identity changes
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/gshadow -p wa -k identity
# Login monitoring
-w /var/log/faillog -p wa -k logins
-w /var/log/lastlog -p wa -k logins
# Docker monitoring
-w /etc/docker -p wa -k docker-config
-w /var/run/docker.sock -p wa -k docker-socket
-w /usr/bin/docker -p x -k docker-command
# Kernel module loading
-a always,exit -F arch=b64 -S init_module -S delete_module -S finit_module -k kernel-modules
# Privilege escalation
-a always,exit -F arch=b64 -S setuid -S setgid -S setreuid -S setregid -k privilege-escalation
# ... (36 Regeln insgesamt)
EOF
# Regeln laden
augenrules --load
systemctl enable auditd
Wazuh Integration
<!-- ossec.conf: Audit Log als Quelle -->
<localfile>
<log_format>audit</log_format>
<location>/host-logs/audit/audit.log</location>
</localfile>
6. SCA-Policy für Ubuntu 24.04
CIS Benchmark für Ubuntu 24.04 aktiviert
Security Configuration Assessment mit 99 Prüfpunkten. Baseline: 46 bestanden, 53 nicht bestanden.
Wazuh liefert standardmäßig SCA-Policies für Ubuntu 22.04 mit. Da der Server Ubuntu 24.04 verwendet, wurde die Anforderungsprüfung der Policy auf die aktuelle OS-Version angepasst. Die ursprüngliche Policy wurde deaktiviert, um doppelte Check-IDs zu vermeiden.
Problem und Lösung
cis_ubuntu22-04.ymlRequirement Check:
r:Ubuntu 22.04Ergebnis: Übersprungen auf Ubuntu 24.04
cis_ubuntu24-04.ymlRequirement Check:
r:Ubuntu 24.04Ergebnis: 99 Checks ausgeführt
# Auf dem Agent (Host):
mv /var/ossec/ruleset/sca/cis_ubuntu22-04.yml \
/var/ossec/ruleset/sca/cis_ubuntu22-04.yml.disabled
systemctl restart wazuh-agent
SCA Baseline-Ergebnis
| Status | Anzahl | Beispiele |
|---|---|---|
| Bestanden | 46 | SSH-Härtung, Kernel-Parameter, Dateiberechtigungen |
| Nicht bestanden | 53 | Audit-Policies (inzwischen behoben), Partitionierung, PAM-Konfiguration |
| Gesamt | 99 | CIS Benchmark Level 1 + Level 2 |
7. Active Response auf Host-Agent umleiten
firewall-drop läuft jetzt auf dem Host-Agent
Active Response Kommandos werden an Agent 001 (Host) delegiert, der iptables-Zugriff hat. IP-Blockierung funktioniert nun korrekt.
Dies war das kritischste Problem: Active Response war konfiguriert, blockierte aber
nie eine IP. Der Grund: firewall-drop ruft iptables auf,
was im Wazuh-Manager-Container mangels NET_ADMIN-Capability fehlschlug.
Änderung an allen drei Active-Response-Blöcken
<active-response>
<command>firewall-drop</command>
<location>local</location>
<!-- Scheitert: Container hat
kein NET_ADMIN! -->
</active-response>
<active-response>
<command>firewall-drop</command>
<location>defined-agent</location>
<agent_id>001</agent_id>
<!-- Agent auf dem Host hat
iptables-Zugriff -->
</active-response>
Verifizierung: IP blockiert
# Nach einem SSH-Brute-Force-Angriff:
iptables -L INPUT -n | grep DROP
# Ergebnis:
DROP all -- 203.0.113.42 0.0.0.0/0
# Active Response Log:
cat /var/ossec/logs/active-responses.log
# Fri Jan 29 14:23:17 CET 2026 /var/ossec/active-response/bin/firewall-drop add
# - 203.0.113.42 1738155797.12345 5710 - -
- SSH Brute-Force (Rules 5710-5716): 10 Minuten IP-Block
- Authentication Failures (Rules 5503-5504): 5 Minuten IP-Block
- Web-Service Brute-Force (Rules 100002, 100012, 100021, 100041, 100051): 15 Minuten IP-Block
defined-agent mit agent_id=001 (Host).
8. Docker Daemon Log-Forwarding
Docker Daemon Logs über journald exportiert
Docker-Daemon-Fehler und Warnungen werden über einen systemd-Service in eine Datei exportiert und von Wazuh analysiert.
# /etc/systemd/system/docker-journal-export.service
[Unit]
Description=Export Docker daemon journal to file
After=docker.service
[Service]
Type=simple
ExecStart=/bin/bash -c 'journalctl -u docker -f >> /var/log/docker-daemon.log'
Restart=always
[Install]
WantedBy=multi-user.target
<!-- ossec.conf -->
<localfile>
<log_format>syslog</log_format>
<location>/host-logs/docker-daemon.log</location>
</localfile>
9. Zentralisierte Agent-Konfiguration
Zentrale agent.conf für alle Agents
SCA-Policy, erweiterte FIM-Verzeichnisse und Audit-Log-Quellen werden zentral vom Manager an Agents verteilt.
Statt jeden Agent einzeln zu konfigurieren, verteilt der Manager eine zentrale
agent.conf an alle Agents der Default-Gruppe. Dies umfasst:
Zentral verwaltete FIM-Verzeichnisse
<agent_config>
<syscheck>
<!-- SSH-Konfiguration -->
<directories check_all="yes" realtime="yes" report_changes="yes">
/etc/ssh
</directories>
<!-- Sudo-Konfiguration -->
<directories check_all="yes" realtime="yes" report_changes="yes">
/etc/sudoers.d
</directories>
<!-- Cron-Jobs -->
<directories check_all="yes" realtime="yes">
/etc/cron.d,/etc/cron.daily,/etc/cron.hourly
</directories>
<!-- systemd Service-Dateien -->
<directories check_all="yes" realtime="yes" report_changes="yes">
/etc/systemd/system
</directories>
<!-- Docker-Konfiguration -->
<directories check_all="yes" realtime="yes" report_changes="yes">
/etc/docker
</directories>
<!-- Infrastructure-as-Code -->
<directories check_all="yes" realtime="yes" report_changes="yes">
/opt/docker/compose,/opt/docker/security
</directories>
</syscheck>
<!-- SCA Policy -->
<sca>
<enabled>yes</enabled>
<policies>
<policy>cis_ubuntu24-04.yml</policy>
</policies>
</sca>
<!-- Audit-Logs -->
<localfile>
<log_format>audit</log_format>
<location>/var/log/audit/audit.log</location>
</localfile>
</agent_config>
10. VirusTotal Integration
API Key in ossec.conf (Wazuh 4.9 Limitation)
Wazuh 4.9 unterstützt keine Dateireferenzen für <api_key> in Integrationsblöcken. Der Key bleibt in der ossec.conf.
Die VirusTotal-Integration prüft geänderte Dateien (erkannt durch FIM/Syscheck) automatisch
gegen die VirusTotal-Datenbank. Es wurde versucht, den API Key in eine externe Datei auszulagern,
aber Wazuh 4.9 unterstützt dies nicht für das <api_key>-Element.
<!-- VirusTotal Integration (aktiv) -->
<integration>
<name>virustotal</name>
<api_key>VT_API_KEY</api_key> <!-- Kann nicht externalisiert werden -->
<group>syscheck</group>
<alert_format>json</alert_format>
</integration>
11. Docker Socket Härtung
Docker Socket Berechtigungen auf 660 gesetzt
Persistente Berechtigung via systemd Drop-in. Nur root und docker-Gruppe haben Zugriff.
srw-rw-rw- docker.sock (666)Jeder Benutzer kann Docker-Befehle ausführen – Privilege Escalation möglich
srw-rw---- docker.sock (660)Nur root und docker-Gruppe – Standard-Linux-Sicherheit
# Persistente Berechtigung via systemd Drop-in
mkdir -p /etc/systemd/system/docker.service.d
cat > /etc/systemd/system/docker.service.d/socket-permissions.conf << 'EOF'
[Service]
ExecStartPost=/bin/chmod 660 /var/run/docker.sock
EOF
systemctl daemon-reload
systemctl restart docker
docker run -v /:/mnt
--privileged genügt für vollständigen Host-Zugriff.
Ergebnis & Monitoring-Architektur
Nach Abschluss aller 12 Maßnahmen ist die Wazuh-SIEM-Infrastruktur umfassend gehärtet. Die folgende Übersicht zeigt die gesamte Log-Pipeline und Benachrichtigungsarchitektur.
Vollständige Log-Quellen (11)
| # | Log-Quelle | Format | Pfad im Container |
|---|---|---|---|
| 1 | auth.log | syslog | /host-logs/auth.log |
| 2 | syslog | syslog | /host-logs/syslog |
| 3 | kern.log | syslog | /host-logs/kern.log |
| 4 | Traefik Access Log | json | /traefik-logs/access.log |
| 5 | Linux Audit Log | audit | /host-logs/audit/audit.log |
| 6 | Postfix (Mailcow) | syslog | /mailcow-logs/postfix.log |
| 7 | Dovecot (Mailcow) | syslog | /mailcow-logs/dovecot.log |
| 8 | Rspamd (Mailcow) | syslog | /mailcow-logs/rspamd.log |
| 9 | Fail2ban | syslog | /fail2ban-logs/fail2ban.log |
| 10 | Docker Daemon | syslog | /host-logs/docker-daemon.log |
| 11 | Active Responses | syslog | /var/ossec/logs/active-responses.log |
Benachrichtigungskanäle
| Kanal | Trigger | Ziel |
|---|---|---|
| Gotify Push | Alert Level ≥ 7 | gotify.matzka.cloud (Mobile App) |
| E-Mail (SMTP) | Alert Level ≥ 10 | reinhard@matzka.cloud |
| Active Response | Brute-Force Rules | iptables DROP auf Host-Agent |
| Wazuh Dashboard | Alert Level ≥ 3 | siem.matzka.cloud |
| Prometheus Exporter | Metriken (kontinuierlich) | monitor.matzka.cloud (Grafana) |
Host-Level Services
| Service | Zweck | Status |
|---|---|---|
wazuh-agent |
Host-Monitoring, FIM, Active Response | enabled & running |
auditd |
Syscall-Level Überwachung (36 Regeln) | enabled & running |
mailcow-log-forward |
Mailcow Container Logs → Dateien | enabled & running |
docker-journal-export |
Docker Daemon Journal → Datei | enabled & running |
- 12 Schwachstellen identifiziert (2 CRITICAL, 4 HIGH, 6 MEDIUM)
- 11 vollständig behoben, 1 als Wazuh-Limitation dokumentiert
- 47 Custom Detection Rules aktiv (über 3 Rule-Dateien)
- 36 Audit-Regeln für Syscall-Level-Überwachung
- 11 Log-Quellen aktiv + Docker Event Monitoring
- 3-stufiges Active Response mit verifizierter IP-Blockierung
- CIS Benchmark Baseline: 46/99 bestanden
- 5 Benachrichtigungskanäle (Gotify, E-Mail, AR, Dashboard, Prometheus)
Nützliche Befehle
Wazuh Manager
# Manager-Status prüfen
docker exec wazuh-manager /var/ossec/bin/wazuh-control status
# Agent-Status abfragen
docker exec wazuh-manager /var/ossec/bin/agent_control -l
# Custom Rules prüfen
docker exec wazuh-manager ls -la /var/ossec/etc/rules/custom/
# Log-Test-Modus
docker exec -it wazuh-manager /var/ossec/bin/wazuh-logtest
# ossec.conf prüfen
docker exec wazuh-manager cat /var/ossec/etc/ossec.conf | grep smtp_server
# Manager neu starten
docker compose restart wazuh.manager
Host Agent
# Agent-Status
systemctl status wazuh-agent
# Active Response Log (IP-Blockierungen)
tail -f /var/ossec/logs/active-responses.log
# Aktuell blockierte IPs
iptables -L INPUT -n | grep DROP
# auditd Status und Regelanzahl
auditctl -s
auditctl -l | wc -l
# SCA Scan manuell auslösen
/var/ossec/bin/wazuh-control restart
Troubleshooting
# DockerListener prüfen
docker exec wazuh-manager /var/ossec/framework/python/bin/python3 -c "import docker; print('OK')"
# Gotify-Integration testen (Alert wird gesendet)
docker exec wazuh-manager cat /var/ossec/logs/integrations.log
# Mailcow-Logs prüfen
ls -la /var/log/mailcow/
systemctl status mailcow-log-forward
# Docker Daemon Logs
systemctl status docker-journal-export
tail -20 /var/log/docker-daemon.log