Wazuh started as a fork of OSSEC HIDS and keeps its configuration format, rule syntax and /var/ossec directory layout, while adding a REST API, vulnerability detection, centralized agent enrollment and a web dashboard. That shared heritage makes migration manageable, but it also means OSSEC and Wazuh cannot live side by side on the same machine. In this tutorial you will back up an existing OSSEC manager, build a new Wazuh manager on Ubuntu 24.04, port your custom rules, decoders and configuration, and replace the OSSEC agents with Wazuh agents one by one.

Prerequisites

To follow this guide you need:

  • An existing OSSEC 2.x or 3.x manager with agents, and root access to it.
  • A new server for the Wazuh manager running Ubuntu 24.04 LTS, for example a CubePath VPS, with at least 2 vCPUs and 4 GB of RAM. Add more if you also plan to run the Wazuh indexer and dashboard on it.
  • A non-root user with sudo privileges on the new server.
  • A DNS name for the new manager, such as wazuh.your_domain, that agents can resolve.
  • A maintenance window: each agent stops reporting briefly while it is swapped.

Building a new manager instead of upgrading in place lets you keep the OSSEC manager running until every agent has moved, and gives you a clean rollback path.

Step 1 - Backing up the OSSEC manager

On the OSSEC manager, stop the service so files are consistent, and archive the whole installation:

sudo /var/ossec/bin/ossec-control stop
sudo tar czf /root/ossec-backup-$(date +%F).tar.gz /var/ossec
sudo /var/ossec/bin/ossec-control start

Then write down what you will need to rebuild on Wazuh. List the registered agents:

sudo /var/ossec/bin/manage_agents -l
Available agents:
   ID: 001, Name: web-01, IP: any
   ID: 002, Name: db-01, IP: any

The files that carry your customizations are:

File on OSSECContents
/var/ossec/etc/ossec.confManager configuration (syscheck, localfile, email, active response)
/var/ossec/rules/local_rules.xmlYour custom rules
/var/ossec/etc/local_decoder.xmlYour custom decoders
/var/ossec/etc/shared/agent.confCentralized agent configuration
/var/ossec/active-response/bin/Active response scripts, including custom ones

Copy them to the new server, for example with scp, into a working directory such as ~/ossec-migration/.

Step 2 - Installing the Wazuh manager

On the new Ubuntu 24.04 server, add the Wazuh repository with its signing key in /etc/apt/keyrings:

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://packages.wazuh.com/key/GPG-KEY-WAZUH | sudo gpg --dearmor -o /etc/apt/keyrings/wazuh.gpg
echo "deb [signed-by=/etc/apt/keyrings/wazuh.gpg] https://packages.wazuh.com/4.x/apt/ stable main" | sudo tee /etc/apt/sources.list.d/wazuh.list

Install and start the manager:

sudo apt update
sudo apt install wazuh-manager
sudo systemctl enable --now wazuh-manager

Check that the daemons are running:

sudo /var/ossec/bin/wazuh-control status
wazuh-clusterd not running...
wazuh-modulesd is running...
wazuh-monitord is running...
wazuh-logcollector is running...
wazuh-remoted is running...
wazuh-syscheckd is running...
wazuh-analysisd is running...
wazuh-execd is running...
wazuh-db is running...
wazuh-authd is running...
wazuh-apid is running...

wazuh-clusterd only runs in multi-node clusters, so not running is expected. Agents talk to the manager on TCP 1514 and enroll on TCP 1515. Open both ports, ideally only to your agents' networks:

sudo ufw allow 1514/tcp
sudo ufw allow 1515/tcp

Step 3 - Porting custom rules and decoders

The rule and decoder syntax is the same, but the paths changed. In Wazuh, custom rules go in /var/ossec/etc/rules/local_rules.xml and custom decoders in /var/ossec/etc/decoders/local_decoder.xml. Both files already exist with examples. Review them, then replace them with your OSSEC versions:

sudo cp ~/ossec-migration/local_rules.xml /var/ossec/etc/rules/local_rules.xml
sudo cp ~/ossec-migration/local_decoder.xml /var/ossec/etc/decoders/local_decoder.xml
sudo chown wazuh:wazuh /var/ossec/etc/rules/local_rules.xml /var/ossec/etc/decoders/local_decoder.xml
sudo chmod 660 /var/ossec/etc/rules/local_rules.xml /var/ossec/etc/decoders/local_decoder.xml

Two things commonly break:

  • Rule IDs. Custom rules must use IDs between 100000 and 120000, which is the same range OSSEC recommended. Any custom rule with a lower ID can collide with a Wazuh built-in rule; renumber it by hand.
  • Parent rules and groups. Wazuh rewrote much of the default ruleset. A custom rule with <if_sid> or <if_group> pointing at an OSSEC built-in rule may now reference a rule with a different meaning, or none at all. Search the Wazuh ruleset in /var/ossec/ruleset/rules/ for the log you are matching and update the parent ID.

Check that the analysis engine accepts the files:

sudo /var/ossec/bin/wazuh-analysisd -t

No output and exit code 0 means the configuration and rules loaded. Any error names the file and rule that failed. Next, feed a real log line that one of your custom rules should match into wazuh-logtest:

sudo /var/ossec/bin/wazuh-logtest

Paste the log line and press Enter. The output shows the decoder that was used and the rule that fired:

