September 6, 2026
Building a Centralized SOC Lab: Integrating Wazuh SIEM Telemetry with Graylog via Filebeat & Docker
A step-by-step operational guide to forwarding endpoint security events from a Wazuh Manager VM to Graylog running on Windows using WSL2โฆ
By Muhammad Usman
4 min read
A step-by-step operational guide to forwarding endpoint security events from a Wazuh Manager VM to Graylog running on Windows using WSL2, Docker Compose, and Filebeat.
1. Executive Summary & Core Use Cases
In modern Security Operations Center (SOC) environments, combining host-level security detection with centralized log aggregation is standard practice. Wazuh functions as an Endpoint Detection and Response (EDR) and Security Information and Event Management (SIEM) solution โ handling file integrity monitoring, vulnerability scans, and endpoint threat detection. Graylog, powered by OpenSearch, acts as a centralized log management platform built for lightning-fast queries, custom data extraction, and stream-based filtering.
By forwarding Wazuh telemetry directly into Graylog using Filebeat, security analysts achieve several core operational capabilities:
- Centralized Security Management: Aggregate endpoint alerts from Linux and Windows hosts alongside network device logs in a single operational view.
- Rapid Incident Response & Forensics: Leverage Graylog's high-performance search engine to query security logs across historical timeframes during threat-hunting exercises.
- Custom Stream Processing & Alerting: Route specific threat categories (e.g., Failed Authentication, Privilege Escalation) into targeted Graylog streams to fire automated webhooks to external ticketing or notification tools.
2. Nework Topology & Lab Architecture
The lab is configured inside VirtualBox using a private Host-Only Network (192.x.x.x/24) to isolate security traffic while allowing inter-system communication.
- Windows Host (
192.xxx.xx.x): Runs Docker Desktop via WSL2 (orchestrating Graylog, OpenSearch, and MongoDB) and acts as a monitored Wazuh Agent endpoint. - Wazuh Manager VM (
192.x.x.x): Executes the core detection engine, ruleset matching, and Filebeat log shipping. - Kali Linux VM (
192.x.x.x): Serves as an attack platform and monitored Linux endpoint running a Wazuh Agent.
3. WSL2 & Docker Compose Setup on Windows
Graylog requires a backend search engine (OpenSearch) and a metadata database (MongoDB). Deploying this stack on Windows is handled using WSL2 and Docker Desktop.
Step A: Enable WSL2
Open PowerShell as Administrator:
wsl --install
wsl --set-default-version 2wsl --install
wsl --set-default-version 2Step B: Deploy the Graylog Container Stack
Install Docker Desktop on Windows, ensuring Use the WSL 2 based engine is checked in Settings -> General.
Create a folder named graylog-soc and save the following docker-compose.yml:
version: '3.8'
services:
mongodb:
image: mongo:5.0
container_name: graylog_mongodb
volumes:
- mongo_data:/data/db
restart: always
opensearch:
image: opensearchproject/opensearch:2.11.0
container_name: graylog_opensearch
environment:
- OPENSEARCH_JAVA_OPTS=-Xms1g -Xmx1g
- bootstrap.memory_lock=true
- discovery.type=single-node
- action.auto_create_index=false
- DISABLE_INSTALL_DEMO_CONFIG=true
- DISABLE_SECURITY_PLUGIN=true
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- opensearch_data:/usr/share/opensearch/data
restart: always
graylog:
image: graylog/graylog:5.2
container_name: graylog_server
depends_on:
- mongodb
- opensearch
ports:
- "9000:9000" # Web Interface
- "5044:5044" # Beats Input Receiver
environment:
GRAYLOG_PASSWORD_SECRET: "8a12f38d4e56719abc02d4eef1102931a"
GRAYLOG_ROOT_PASSWORD_SHA2: "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918" # SHA-256 for 'admin'
GRAYLOG_HTTP_BIND_ADDRESS: "0.0.0.0:9000"
GRAYLOG_ELASTICSEARCH_HOSTS: "http://opensearch:9200"
volumes:
- graylog_data:/usr/share/graylog/data
restart: always
volumes:
mongo_data:
opensearch_data:
graylog_data:version: '3.8'
services:
mongodb:
image: mongo:5.0
container_name: graylog_mongodb
volumes:
- mongo_data:/data/db
restart: always
opensearch:
image: opensearchproject/opensearch:2.11.0
container_name: graylog_opensearch
environment:
- OPENSEARCH_JAVA_OPTS=-Xms1g -Xmx1g
- bootstrap.memory_lock=true
- discovery.type=single-node
- action.auto_create_index=false
- DISABLE_INSTALL_DEMO_CONFIG=true
- DISABLE_SECURITY_PLUGIN=true
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- opensearch_data:/usr/share/opensearch/data
restart: always
graylog:
image: graylog/graylog:5.2
container_name: graylog_server
depends_on:
- mongodb
- opensearch
ports:
- "9000:9000" # Web Interface
- "5044:5044" # Beats Input Receiver
environment:
GRAYLOG_PASSWORD_SECRET: "8a12f38d4e56719abc02d4eef1102931a"
GRAYLOG_ROOT_PASSWORD_SHA2: "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918" # SHA-256 for 'admin'
GRAYLOG_HTTP_BIND_ADDRESS: "0.0.0.0:9000"
GRAYLOG_ELASTICSEARCH_HOSTS: "http://opensearch:9200"
volumes:
- graylog_data:/usr/share/graylog/data
restart: always
volumes:
mongo_data:
opensearch_data:
graylog_data:Launch the stack:
docker compose up -ddocker compose up -dVerify that all three containers are active:
docker psdocker ps4. Configuring Graylog Beats Input & Windows Firewall
For Graylog to receive incoming log batches from Filebeat, an active Beats input port must be opened and allowed through the host firewall.
Step A: Configure Beats Input in Graylog UI
- Navigate to
http://localhost:9000in your browser and log in (admin/admin). - Go to System -> Inputs.
- Select Beats from the dropdown menu and click Launch new input.
- Set Title to
Wazuh-Alerts Beatsand Port to5044. - Click Save.
Step B: Configure Windows Defender Firewall
Open PowerShell as Administrator on your Windows host to allow incoming traffic on TCP port 5044:
New-NetFirewallRule -DisplayName "Graylog Beats 5044" -Direction Inbound -LocalPort 5044 -Protocol TCP -Action AllowNew-NetFirewallRule -DisplayName "Graylog Beats 5044" -Direction Inbound -LocalPort 5044 -Protocol TCP -Action Allow
5. Configuring Filebeat on Wazuh Manager
Filebeat monitors the core alert file (/var/ossec/logs/alerts/alerts.json) on the Wazuh Manager and forwards formatted JSON records to Graylog.
On the Wazuh Manager VM, edit /etc/filebeat/filebeat.yml:
filebeat.modules:
- module: wazuh
alerts:
enabled: true
archives:
enabled: false
logging.level: info
logging.to_files: true
logging.files:
path: /var/log/filebeat
name: filebeat
keepfiles: 7
permissions: 0644
output.logstash:
hosts: ["<windows host ip>:5044"]filebeat.modules:
- module: wazuh
alerts:
enabled: true
archives:
enabled: false
logging.level: info
logging.to_files: true
logging.files:
path: /var/log/filebeat
name: filebeat
keepfiles: 7
permissions: 0644
output.logstash:
hosts: ["<windows host ip>:5044"]Critical Configuration Rule: YAML parser syntax requires literal spaces instead of tabs. The hosts: definition under output.logstash: must be indented by exactly two spaces. Incorrect indentation or tab characters will throw errors such as yaml: line XX: did not find expected key or No outputs are defined.
Validate the configuration file and restart the service:
sudo filebeat test config
sudo systemctl restart filebeat
sudo systemctl status filebeatsudo filebeat test config
sudo systemctl restart filebeat
sudo systemctl status filebeat
6. Troubleshooting Real-World Pipeline Bottlenecks
Setting up multi-node security pipelines often uncovers networking and configuration hurdles. Here are the main troubleshooting solutions applied during this integration:
A. Testing Sockets Without nc (Netcat)
Minimal Linux installations (like the Wazuh OVA appliance) often omit diagnostic utilities like nc or telnet. You can test network port connectivity directly using Bash's built-in TCP features:
timeout 3 bash -c "</dev/tcp/192.168.56.1/5044" && echo "PORT OPEN" || echo "PORT CLOSED"timeout 3 bash -c "</dev/tcp/192.168.56.1/5044" && echo "PORT OPEN" || echo "PORT CLOSED"Resolving Clock Skew & Timezone Search Filters
If Graylog's System / Inputs tab displays active network throughput on port 5044, but queries return zero results, check for VM clock drift:
Bash
datedateWhen system clocks differ across host and guest VMs, events are indexed under shifted timestamps. Expanding Graylog's time range dropdown from "Search in last 5 minutes" to Search in all messages resolves search visibility while system clocks resynchronize.
7. Generating Security Events & Verifying Log Delivery
To confirm end-to-end ingestion, generate synthetic authentication failures on your connected endpoints.
From Windows Host (PowerShell):
Trigger a failed authentication event (Windows Event ID 4625):
net use \\127.0.0.1\IPC$ /user:fakeuser wrongpasswordnet use \\127.0.0.1\IPC$ /user:fakeuser wrongpasswordFrom attacker machine(Terminal):
Trigger a local authentication failure:
In my case i was using a windows endpoint:
Verify Log Delivery in Graylog:
- Open
[http://localhost:9000/search](http://localhost:9000/search.). - Type
fakeuserinto the search bar. - Set the time range filter to Search in all messages and press Enter.
Expanding any event record displays structured key-value maps (such as agent_name, rule_id, and full_log), confirming that Filebeat and Graylog are successfully ingesting, parsing, and centralizing security telemetry.