Home About Tools Projects Guides & Blog ⚡ Hire Me ✦ Websites Contact →
Home Projects Home SOC: Wazuh + Elastic
Homelab · SIEM · Threat Detection

Home SOC with
Wazuh + Elastic SIEM

How I built a Security Operations Centre on my Proxmox homelab. Wazuh for host-based intrusion detection across every VM, Elastic for log aggregation and search, and custom alert rules that have caught real threats on my network.

Status Live
Platform Proxmox VE 8
Agents deployed 9 endpoints
Logs/day ~40,000
Cost £0 (open source)
// overview

What this is and why I built it

A SIEM (Security Information and Event Management) system collects logs from across your infrastructure, normalises them, and applies detection rules to identify suspicious behaviour. At work we use Microsoft Sentinel, which is excellent but expensive for home use. Wazuh paired with the Elastic Stack gives you most of the same capability for free, and running it yourself teaches you things about detection engineering that no amount of reading can replicate.

The setup runs entirely on my Proxmox server. Wazuh acts as the HIDS (host-based intrusion detection system), running a lightweight agent on every VM and container in the lab. Those agents forward security events to the Wazuh manager, which correlates them against a ruleset and feeds alerts into Elasticsearch. Kibana sits on top for dashboards and investigation.

🎯
This is a practical security lab, not a toy. Within the first week of running it I caught two SSH brute-force attempts against my Proxmox host from external IPs, a port scan from a device on my IoT VLAN that had been compromised, and multiple failed sudo attempts from a misconfigured container. None of those would have been visible without this setup.
// stack

The full stack

Each component has a specific job. Wazuh handles the agent-side collection and initial rule matching. Elastic handles storage, search, and visualisation. The two are integrated via Wazuh's built-in Elasticsearch output.

Wazuh Manager HIDS
Central manager receives log data from all agents. Applies the built-in ruleset (4,000+ rules) plus custom rules I've written. Handles active response to automatically block IPs that hit brute-force thresholds.
VM: 4 vCPU / 8GB RAMUbuntu 22.04Wazuh 4.8
Wazuh Agents AGENT
Lightweight agent installed on every endpoint in the lab. Monitors file integrity (FIM), watches for rootkits, collects system logs, monitors running processes, and checks for CVEs in installed packages.
9 endpointsLinux + Windows<1% CPU overhead
Elasticsearch STORAGE
Receives all Wazuh alert data and raw logs. Provides the fast full-text search that makes incident investigation practical. Running a single-node cluster on dedicated storage. 30-day retention before index rollover.
VM: 4 vCPU / 12GB RAM500GB SSDElastic 8.14
Kibana VISUALISATION
Frontend for Elasticsearch. Hosts the Wazuh dashboards (pre-built and custom), KQL-based investigation interface, and alert management UI. Accessed over Tailscale so I can check in from anywhere without exposing it publicly.
Runs alongside ElasticsearchTailscale access only
// infrastructure

Resource allocation on Proxmox

The Elastic stack is memory-hungry. Elasticsearch wants at least 8GB heap, which means the VM needs 12-16GB of RAM. Running this on a machine with less than 32GB total is going to hurt. Here's what I allocated.

VM / ContainerRolevCPURAMStorage
wazuh-managerWazuh Manager + Indexer48 GB100 GB SSD
elastic-stackElasticsearch + Kibana416 GB500 GB SSD
TotalSOC stack only824 GB600 GB
⚠️
Elasticsearch heap sizing. Set the JVM heap to half the VM's RAM, capped at 31GB. So on a 16GB VM: -Xms8g -Xmx8g in jvm.options. Going above 32GB heap disables pointer compression and actually makes performance worse.
// how it works

Log ingestion and alert pipeline

Understanding the data flow helps when you're debugging missing logs or tuning rules.

1
Agent collects events
On each endpoint the Wazuh agent tails log files (syslog, auth.log, Windows Event Log), monitors file changes via FIM, and runs periodic vulnerability checks. Events are sent to the manager over TLS on port 1514.
2
Manager applies ruleset
The Wazuh manager normalises events and runs them through its ruleset. Rules can match on single events or correlate multiple events over a time window (e.g. 10 failed logins in 60 seconds). Each matched rule generates an alert with a severity level 0-15.
3
Active response fires (where configured)
For high-severity rules like SSH brute force, active response scripts run automatically. The most commonly used one calls firewall-drop to add an iptables block for the source IP, with a 600-second expiry.
4
Alerts forwarded to Elasticsearch
All alerts and raw log data are forwarded to Elasticsearch via the Wazuh indexer. Data is written to daily indices (wazuh-alerts-4.x-YYYY.MM.DD) for easy retention management.
5
Kibana dashboards and investigation
Alerts appear in the Wazuh Kibana dashboards within seconds. I've built custom dashboards for the views I check daily: top alert sources, FIM events, authentication failures, and vulnerability summary.
// detection rules

Custom rules I've written

The built-in ruleset covers most common attack patterns well. But lab environments have unique behaviour, and writing custom rules is one of the best ways to build detection engineering skills. Here are a few I've added.

// Detect port scan from internal network
<!-- Port scan detection: 20+ connections to different ports in 10 seconds -->
<rule id="100001" level="10" frequency="20" timeframe="10">
  <if_matched_sid>5706</if_matched_sid>
  <same_source_ip />
  <description>Port scan detected from internal IP</description>
  <group>network_scan,attack</group>
</rule>
// Alert on new cron job created by non-root user
<rule id="100010" level="12">
  <if_sid>533</if_sid>       <!-- FIM: file added -->
  <match>/var/spool/cron</match>
  <description>Cron job created by non-root user $(user.name)</description>
  <group>persistence,suspicious</group>
  <mitre>
    <id>T1053.003</id>  <!-- Scheduled Task/Job: Cron -->
  </mitre>
</rule>
🗂️
Map rules to MITRE ATT&CK. Adding <mitre> IDs to custom rules lets you see attack coverage across the ATT&CK framework in the Kibana dashboard. It makes it immediately obvious which techniques you're detecting and which have gaps.
// real detections

Notable alerts from the first 30 days

These are real events caught by the SOC, not lab simulations. Running an internet-connected homelab means genuine threat activity hits within hours of standing something up.

EventSourceRule triggeredSeverity
SSH brute force - 847 attempts in 4 minutes External IP (China AS) Multiple authentication failures followed by blocked by active response CRITICAL
Port scan from IoT VLAN device Internal 192.168.30.x Custom rule 100001 - 47 ports probed in 8 seconds from a smart plug HIGH
Unexpected sudo escalation Dev container Non-standard user ran sudo in a container that should have had it disabled HIGH
Rootkit scan positive hit Homelab VM Wazuh rootcheck found hidden process - turned out to be a benign monitoring tool running outside of /proc visibility. Investigated and whitelisted. MEDIUM
FIM alert on /etc/passwd Multiple VMs File integrity monitoring detected modification to /etc/passwd - triggered by a legitimate package update but confirmed no unexpected entries added. MEDIUM
// outcomes

What this setup delivers

9
Endpoints monitored across the homelab
~40k
Log events processed per day
£0
Licence cost (fully open source)
5
Real threats detected in first 30 days
🎓
The best cybersecurity study tool I've built. Running a live SIEM teaches detection engineering, log analysis, alert triage, and incident investigation in a way that no course or lab exercise can match. If you're studying for SC-200 or working toward a SOC analyst role, building this is worth more than any mock exam.