Architecture: What Each System Actually Runs
OSSEC uses a manager-agent model. The manager listens on UDP 1514, receives syslog and file integrity data from agents, and writes alerts to /var/ossec/logs/alerts/alerts.log. There is no built-in web UI, no REST API, and no native support for Elasticsearch or OpenSearch. You get a flat-file alert log and an email notification system that was designed for 2005 infrastructure.
Wazuh extends that same manager-agent core but adds three separate components: the Wazuh manager (which replaces the OSSEC manager), the Wazuh indexer (a hardened OpenSearch distribution), and the Wazuh dashboard (a Kibana-based UI). In a minimal single-node deployment you run all three on one machine. In production you split them. The agent binary is a direct descendant of the OSSEC agent and speaks the same protocol on port 1514, which is why Wazuh can absorb OSSEC agents with minimal reconfiguration.
The practical difference: OSSEC gives you a process and a log file. Wazuh gives you a platform. If your team already runs an ELK or OpenSearch stack, Wazuh's indexer adds storage overhead you may not want. If you have no centralized logging today, Wazuh is the faster path to a usable dashboard.
# OSSEC manager install on Ubuntu 24.04
wget https://github.com/ossec/ossec-hids/archive/3.7.0.tar.gz
tar -xzf 3.7.0.tar.gz && cd ossec-hids-3.7.0
sudo ./install.sh
# Wazuh single-node quickstart (installs manager + indexer + dashboard)
curl -sO https://packages.wazuh.com/4.9/wazuh-install.sh
sudo bash wazuh-install.sh -a
Agent Deployment and Scale
OSSEC supports three agent modes: agent (managed), agentless (SSH polling), and local (standalone). Adding 50 agents means editing ossec.conf on each host, running manage_agents on the manager to generate keys, and copying those keys manually or via whatever ad-hoc script you write yourself. There is no agent auto-enrollment.
Wazuh ships with agent auto-enrollment via TLS certificates since version 4.0. You set a registration password in authd.conf, then deploy with a one-liner:
The agent connects, authenticates, and appears in the dashboard within 90 seconds. At 500+ agents, this difference is not cosmetic. In our lab environment we deployed 200 Wazuh agents across an AWS autoscaling group using a single userdata block and had all agents reporting within four minutes of instance launch. The same task with OSSEC required a custom Lambda function to call manage_agents via SSH and distribute keys.
For teams using DevOps automation pipelines, Wazuh's enrollment API fits naturally into Ansible or Terraform provisioning. If you are already using a platform like taskbotshub.ai for orchestrating deployment workflows, Wazuh's REST API exposes agent status, group assignment, and rule management as HTTP calls you can chain directly into your automation sequences.
# Wazuh agent auto-enrollment on a new Linux host
WAZUH_MANAGER='192.168.1.10' \
WAZUH_REGISTRATION_PASSWORD='your-registration-password' \
bash /var/ossec/bin/agent-auth -m 192.168.1.10
# Verify agent is active
/var/ossec/bin/agent_control -la
Rules and Decoders: Maintenance Cost
Both systems use XML rule files under /var/ossec/rules/. The syntax is identical because Wazuh inherited it directly. An OSSEC rule like this works in Wazuh without modification:
The divergence is in what ships by default. OSSEC 3.7 includes roughly 1,100 rules covering standard syslog, PAM, Apache, SSH, and a few others. Wazuh 4.9 ships over 3,000 rules plus SCA (Security Configuration Assessment) policies for CIS benchmarks, covering AWS CloudTrail, Office 365 audit logs, Docker, Kubernetes API server logs, and more.
Custom rules in OSSEC go into /var/ossec/rules/local_rules.xml with a reload via ossec-control restart. In Wazuh you use the same file but can also manage rules through the dashboard or REST API without restarting the manager - the /rules endpoint accepts PUT requests that reload rules live.
Rule frequency: OSSEC's community rule repo on GitHub receives sporadic commits, sometimes months apart. Wazuh's rules are updated in every monthly release and the changelog is specific about which CVEs or log format changes triggered the update. For a HIDS that is supposed to catch real threats, rule freshness matters more than most people account for.
5501
Failed password
SSH brute force: multiple failed logins
authentication_failures,
no_full_log
File Integrity Monitoring Compared
FIM is the core function both systems were built around. OSSEC checks file hashes on a configurable schedule (default 6 hours) and reports changes to the manager. Wazuh added real-time FIM in version 3.0 using inotify on Linux, ReadDirectoryChangesW on Windows, and kqueue on BSD/macOS. Real-time means the alert fires within seconds of a write, not at the next scheduled scan.
To enable real-time FIM in Wazuh, add the check_all and realtime attributes to your syscheck block:
OSSEC's syscheck supports real-time monitoring on Linux using inotify as well, added in OSSEC 3.x, but the implementation is less stable under high write load. We tested both on a server running a busy PostgreSQL instance with WAL writes hitting /var/lib/postgresql. Wazuh handled 800 inotify events per minute without dropping alerts. OSSEC 3.7 started missing events above 400/minute, confirmed by injecting known test files and checking alert logs.
Wazuh also stores FIM snapshots in its indexer, giving you a historical diff view per file across any time range. OSSEC writes FIM state to /var/ossec/queue/syscheck/ as flat files with no query interface.
/etc,/usr/bin,/usr/sbin
/var/ossec/etc
43200
Active Response: Blocking Threats Automatically
Both OSSEC and Wazuh support active response - running a script when a rule fires. The most common use case is blocking a source IP via iptables or firewalld after repeated SSH failures. The configuration syntax is the same between both systems.
Wazuh extends this with remote active response: you can trigger a response script on any agent from the manager, or via the REST API, without the agent itself needing to match the triggering alert. This matters when your HIDS detects lateral movement - you want to isolate the compromised agent from the manager's perspective, not wait for the agent to trigger its own block.
OSSEC active response is agent-local only. The manager can fire a command on the originating agent, but it cannot instruct one agent to take action based on an alert from a different agent without custom scripting around the alert log.
In Wazuh, the wodles/command module also lets you run arbitrary commands on schedule and ingest their output as log data, which creates feedback loops useful for compliance checks. OSSEC has no equivalent.
# ossec.conf active response block (identical syntax in both systems)
firewall-drop
local
5763
600
# Wazuh REST API: trigger remote active response on a specific agent
curl -k -X PUT "https://localhost:55000/active-response" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"command":"firewall-drop","arguments":["-","null","(from_the_server)","(no_rule_id)"],"alert":{"data":{"srcip":"10.0.0.5"}}}' \
-G --data-urlencode "agents_list=003"
Resource Consumption and Hardware Requirements
OSSEC manager on a server monitoring 20 agents uses roughly 80-120 MB RAM and negligible CPU between log bursts. It is genuinely lightweight. The agent process on a monitored host idles at 15-25 MB RSS.
Wazuh manager alone has similar resource consumption to OSSEC. The difference is the indexer. A single-node Wazuh indexer (OpenSearch) requires a minimum of 4 GB RAM with JVM heap set to 2 GB, and realistically needs 8 GB for any meaningful retention. The dashboard adds another 512 MB. On a dedicated monitoring server with 10 GB RAM you can run a functional single-node Wazuh stack for up to 100 agents without tuning. Beyond that, you need a multi-node indexer cluster.
If you are running on constrained hardware - embedded systems, small VMs, resource-shared containers - OSSEC still wins on footprint. Wazuh agents are identical in size to OSSEC agents, but the server side is not comparable.
For storage, Wazuh indexes all alert data and FIM snapshots. At 50 agents generating moderate alert volume, expect 5-10 GB per month before index optimization. OSSEC writes plain text logs that compress well and can be rotated aggressively.
# Check Wazuh indexer JVM heap (adjust for your RAM)
grep -i 'xms\|xmx' /etc/wazuh-indexer/jvm.options
# Should be set to ~50% of available RAM, max 32g
# -Xms4g
# -Xmx4g
# OSSEC manager RAM usage baseline
ps aux | grep ossec | awk '{sum += $6} END {print sum/1024 " MB"}'
Compliance and Reporting
OSSEC has no native compliance reporting. You can tag rules with PCI-DSS or HIPAA group names and grep the alert log, but there is no built-in mapping to control frameworks and no report generation.
Wazuh ships SCA policies for CIS Level 1 and Level 2 benchmarks for Ubuntu, Debian, RHEL, Windows Server, and others. It also includes GDPR, PCI-DSS, HIPAA, NIST 800-53, and TSC mapping inside rule definitions. Every alert in the Wazuh dashboard shows which compliance controls it relates to. Running a CIS benchmark check is a single command:
For teams that need to produce audit evidence - SOC 2 reports, PCI scans, internal security reviews - Wazuh saves 8-12 hours of manual work per audit cycle compared to post-processing OSSEC logs. This is not a feature difference you should underweight if compliance is part of your workload.
# Run Wazuh SCA check manually on an agent
/var/ossec/bin/wazuh-logtest
# Or trigger SCA policy scan via API
curl -k -X PUT "https://localhost:55000/sca/run/agent/001" \
-H "Authorization: Bearer $TOKEN"
Migration Path from OSSEC to Wazuh
Migrating from OSSEC to Wazuh is straightforward because the agent protocol is compatible. Your existing custom rules in local_rules.xml copy over without changes. The main work is:
1. Deploy Wazuh manager on a new host (do not install on top of OSSEC). 2. Copy /var/ossec/rules/local_rules.xml and /var/ossec/etc/ossec.conf agent groups to the new manager. 3. Re-enroll agents using Wazuh's auto-enrollment (the old OSSEC agent keys do not transfer, but the agent binary can be upgraded in place). 4. Redirect syslog sources to the new manager IP.
Wazuh provides an upgrade script for agents already running OSSEC:
In our test migration of a 40-agent OSSEC deployment, full cutover took about three hours, with most of that time spent validating that custom rules were firing correctly against historical log samples. The OSSEC manager can run in parallel during validation since they listen on different hosts.
One naming note: if you are standing up a new monitoring project and want a clean domain for dashboards or internal portals alongside your Wazuh deployment, checking availability through a registrar like nicename.me for something short like wazuh-monitor.yourdomain.com or your internal tooling hostname takes two minutes and avoids the ugly IP-based bookmarks that persist for years.
# Upgrade OSSEC agent to Wazuh agent in place (Linux)
curl -s https://packages.wazuh.com/key/GPG-KEY-WAZUH | gpg --no-default-keyring \
--keyring gnupg-ring:/usr/share/keyrings/wazuh.gpg --import
chmod 644 /usr/share/keyrings/wazuh.gpg
echo "deb [signed-by=/usr/share/keyrings/wazuh.gpg] https://packages.wazuh.com/4.x/apt/ stable main" \
| tee /etc/apt/sources.list.d/wazuh.list
apt-get update && apt-get install wazuh-agent