Introduction to Wazuh SIEM on Docker
We observed that standard bare-metal Wazuh SIEM deployments often fail during rapid scaling due to dependency conflicts between the manager and the indexer nodes. Moving to a containerized architecture solves the "it works on my machine" problem while providing an isolated environment for the Indexer, Manager, and Dashboard components. In our testing, a Docker-based Wazuh stack reduced deployment time from two hours to under fifteen minutes, allowing us to spin up ephemeral SOC labs for specific red-team engagements.
What is Wazuh SIEM?
Wazuh is a fork of OSSEC that has evolved into a comprehensive XDR (Extended Detection and Response) and SIEM platform. Unlike traditional log aggregators, Wazuh provides an active agent that performs deep system inspection. We use it primarily for:
- Log data analysis from Linux, Windows, macOS, and cloud environments.
- File Integrity Monitoring (FIM) to detect unauthorized changes in critical system binaries.
- Rootkit and malware detection through anomaly-based scanning.
- Security Configuration Assessment (SCA) to identify misconfigurations against CIS benchmarks.
- Vulnerability detection by cross-referencing installed packages with CVE databases.
Benefits of Deploying Wazuh via Docker Containers
Deploying Wazuh via Docker Compose allows us to define the entire security infrastructure as code. This is particularly useful for Indian SMEs that need to comply with the Digital Personal Data Protection (DPDP) Act 2023 without investing in expensive proprietary licenses. Docker provides:
- Component Isolation: The Wazuh Indexer (based on OpenSearch) is resource-heavy. Docker allows us to set hard memory limits, preventing the Indexer from starving the Manager process.
- Simplified Upgrades: Upgrading a bare-metal Wazuh cluster is risky. With Docker, we simply update the image tag in our YAML file and restart the containers.
- Persistence: By mapping local directories to container volumes, we ensure that security alerts and indices survive container restarts or host reboots.
Wazuh vs. Elastic SIEM: Choosing the Right Security Platform
I often get asked why we choose Wazuh over a vanilla Elastic (ELK) stack for security monitoring. While Elastic is a world-class search engine, it requires significant manual tuning to become a functional SIEM. Wazuh comes pre-configured with over 3,000 detection rules and a dedicated agent that handles the heavy lifting of data collection.
Core Architectural Differences
Elastic SIEM relies heavily on Beats (Filebeat, Winlogbeat) for data ingestion. While effective, these agents are primarily log forwarders. The Wazuh agent is bi-directional; it can receive instructions from the manager to run scripts, restart services, or isolate a host. In our lab environments, this active response capability is the deciding factor for choosing Wazuh.
Feature Comparison: Threat Detection and Response
Wazuh integrates the OpenSearch engine (formerly Elasticsearch) for storage, but it layers a sophisticated analysis engine on top. This engine performs real-time decoders and rule matching. For example, when a failed SSH login occurs, Wazuh doesn't just store the log; it triggers a counter that can automatically add the source IP to a blocklist via the firewall-drop executable. For organizations managing remote infrastructure, implementing secure SSH access for teams ensures that even administrative actions are logged and audited.
Why Wazuh Is Often Preferred for Compliance and EDR
For organizations operating in India, compliance with CERT-In mandates requires rigorous log retention and incident reporting. Wazuh includes built-in modules for PCI-DSS, GDPR, and NIST 800-53. We have found that mapping these to the DPDP Act 2023 requirements is straightforward because Wazuh tracks data access and system changes at a granular level. Elastic's advanced security features often require a "Platinum" license, whereas Wazuh provides these out of the box for free.
Prerequisites for Installing Wazuh Docker
Before pulling images, you must tune the host operating system. The Wazuh Indexer is an OpenSearch-based service, and like all Lucene-based engines, it requires high mmap counts to function without crashing.
Minimum Hardware and System Requirements
Do not attempt to run a production-grade Wazuh stack on a t2.micro instance. We recommend the following minimums for a lab with 1-10 agents:
- CPU: 4 Cores (Intel VT-x or AMD-V enabled).
- RAM: 8 GB (16 GB preferred for smoother Dashboard performance).
- Storage: 50 GB of SSD space. IOPS is critical for indexing logs.
- OS: Ubuntu 22.04 LTS or Debian 11/12.
Installing Docker and Docker Compose on Your Host
We use the official Docker repository rather than the default snap or apt versions to ensure we have the latest engine features. Run the following to prepare your environment:
sudo apt-get updatesudo apt-get install ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Crucially, increase the virtual memory limits on the host, or the Indexer container will enter a crash loop:
sudo sysctl -w vm.max_map_count=262144
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf
Step-by-Step Guide: Install Wazuh SIEM Using Docker Compose
We rely on the official Wazuh Docker repository to maintain consistency. This repository contains the orchestration logic for the three main services: the Indexer (storage), the Server (analysis), and the Dashboard (visualization).
Cloning the Official Wazuh Docker Repository
Navigate to your /opt directory or a dedicated lab folder and clone the repository. We typically use the -b flag to specify a stable version branch.
cd /opt
sudo git clone https://github.com/wazuh/wazuh-docker.git -b v4.7.2 cd wazuh-docker
Configuring the docker-compose.yml File
The default configuration is suitable for basic labs, but for a scalable SOC, we modify the environment variables to handle resource allocation and API security. Below is a snippet of how we configure the manager service within the docker-compose.yml:
services:
wazuh.manager: image: wazuh/wazuh-manager:4.7.2 environment: - INDEXER_URL=https://wazuh.indexer:9200 - API_USER=admin - API_PASSWORD=SecretPassword123! - WAZUH_CLUSTER_KEY=938451a24362d2966579308638b9392e ulimits: nofile: soft: 65536 hard: 65536 deploy: resources: limits: memory: 4g volumes: - ./wazuh_logs:/var/ossec/logs - /var/run/docker.sock:/var/run/docker.sock:ro
Generating Necessary SSL Certificates
Wazuh components communicate over encrypted TLS channels. The repository includes a tool to generate these certificates automatically. This step is mandatory; without valid certs, the Dashboard will fail to authenticate with the Indexer.
docker compose -f generate-certs.yml run --rm generator
This command creates a config/wazuh_indexer_certs directory containing the CA, node certificates, and admin keys. Ensure these files are owned by the user running the Docker daemon.
Launching the Wazuh Stack (Indexer, Server, and Dashboard)
We prefer running the stack in detached mode to keep the terminal free for monitoring logs. The -d flag handles this.
docker compose up -d
Monitor the startup process using docker ps. It usually takes 2-3 minutes for the Indexer to initialize its shards and for the Dashboard to become available on port 443.
Post-Installation and Configuration
Once the containers are up, the first task is verifying that the internal API communication is functional. A common failure point is the Dashboard failing to connect to the Manager API due to incorrect credentials in the environment file.
Accessing the Wazuh Web Interface
Open your browser and navigate to https://<YOUR_SERVER_IP>. You will encounter a self-signed certificate warning; this is expected for lab environments. Log in using the default credentials (usually admin / SecretPassword123! if you used the snippet above). The Dashboard will perform a system check for about 60 seconds before showing the overview page.
Verifying Container Health and Connectivity
We use the following commands to ensure the Manager is correctly identifying its cluster nodes and that the Indexer is healthy:
# Check agent control from inside the manager containerdocker exec -it wazuh-docker-wazuh.manager-1 /var/ossec/bin/agent_control -l
Verify Indexer health via API
curl -k -u admin:SecretPassword123! https://localhost:9200/_cluster/health?pretty
If the status in the health check is "red", it usually means the vm.max_map_count was not set correctly on the host, or the Indexer has insufficient RAM to initialize shards.
Initial Setup: Adding Your First Wazuh Agent
To add an agent, navigate to the "Agents" section in the Dashboard and click "Deploy new agent". Select your OS (e.g., Ubuntu), enter the Wazuh Manager IP, and choose a group (default is usually fine). It will generate a one-liner command. On the target machine, run:
wget https://packages.wazuh.com/4.x/apt/pool/main/w/wazuh-agent/wazuh-agent_4.7.2-1_amd64.deb
sudo WAZUH_MANAGER='192.168.1.100' WAZUH_AGENT_NAME='Web-Srv-01' dpkg -i wazuh-agent_4.7.2-1_amd64.deb sudo systemctl daemon-reload sudo systemctl enable wazuh-agent sudo systemctl start wazuh-agent
Optimizing Wazuh Docker Performance
Performance degradation in Wazuh usually manifests as "Agent Unreachable" messages or Dashboard timeouts. This is almost always related to disk I/O or Java heap exhaustion.
Managing Elasticsearch/OpenSearch Heap Size
The Wazuh Indexer runs on the JVM. By default, it may try to grab 50% of the available system RAM. In a Docker environment, we must explicitly set the OPENSEARCH_JAVA_OPTS to prevent the container from being killed by the OOM (Out of Memory) killer.
wazuh.indexer:
environment: - "OPENSEARCH_JAVA_OPTS=-Xms2g -Xmx2g"
Rule of thumb: Set -Xms and -Xmx to the same value to avoid heap resizing overhead. This value should be no more than 50% of the container's RAM limit.
Persistent Storage and Volume Management
In the Indian context, CERT-In's February 2022 directions mandate that service providers maintain logs for 180 days. To achieve this in Docker, you must map the Indexer's data directory to a high-capacity external volume or a RAID array.
volumes:
- /mnt/secure_storage/wazuh/indexer_data:/usr/share/opensearch/data - /mnt/secure_storage/wazuh/manager_logs:/var/ossec/logs
Monitoring Docker Logs for SIEM Troubleshooting
When an agent fails to connect, checking the manager's internal logs is more effective than looking at the Docker daemon logs. Use this command to tail the OSSEC log file directly from the container:
docker exec -it wazuh-docker-wazuh.manager-1 tail -f /var/ossec/logs/ossec.log | grep "ERROR"
We also monitor real-time resource consumption to identify spikes during vulnerability scans:
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}"
Advanced Threat Detection: Monitoring Container Vulnerabilities
A SOC lab is only as good as its detection capabilities. We specifically configure Wazuh to monitor the very Docker host it runs on, protecting against common container vulnerabilities. This creates a recursive security layer where Wazuh monitors for container escapes.
Detecting CVE-2024-21626 (runc Container Breakout)
This critical vulnerability allows an attacker to escape a container and gain host access. To detect this, we configure the Wazuh FIM module to monitor the /proc filesystem. Add this to your ossec.conf on the Docker host:
<syscheck>
<directories check_all="yes" report_changes="yes" realtime="yes">/proc/self/fd/</directories> </syscheck>
Identifying CVE-2023-4911 (Looney Tunables)
Wazuh's Vulnerability Detector module is highly effective at finding unpatched glibc versions. In India, where many legacy systems still run Windows Server 2012 or older Ubuntu 16.04 instances, this module is vital. Once enabled, Wazuh will automatically flag containers running vulnerable versions of GNU C Library by querying the container's internal package manager.
# Query the Wazuh API to see vulnerable packages on agent 001
curl -k -u admin:SecretPassword123! -X GET "https://localhost:55000/syscollector/001/packages?pretty=true" | jq '.data.affected_items[] | select(.name=="libc6")'
Compliance and the Indian DPDP Act 2023
The Digital Personal Data Protection Act (DPDP) 2023 emphasizes "Reasonable Security Practices." While the Act doesn't name specific tools, Wazuh provides the technical controls necessary to meet its mandates. Specifically, the Data Inventory and Access Control modules help track who accessed what data and when.
Handling Aggressive NATing in Tier-2 Cities
Indian infrastructure, especially in Tier-2 and Tier-3 cities, often uses multi-layered NAT. This causes Wazuh agents to frequently disconnect. We solve this by adjusting the keep-alive interval and using the <registration_password> feature to ensure that even if an agent's public IP changes, it can re-authenticate securely.
<client>
<server> <address>wazuh.example.in</address> <port>1514</port> <protocol>tcp</protocol> </server> <config-profile>ubuntu_22, docker_host</config-profile> <keep_alive_interval>30</keep_alive_interval> <time-reconnect>60</time-reconnect> </client>
We also recommend using a Reverse Proxy like Nginx with a valid .in domain and Let's Encrypt certificates for the Dashboard. This avoids the "Insecure Connection" hurdles often blocked by corporate firewalls in Indian banking and financial sectors.
Scaling Your SIEM with Docker
As your SOC lab grows from 10 to 100 agents, you will need to transition from a single-node Docker Compose setup to a multi-node Docker Swarm or Kubernetes cluster. Wazuh's architecture supports this by allowing multiple Manager nodes to share a single Indexer cluster.
One final technical insight: always monitor the remoted process. This is the service responsible for receiving data from agents. If you notice high CPU on remoted, it's time to implement a Load Balancer (like HAProxy) in front of your Wazuh Manager containers to distribute the incoming encrypted traffic.
# Check the connection status of the remoted service
openssl s_client -connect <WAZUH_MANAGER_IP>:1515
Next Command: Explore the /var/ossec/etc/rules/local_rules.xml file to begin writing custom decoders for your proprietary Indian fintech applications.
