Enterprise SIEM in the Lab: Deploying Wazuh 4.14 Across Active Directory, Linux, and Hypervisors

Written by

in

,

Firewalls and VLANs protect your perimeter, but they tell you almost nothing about what happens inside an operating system once a machine is on your network. If an admin account gets brute-forced, an unauthorized USB stick is plugged into a hypervisor, or a configuration file changes unexpectedly, standard firewalls are completely blind to it.

To bring real enterprise visibility to my lab, I built a dedicated virtual machine running Wazuh 4.14 SIEM. It collects security telemetry, monitors file integrity, audits vulnerabilities, and watches every Windows domain controller, Linux Docker host, and hypervisor in the rack. Here is how I set it up and the exact gotchas I ran into during fleet enrollment.

1. The Dedicated SIEM Architecture

Wazuh is resource-heavy—running the Manager, Elasticsearch-based Indexer, and Dashboard together will easily eat 8 to 12 GB of RAM. Rather than crowding my primary application server, I provisioned a dedicated Ubuntu cloud-init VM on XCP-ng (wazuh01 at 10.1.20.21) with 4 vCPUs, 12GB RAM, and 150GB disk.

Wazuh runs single-node via Docker in /opt/wazuh/wazuh-docker-4.14.8/single-node:

Service / Port Protocol Purpose
1514/tcp Wazuh Agent Events Encrypted real-time event streaming from endpoints
1515/tcp Agent Enrollment (authd) Secure automated agent key negotiation
514/udp Syslog Ingestion Firewall and switch log aggregation from UDM Pro
443/tcp Wazuh Dashboard Web UI secured by local Root CA (https://wazuh.ittechstl.local)
9200 / 55000 Indexer & REST API Bound strictly to 127.0.0.1 for security

2. Gotcha #1: The Hardcoded Dashboard Password Bug

Right after initial deployment, the web dashboard loaded cleanly, but showed an immediate red alert: “API connections down (check-api 401 Unauthorized).”

Here was the trap: I changed API_PASSWORD in docker-compose.yml, but Wazuh’s dashboard container has an internal config file (config/wazuh_dashboard/wazuh.yml) that hardcodes the default password (MyS3cr37P450r.*-). Updating compose did not update wazuh.yml.

The Fix: Whenever you rotate the Wazuh API or admin passwords, you must update both the compose environment variables AND the password: string inside wazuh.yml, then restart the dashboard container.

3. Gotcha #2: Locking Down Agent Enrollment

By default, Wazuh’s authd enrollment daemon will register any device that sends a request. In a lab where I test untrusted client laptops and IoT devices, that is dangerous. I locked down enrollment by requiring a pre-shared registration password in /var/ossec/etc/ossec.conf:

<auth>
  <disabled>no</disabled>
  <port>1515</port>
  <use_password>yes</use_password>
  <purge>yes</purge>
</auth>

The registration secret was generated and stored securely in Vaultwarden. Any agent trying to register without this key is immediately rejected.

4. Enrolling the Fleet: Windows & Linux

With enrollment secured, I deployed agents across our core hosts:

  1. Windows Domain Controller (AD1) & Hyper-V (HV2): Deployed the Wazuh MSI package remotely via PowerShell WinRM, setting the manager address and registration password as MSI arguments.
  2. Linux Docker Hosts (docker02, zabbix01): Wrote an automated shell script (install-wazuh-agent.sh) that downloads the official apt repository, pins the package version, registers via agent-auth, and starts the systemd daemon.
  3. The .local DNS Gotcha: Hosts without an explicit DNS search domain (like isolated utility VMs) failed to resolve wazuh.ittechstl.local because Ubuntu’s systemd-resolved treats .local as mDNS (Bonjour). The fix was pointing agents directly to the manager’s static IP (10.1.20.21).

5. What We Catch in Real Time

Having Wazuh watching the environment has already paid off:

  • File Integrity Monitoring (FIM): It watches /etc/, Caddy configs, and Windows system directories. If a configuration file or certificate changes, Wazuh logs the exact diff and the user who modified it.
  • Active Directory Audit Logging: Every failed Kerberos login, locked account, and administrative group modification on AD1 generates a structured security event.
  • Vulnerability Auditing: Wazuh correlates installed package versions against NIST CVE databases daily, highlighting outdated packages across our Linux VMs before attackers can target them.

Running a true SIEM turns cybersecurity from guesswork into concrete, actionable data. It takes tuning, but it gives us enterprise-grade threat detection right inside our own rack.