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.
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.
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.
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 / Container | Role | vCPU | RAM | Storage |
|---|---|---|---|---|
| wazuh-manager | Wazuh Manager + Indexer | 4 | 8 GB | 100 GB SSD |
| elastic-stack | Elasticsearch + Kibana | 4 | 16 GB | 500 GB SSD |
| Total | SOC stack only | 8 | 24 GB | 600 GB |
-Xms8g -Xmx8g in jvm.options. Going above 32GB heap disables pointer compression and actually makes performance worse.Log ingestion and alert pipeline
Understanding the data flow helps when you're debugging missing logs or tuning rules.
firewall-drop to add an iptables block for the source IP, with a 600-second expiry.wazuh-alerts-4.x-YYYY.MM.DD) for easy retention management.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.
<!-- 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>
<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>
<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.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.
| Event | Source | Rule triggered | Severity |
|---|---|---|---|
| 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 |