Wazuh: A SIEM You Can Actually Run at Home
Enterprise security monitoring, shrunk to fit a machine you own — and the RAM bill that comes with it

Contents
Here is an uncomfortable question to ask yourself about your own homelab: if someone got a shell on one of your boxes six weeks ago, how would you know today? Most honest answers are some variant of “I’d notice the CPU fan”. Which is to say: you would not know, unless the intruder was clumsy enough to start mining crypto badly.
That gap is the reason SIEM exists as a product category. Security Information and Event Management is a mouthful that means one modest idea — pull the logs and system state from every machine into one place, run rules against them, and raise something a human can read when the rules trip. The commercial versions of that idea cost more per year than my entire rack cost to build, and they are priced per gigabyte ingested, which is a pricing model apparently designed to punish you for having good logging.
Wazuh is the open-source answer. It is a fork of OSSEC that grew a real correlation engine, an OpenSearch-based indexer, and a dashboard, and it is free in the way that matters: no node limits, no ingest tiers, no feature gates on the security-relevant parts. I looked at whether it is worth the RAM back in January and came away cautiously positive. Six months of running it in earnest have sharpened that into something more specific, including one loud reservation.
What Wazuh actually does, before you install anything
Wazuh’s marketing lists about fifteen capabilities. Four of them justify the install, and the rest are bonus.
File integrity monitoring. An agent hashes the files you tell it to watch and raises an alert when one changes. Point it at /etc, /usr/bin, /usr/sbin and the web roots, and you have a tripwire on every persistence mechanism a lazy attacker uses. This is the single highest-value thing in the product, and it is the thing nothing else in a normal homelab stack does at all.
Log analysis with decoders and rules. The agent ships log lines, the manager decodes them into fields, and rules match against fields. Rules have levels from 0 to 16 and can reference other rules, which is how correlation happens: “rule 5710 (failed SSH) firing eight times in 120 seconds from one source” becomes rule 5712 at level 10.
Rootcheck and SCA. Policy scans against CIS benchmarks that tell you your SSH config allows password auth and your kernel has net.ipv4.ip_forward on. Genuinely useful the first time you run it, mostly noise afterwards. It overlaps heavily with what Lynis gives you for free in one binary, and Lynis needs no infrastructure.
Vulnerability detection. The agent inventories installed packages, the manager cross-references them against CVE feeds, and you get a list of what on your boxes is known-broken. This works well and is a legitimate reason to run the thing.
Everything else — the MITRE ATT&CK mapping, the compliance dashboards for PCI DSS and GDPR, the cloud connectors — is enterprise furniture. It does no harm sitting there, and it is decoration in a house with three machines in it.
Installing without hating yourself
The all-in-one installer works, and it is the right call for a homelab. Do not build a distributed cluster on three nodes to feel professional about it.
| |
That is three processes on one box: wazuh-manager (the brain), wazuh-indexer (OpenSearch, the storage), and wazuh-dashboard (OpenSearch Dashboards, the face). The indexer is where all your RAM went. Give the whole thing 8 GB and a dedicated VM; 4 GB technically boots and then the JVM spends its life in garbage collection while you wonder why the dashboard times out.
Agents install per machine and register against the manager:
| |
The agent is a C program in about 40 MB of RAM. It is genuinely lightweight, and it is the one part of Wazuh I have no complaints about at all.
The configuration that actually matters
Default Wazuh is loud. Out of the box you will get thousands of level-3 events a day telling you cron ran and a user logged in. The first week is spent making it quiet enough to be worth reading, and the file where that happens is /var/ossec/etc/ossec.conf on the manager, plus local_rules.xml for your overrides.
File integrity monitoring wants real-time on the directories that matter and scheduled scans on the ones that do not:
| |
Silencing rules you have judged irrelevant goes in local_rules.xml, and the crucial habit is writing why in a comment, because in four months you will not remember:
| |
Level 0 means “decode it, store it, never alert”. Level 12 means “wake me”. That second rule is the entire point of a SIEM: the same event means different things on different machines, and a correlation engine is where you encode that judgement.
Alerting outward needs <command> and <active-response> blocks, or an integration. I push level-10-and-above to a self-hosted push endpoint rather than email, because email alerts get filtered into a folder and die there.
What a real alert looks like
Abstract talk about correlation engines is easy to nod along to and hard to evaluate. Here is an actual chain from my own logs, lightly genericised, because it shows what the machinery buys you over grepping.
A scan hit the edge box. Wazuh’s decoder turned each failed SSH line into fields, rule 5710 fired per attempt at level 5, and eight of those inside two minutes rolled up into rule 5712 at level 10:
| |
The first alert is noise. Something on the internet tried eight passwords against a box with password authentication disabled and achieved nothing. Rule 5712 fires on my edge host several times a week and I ignore it completely.
The second alert is the one that matters, and it landed sixty-two seconds later. sshd_config changed on a host where I had made no change. In that instance it was an unattended-upgrades run rewriting the file after a package update, which I confirmed inside a minute by reading the apt history — dull, and exactly the dullness you want. But notice the shape of what happened: the tool told me, unprompted, that a security-critical file on an internet-facing machine had been modified, and it told me a minute after it happened rather than during an incident review in November.
That is the capability. No amount of grep on auth.log produces the second alert, because the second alert has nothing to do with logs. It comes from an agent hashing files on a schedule and noticing arithmetic that changed.
The RAM problem, stated honestly
This is where I stop being nice about it. On my box, steady state with four agents:
| Process | Resident |
|---|---|
| wazuh-indexer (JVM) | 4.1 GB |
| wazuh-dashboard (Node) | 620 MB |
| wazuh-manager | 380 MB |
| Total | ~5.1 GB |
Five gigabytes to watch four machines. The indexer is OpenSearch, and OpenSearch was designed for clusters ingesting terabytes; running it to hold 3 GB of alerts is using a shipping crane to move a bicycle. There is no supported way to swap it for something smaller, and the dashboard is welded to it.
Compare that to Loki holding logs for the same four machines in about 300 MB. Loki does less — no FIM, no CVE feed, no correlation engine — and it does that less for one-seventeenth of the memory. If your machine has 16 GB and hosts other things, Wazuh will take a third of it and you will feel that every time something else needs to grow.
Retention is the other tax. Alerts land in daily indices and stay forever unless you tell them otherwise. Set an ISM policy on day one:
| |
Skip that and the disk fills, the indexer goes read-only at the 95% flood-stage watermark, and every agent silently stops reporting. Which brings us neatly to the failure modes.
The habit that decides whether it was worth it
Every piece of security tooling has a hidden requirement that the documentation never lists, and for a SIEM it is this: someone has to look at it. Wazuh generates a dashboard. The control is a human forming a judgement, and the software’s only job is making that judgement possible.
The homelab failure pattern is completely predictable. You install it in a burst of enthusiasm, you tune the noise for a fortnight, you check the dashboard daily for a month, and then you stop. Six months later it is a VM eating 5 GB that nobody has opened since spring. It is worse than nothing at that point, because you believe you have monitoring and you have a decoration.
What has worked for me is refusing to rely on the dashboard at all. The dashboard is for investigating something after I already know it happened. The thing that makes Wazuh survive is a small number of alerts that arrive somewhere I cannot ignore — a push notification on my phone, from a rule I wrote deliberately, for an event I have decided in advance is worth interrupting my evening.
That list is short and it should be short. File integrity change on an internet-facing host. A new user account created anywhere. A successful SSH login from an address outside my own networks. Sudo by an account that should never use sudo. Four rules. Everything else lands in the index, waits, and gets queried when I have a reason.
The discipline is that every one of those four must be genuinely rare. An alert that fires weekly becomes wallpaper within a month and you will start swiping it away without reading. If a rule fires and the answer is “oh, that is just the backup job”, the rule is wrong and you fix it that day. An alert you have learned to dismiss is worse than no alert, because it costs attention and returns nothing.
Get that right and the RAM argument mostly evaporates.
Troubleshooting
“Agents show Never connected.” The manager listens on 1514/TCP for agent traffic and 1515/TCP for enrolment. Enrolment happens once and people forget to open it. Check /var/ossec/logs/ossec.log on the agent — Unable to connect to enrollment service means 1515 is blocked; Unable to connect to '192.168.1.20:1514' means the agent enrolled fine and the data port is shut.
“The dashboard is empty but agents are Active.” Almost always the indexer refusing writes. Check it directly:
| |
Red with a single node usually means the disk watermark tripped. Free space, then clear the read-only block that OpenSearch set: PUT /_all/_settings {"index.blocks.read_only_allow_delete": null}.
“FIM is eating the CPU.” You pointed realtime="yes" at a directory with a hundred thousand files, and inotify watches are per-file. Check sysctl fs.inotify.max_user_watches — the agent silently degrades to scheduled scanning when it runs out, so you get the CPU cost without the real-time benefit. Watch /etc in real time and scan /var/www on a schedule.
“Everything worked until an upgrade.” Wazuh’s minor versions expect manager and agents to match. A manager on 4.12 with agents on 4.9 mostly works until a decoder changes and a rule stops firing, with no error anywhere. Upgrade the manager first, then the agents, and check agent_control -l reports the version you expect.
Is it worth it?
Wazuh is worth it if you have five or more machines, at least one exposed to the internet, and 8 GB you can genuinely spare. File integrity monitoring plus vulnerability detection plus rule-based correlation is a real capability, it is the capability your homelab is otherwise completely missing, and nobody else gives it to you for free. The first time it tells you /etc/ssh/sshd_config changed on a box where you changed nothing, the RAM stops being a debate.
Wazuh is a mistake if you have three machines and 16 GB total. You will spend the RAM, spend the first fortnight tuning noise, and end up with a dashboard you check twice a month. For that shape of lab, CrowdSec on the edge plus AIDE for file integrity plus a weekly Lynis run covers 70% of the value at 5% of the cost. That is a good trade and you should take it without embarrassment.
The reservation I promised: Wazuh is enterprise software wearing a homelab hat. Every design decision assumes a security team, a compliance requirement and a hardware budget, and you have none of those. It will work, it will work well, and it will always feel one size too big for the room. I keep running it because file integrity monitoring on the edge box is worth 5 GB to me specifically. Do the same arithmetic with your own numbers before you install anything, because the answer genuinely changes with the size of the lab.