**Phase 3: Completed filtering (rules).
        id: '100010'
        level: '10'
        description: 'Failed login to internal app'
**Alert to be generated.

Repeat for each custom rule, then restart the manager:

sudo systemctl restart wazuh-manager

Step 4 - Porting the manager configuration

Do not copy the OSSEC ossec.conf over the Wazuh one. The Wazuh file contains many new sections (wodle, vulnerability-detection, sca, the API and auth settings) that the OSSEC file lacks. Instead, open the Wazuh file and port your settings section by section:

sudo nano /var/ossec/etc/ossec.conf

The sections below keep the same syntax, so you can move them across directly:

  • <syscheck>: your monitored <directories> and <ignore> entries. Wazuh also supports realtime="yes" on a directory for instant file integrity alerts on Linux.
  • <localfile>: extra log files the manager itself reads.
  • <global> email settings: <email_notification>, <smtp_server>, <email_from>, <email_to>.
  • <command> and <active-response> blocks.

For example, a syscheck block that watches /etc in real time and /usr/bin on the periodic scan:

<syscheck>
  <disabled>no</disabled>
  <frequency>43200</frequency>
  <directories realtime="yes">/etc</directories>
  <directories>/usr/bin,/usr/sbin</directories>
  <ignore>/etc/mtab</ignore>
</syscheck>

Copy your centralized agent configuration as well, so agents in the default group receive it:

sudo cp ~/ossec-migration/agent.conf /var/ossec/etc/shared/default/agent.conf
sudo chown wazuh:wazuh /var/ossec/etc/shared/default/agent.conf

Validate and restart:

sudo /var/ossec/bin/wazuh-analysisd -t
sudo systemctl restart wazuh-manager

Step 5 - Replacing the OSSEC agents

OSSEC and the Wazuh agent both install into /var/ossec, so remove OSSEC from each host before installing Wazuh. Migrate one low-risk agent first, confirm it reports, then continue with the rest.

On the agent host, stop OSSEC and keep a copy of its directory:

sudo /var/ossec/bin/ossec-control stop
sudo tar czf /root/ossec-agent-backup-$(date +%F).tar.gz /var/ossec

If OSSEC was installed from packages, remove the package (the name is usually ossec-hids-agent):

sudo apt remove ossec-hids-agent

If it was installed from source, there is no package; disable the init script and move the files out of the way:

sudo systemctl disable ossec
sudo mv /var/ossec /var/ossec.old
sudo mv /etc/ossec-init.conf /etc/ossec-init.conf.old

Add the Wazuh repository on the agent host with the same three commands as in Step 2, then install the agent. The WAZUH_MANAGER variable writes the manager address into the agent configuration during installation:

sudo apt update
sudo WAZUH_MANAGER="wazuh.your_domain" apt install wazuh-agent
sudo systemctl daemon-reload
sudo systemctl enable --now wazuh-agent

On start, the agent enrolls itself with the manager over port 1515 and receives a new key, so you do not need to copy the old OSSEC keys. On Rocky Linux or other RHEL-family agents, import the key with sudo rpm --import https://packages.wazuh.com/key/GPG-KEY-WAZUH, create /etc/yum.repos.d/wazuh.repo pointing at https://packages.wazuh.com/4.x/yum/, and install with sudo WAZUH_MANAGER="wazuh.your_domain" dnf install wazuh-agent.

Prevent unplanned agent upgrades from apt upgrade by holding the package, since the agent must never be newer than the manager:

sudo apt-mark hold wazuh-agent

Step 6 - Verifying the migration

On the Wazuh manager, list the connected agents:

sudo /var/ossec/bin/agent_control -l
Wazuh agent_control. List of available agents:
   ID: 000, Name: wazuh (server), IP: 127.0.0.1, Active/Local
   ID: 001, Name: web-01, IP: any, Active

Each migrated agent should be Active. Generate a test event on an agent, such as a failed SSH login or a change in a monitored directory, and watch it arrive on the manager:

sudo tail -f /var/ossec/logs/alerts/alerts.log

Once every agent reports to Wazuh and your custom rules fire as expected, stop the OSSEC manager and keep its backup archive for as long as your retention policy requires. Historical OSSEC alerts are plain text files in that archive; Wazuh does not import them.

Troubleshooting

The agent never appears on the manager. Check /var/ossec/logs/ossec.log on the agent. Unable to connect to enrollment service means port 1515 is blocked or wazuh.your_domain does not resolve; test with nc -zv wazuh.your_domain 1515.

The agent is registered but shows Disconnected. Port 1514 is blocked, or a stale entry with the same name exists. Remove the old entry on the manager with sudo /var/ossec/bin/manage_agents -r <agent_id> and restart the agent.

wazuh-analysisd -t fails after copying rules. The error names the rule ID. Look for duplicate IDs, IDs below 100000, or if_sid references to rules that do not exist in /var/ossec/ruleset/rules/.

Custom active responses do nothing. Check /var/ossec/logs/active-responses.log on the agent. Scripts written for OSSEC's argument-based interface must be rewritten for the JSON input format.

Conclusion

You backed up OSSEC, built a Wazuh manager on Ubuntu 24.04, ported your rules, decoders and configuration, and replaced each OSSEC agent with a Wazuh agent that enrolls automatically. Next, install the Wazuh indexer and dashboard to get the web interface and vulnerability detection, organize agents into groups with their own agent.conf, and review the Security Configuration Assessment results for each host.