What You Get

Wazuh is an open-source security platform that combines SIEM, endpoint detection and response (EDR), file integrity monitoring, vulnerability detection, and compliance auditing in a single stack. It is built on the OSSEC fork and uses an OpenSearch-based indexer for log storage and a web dashboard for visualisation.

The all-in-one deployment puts three components on a single server: the Wazuh indexer (stores and indexes alert data), the Wazuh manager (receives agent data, runs analysis rules, triggers alerts), and the Wazuh dashboard (web interface for search, visualisation and management). This is the right model for a home lab, a small office, or any environment monitoring fewer than a hundred endpoints. Beyond that, split the components across dedicated servers.

By the end of this guide you have a hardened Wazuh server receiving security telemetry from every machine on your network — Linux servers, Windows workstations and macOS laptops — with file integrity monitoring, vulnerability scanning and real-time alerting configured out of the box.

Prerequisites

Hardware

The all-in-one server needs enough resources to run the indexer, manager and dashboard simultaneously. Minimum requirements depend on how many agents you plan to monitor:

Home lab (1–10 agents):

Small business (10–50 agents):

Upper limit for all-in-one (50–100 agents):

Storage grows with retention. Wazuh indexes roughly 2–5 GB per day per 100 agents depending on log volume. Plan your disk accordingly and set an index retention policy.

Network

The following ports must be accessible on the server:

Agents need outbound access to the server on ports 1514 and 1515. The dashboard and API ports only need to be reachable from your management network.

Part 1 — Ubuntu 24.04 LTS Server Deployment

This is the recommended deployment for production use.

Step 1: System Preparation

Start with a fresh Ubuntu 24.04 LTS server. Update it and install prerequisites:

sudo apt update && sudo apt upgrade -y
sudo apt install -y curl apt-transport-https gnupg2

Set the timezone to UTC:

sudo timedatectl set-timezone UTC

Set a meaningful hostname:

sudo hostnamectl set-hostname wazuh-server

Edit /etc/hosts so the hostname resolves locally:

127.0.0.1   localhost
YOUR_SERVER_IP  wazuh-server

Replace YOUR_SERVER_IP with the server's actual IP address.

Step 2: Firewall

sudo apt install -y ufw
sudo ufw allow 22/tcp
sudo ufw allow 443/tcp
sudo ufw allow 1514/tcp
sudo ufw allow 1515/tcp
sudo ufw allow 55000/tcp
sudo ufw enable

In production, restrict dashboard and API access to your management subnet:

sudo ufw delete allow 443/tcp
sudo ufw delete allow 55000/tcp
sudo ufw allow from 192.168.1.0/24 to any port 443
sudo ufw allow from 192.168.1.0/24 to any port 55000

Step 3: Increase System Limits

The Wazuh indexer (built on OpenSearch) requires higher file descriptor and memory map limits than Ubuntu's defaults. Create /etc/security/limits.d/wazuh.conf:

*  soft  nofile  65536
*  hard  nofile  65536
*  soft  memlock unlimited
*  hard  memlock unlimited

Set the virtual memory map count permanently. Add to /etc/sysctl.d/99-wazuh.conf:

vm.max_map_count = 262144

Apply immediately:

sudo sysctl -w vm.max_map_count=262144

Step 4: Install Wazuh All-in-One

Wazuh provides an installation assistant that handles the entire deployment. Download and run it:

curl -sO https://packages.wazuh.com/4.11/wazuh-install.sh
sudo bash wazuh-install.sh -a

The -a flag performs an all-in-one installation: indexer, manager and dashboard on a single node. The script handles certificate generation, component installation, and initial configuration automatically.

The installation takes several minutes. When it finishes, the script prints the dashboard credentials. Save these immediately — they are displayed only once:

INFO: --- Summary ---
INFO: You can access the web interface https://<wazuh-dashboard-ip>:443
    User: admin
    Password: <generated-password>

If you lose the password, extract it from the installation files:

sudo tar -O -xvf /root/wazuh-install-files.tar wazuh-install-files/wazuh-passwords.txt

Step 5: Verify the Installation

Check that all three services are running:

sudo systemctl status wazuh-indexer
sudo systemctl status wazuh-manager
sudo systemctl status wazuh-dashboard

All three should show active (running).

Open the dashboard in your browser at https://YOUR_SERVER_IP:443. Accept the self-signed certificate warning and log in with the credentials from Step 4.

Step 6: Replace the Self-Signed Certificate

The installation assistant generates self-signed certificates. For anything beyond a home lab, replace them with certificates from Let's Encrypt or your internal CA.

Install Certbot and obtain a certificate:

sudo apt install -y certbot
sudo systemctl stop wazuh-dashboard
sudo certbot certonly --standalone -d wazuh.example.com

Update the dashboard configuration. Edit /etc/wazuh-dashboard/opensearch_dashboards.yml:

server.ssl.enabled: true
server.ssl.certificate: "/etc/letsencrypt/live/wazuh.example.com/fullchain.pem"
server.ssl.key: "/etc/letsencrypt/live/wazuh.example.com/privkey.pem"

Set permissions so the dashboard service can read the certificates:

sudo chmod 640 /etc/letsencrypt/live/wazuh.example.com/privkey.pem
sudo chown root:wazuh-dashboard /etc/letsencrypt/live/wazuh.example.com/privkey.pem
sudo chmod 644 /etc/letsencrypt/live/wazuh.example.com/fullchain.pem

Restart the dashboard:

sudo systemctl start wazuh-dashboard

Set up automatic renewal with a deploy hook. Create /etc/letsencrypt/renewal-hooks/deploy/wazuh-dashboard.sh:

#!/bin/bash
systemctl restart wazuh-dashboard
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/wazuh-dashboard.sh
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer

Step 7: Harden the Server

Disable Unused Ports on the Indexer

The indexer listens on port 9200 by default for inter-node communication. In an all-in-one deployment, this only needs to be accessible locally. Edit /etc/wazuh-indexer/opensearch.yml:

network.host: 127.0.0.1

Restart the indexer:

sudo systemctl restart wazuh-indexer

Change the API Password

The Wazuh API uses a default password. Change it:

sudo /var/ossec/framework/scripts/wazuh-passwords-tool.sh -u wazuh -p 'YOUR_NEW_API_PASSWORD'

Use a strong password. Generate one with:

openssl rand -base64 32

Restrict API Access

Edit /var/ossec/api/configuration/api.yaml:

host: 127.0.0.1

This binds the API to localhost. The dashboard (running on the same machine) can still reach it. Remote API access, if needed, should go through an SSH tunnel or a reverse proxy with authentication.

File Permissions

sudo chmod 750 /var/ossec/etc
sudo chmod 640 /var/ossec/etc/ossec.conf
sudo chmod 640 /var/ossec/etc/client.keys

Kernel Hardening

Add to /etc/sysctl.d/99-hardening.conf:

net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.conf.all.log_martians = 1
kernel.randomize_va_space = 2

Apply:

sudo sysctl --system

Part 2 — Windows Host Deployment (Docker)

If your only available server is a Windows machine, you can run the entire Wazuh stack using Docker Desktop. This is suitable for home labs and small deployments where a dedicated Linux server is not available.

Step 1: Install Docker Desktop

Download Docker Desktop from docker.com and install it. During installation, ensure WSL 2 backend is selected — the Hyper-V backend works but WSL 2 offers better performance for Linux containers.

After installation, open Docker Desktop and verify it is running. Open PowerShell and confirm:

docker --version
docker compose version

Step 2: Increase WSL 2 Resources

The Wazuh stack needs more memory than Docker Desktop allocates by default. Create or edit %USERPROFILE%\.wslconfig:

[wsl2]
memory=8GB
processors=4
swap=2GB

Restart WSL:

wsl --shutdown

Then reopen Docker Desktop.

Step 3: Set the Virtual Memory Map Count

The Wazuh indexer requires an increased vm.max_map_count. Set it in WSL:

wsl -d docker-desktop -u root
sysctl -w vm.max_map_count=262144
echo "vm.max_map_count=262144" >> /etc/sysctl.conf
exit

This persists across WSL restarts.

Step 4: Clone the Wazuh Docker Repository

Open PowerShell and clone the official Wazuh Docker deployment:

cd C:\
git clone https://github.com/wazuh/wazuh-docker.git -b v4.11.0
cd wazuh-docker\single-node

Check the Wazuh Docker releases for the current version tag.

Step 5: Generate Certificates

The deployment needs TLS certificates for inter-component communication:

docker compose -f generate-indexer-certs.yml run --rm generator

Step 6: Start the Stack

docker compose up -d

This pulls the Wazuh indexer, manager and dashboard images and starts them. First run takes several minutes while Docker downloads the images.

Verify all containers are running:

docker compose ps

You should see three healthy containers: wazuh.manager, wazuh.indexer, and wazuh.dashboard.

Step 7: Access the Dashboard

Open https://localhost:443 in your browser. The default credentials are:

Change this password immediately. Edit the docker-compose.yml file and update the INDEXER_PASSWORD and API_PASSWORD environment variables before restarting, or change it through the dashboard's internal user management.

Step 8: Persistent Storage

The Docker Compose file maps named volumes for data persistence. Your data survives container restarts and upgrades. The volumes are:

To back up, use Docker's volume export:

docker run --rm -v wazuh-indexer-data:/data -v C:\Backups:/backup alpine tar czf /backup/wazuh-indexer-data.tar.gz -C /data .

Step 9: Firewall Rules

Windows Defender Firewall needs rules to allow agent connections. Open PowerShell as Administrator:

New-NetFirewallRule -DisplayName "Wazuh Agent" -Direction Inbound -Protocol TCP -LocalPort 1514,1515 -Action Allow
New-NetFirewallRule -DisplayName "Wazuh Dashboard" -Direction Inbound -Protocol TCP -LocalPort 443 -Action Allow

Part 3 — Agent Deployment

Agents are lightweight processes that run on each monitored endpoint. They collect log data, monitor file integrity, detect vulnerabilities, and report everything back to the Wazuh manager. Each agent needs the manager's IP address or hostname to connect.

In the examples below, replace WAZUH_MANAGER_IP with your server's actual IP address or DNS name.

Linux Agent (Ubuntu / Debian)

Step 1: Add the Wazuh Repository

curl -s https://packages.wazuh.com/key/GPG-KEY-WAZUH | sudo gpg --no-default-keyring --keyring gnupg-ring:/usr/share/keyrings/wazuh.gpg --import && sudo 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" | sudo tee /etc/apt/sources.list.d/wazuh.list
sudo apt update

Step 2: Install the Agent

WAZUH_MANAGER="WAZUH_MANAGER_IP" sudo apt install -y wazuh-agent

Setting WAZUH_MANAGER as an environment variable during installation automatically configures the agent to connect to your server. No manual configuration file editing is needed.

Step 3: Enable and Start the Agent

sudo systemctl daemon-reload
sudo systemctl enable wazuh-agent
sudo systemctl start wazuh-agent

Step 4: Verify the Connection

On the agent:

sudo grep "Connected to" /var/ossec/logs/ossec.log

You should see a line confirming connection to the manager. The agent also appears in the Wazuh dashboard under Agents within a few minutes.

Step 5: Prevent Accidental Upgrades

Lock the agent package version to prevent apt from upgrading it independently of the manager:

echo "wazuh-agent hold" | sudo dpkg --set-selections

Linux Agent (RHEL / CentOS / Fedora)

Step 1: Add the Wazuh Repository

Create /etc/yum.repos.d/wazuh.repo:

[wazuh]
gpgcheck=1
gpgkey=https://packages.wazuh.com/key/GPG-KEY-WAZUH
enabled=1
name=EL-$releasever - Wazuh
baseurl=https://packages.wazuh.com/4.x/yum/
protect=1

Step 2: Install the Agent

WAZUH_MANAGER="WAZUH_MANAGER_IP" sudo yum install -y wazuh-agent

Step 3: Enable and Start

sudo systemctl daemon-reload
sudo systemctl enable wazuh-agent
sudo systemctl start wazuh-agent

Step 4: Lock the Package

sudo yum versionlock wazuh-agent

If versionlock is not installed:

sudo yum install -y yum-plugin-versionlock

Windows Agent

Step 1: Download the Installer

Download the MSI installer from the Wazuh downloads page or use PowerShell:

Invoke-WebRequest -Uri https://packages.wazuh.com/4.x/windows/wazuh-agent-4.11.0-1.msi -OutFile $env:TEMP\wazuh-agent.msi

Check the Wazuh downloads page for the current version number.

Step 2: Install with Manager Configuration

Run the installer from an elevated PowerShell prompt, passing the manager address:

msiexec.exe /i $env:TEMP\wazuh-agent.msi /q WAZUH_MANAGER="WAZUH_MANAGER_IP" WAZUH_REGISTRATION_SERVER="WAZUH_MANAGER_IP"

The /q flag runs a silent installation. For a GUI installation, omit it and step through the wizard, entering the manager IP when prompted.

Step 3: Start the Service

NET START Wazuh

Or through PowerShell:

Start-Service -Name "Wazuh"

Step 4: Verify

Check the agent log at C:\Program Files (x86)\ossec-agent\ossec.log for a successful connection message. The agent should appear in the dashboard shortly after.

Step 5: Configure Windows-Specific Monitoring

The Windows agent monitors the Windows Event Log by default. To add specific channels, edit C:\Program Files (x86)\ossec-agent\ossec.conf and add entries under the <ossec_config> block:

<localfile>
  <location>Microsoft-Windows-Sysmon/Operational</location>
  <log_format>eventchannel</log_format>
</localfile>

<localfile>
  <location>Microsoft-Windows-PowerShell/Operational</location>
  <log_format>eventchannel</log_format>
</localfile>

<localfile>
  <location>Microsoft-Windows-Windows Defender/Operational</location>
  <log_format>eventchannel</log_format>
</localfile>

Restart the agent after making changes:

Restart-Service -Name "Wazuh"

Sysmon is particularly valuable. If it is not already installed, deploy it with a community ruleset such as SwiftOnSecurity's Sysmon config for comprehensive process, network and file monitoring.

macOS Agent

Step 1: Download the Installer

Download the PKG installer:

curl -sO https://packages.wazuh.com/4.x/macos/wazuh-agent-4.11.0-1.pkg

Check the Wazuh downloads page for the current version.

Step 2: Install with Manager Configuration

sudo launchctl setenv WAZUH_MANAGER "WAZUH_MANAGER_IP"
sudo installer -pkg wazuh-agent-4.11.0-1.pkg -target /

Step 3: Start the Agent

sudo /Library/Ossec/bin/wazuh-control start

Step 4: Load the Launch Daemon

Ensure the agent starts on boot:

sudo /bin/launchctl load /Library/LaunchDaemons/com.wazuh.agent.plist

Step 5: Grant Full Disk Access

macOS requires explicit permission for the agent to monitor system files and logs. Without this, the agent cannot read many important log sources.

Open System Settings > Privacy & Security > Full Disk Access and add /Library/Ossec/bin/wazuh-agentd. On older macOS versions, the path is through System Preferences > Security & Privacy > Privacy > Full Disk Access.

Without Full Disk Access, the agent runs but cannot monitor the Unified Log, many application logs, or perform complete file integrity monitoring.

Step 6: Verify

sudo /Library/Ossec/bin/wazuh-control status

All components should show as running. Check the log for connection confirmation:

sudo grep "Connected to" /Library/Ossec/logs/ossec.log

Part 4 — Server Configuration

With agents reporting in, configure the manager to make the most of the data it receives.

Agent Groups

Groups let you apply different monitoring policies to different types of endpoint. A Linux server needs different rules from a Windows workstation.

Create groups through the API or the dashboard. Using the command line:

sudo /var/ossec/bin/agent_groups -a -g linux-servers
sudo /var/ossec/bin/agent_groups -a -g windows-workstations
sudo /var/ossec/bin/agent_groups -a -g macos-laptops

Assign an agent to a group (replace 001 with the agent ID shown in the dashboard):

sudo /var/ossec/bin/agent_groups -a -i 001 -g linux-servers

Each group gets a shared configuration directory at /var/ossec/etc/shared/<group-name>/. Place an agent.conf file there to push configuration to all agents in the group.

File Integrity Monitoring

File integrity monitoring (FIM) is one of Wazuh's most valuable features. It watches directories for file creation, modification and deletion, and alerts on changes.

Edit the manager configuration at /var/ossec/etc/ossec.conf or push via group-specific agent.conf files.

Linux FIM Configuration

Add to the <syscheck> block:

<syscheck>
  <frequency>600</frequency>
  <directories check_all="yes" realtime="yes">/etc,/usr/bin,/usr/sbin,/bin,/sbin</directories>
  <directories check_all="yes" realtime="yes">/var/www</directories>
  <directories check_all="yes">/boot</directories>
  <ignore>/etc/mtab</ignore>
  <ignore>/etc/hosts.deny</ignore>
  <ignore>/etc/adjtime</ignore>
  <ignore type="sregex">.log$|.swp$</ignore>
</syscheck>

The realtime="yes" attribute uses inotify to detect changes immediately rather than waiting for the next scan cycle. The frequency (in seconds) controls how often a full scan runs.

Windows FIM Configuration

For Windows agents, push this through the windows-workstations group's agent.conf:

<agent_config os="Windows">
  <syscheck>
    <frequency>600</frequency>
    <directories check_all="yes" realtime="yes">C:\Windows\System32\drivers\etc</directories>
    <directories check_all="yes" realtime="yes">C:\Windows\System32\config</directories>
    <directories check_all="yes">C:\Program Files</directories>
    <directories check_all="yes">C:\Program Files (x86)</directories>
    <directories check_all="yes" realtime="yes">%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs\Startup</directories>
    <ignore type="sregex">.log$|.tmp$</ignore>
    <windows_registry>HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run</windows_registry>
    <windows_registry>HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce</windows_registry>
    <windows_registry>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services</windows_registry>
  </syscheck>
</agent_config>

The <windows_registry> entries monitor the registry for persistence mechanisms — autorun keys and service installations are among the most common footholds malware uses.

macOS FIM Configuration

<agent_config os="Darwin">
  <syscheck>
    <frequency>600</frequency>
    <directories check_all="yes" realtime="yes">/etc</directories>
    <directories check_all="yes">/usr/local/bin,/usr/local/sbin</directories>
    <directories check_all="yes" realtime="yes">/Library/LaunchDaemons</directories>
    <directories check_all="yes" realtime="yes">/Library/LaunchAgents</directories>
    <directories check_all="yes">~/Library/LaunchAgents</directories>
    <ignore type="sregex">.DS_Store$</ignore>
  </syscheck>
</agent_config>

The Launch Daemon and Launch Agent directories are critical — they are the macOS equivalent of Windows autorun keys.

Vulnerability Detection

Wazuh scans agents for known vulnerabilities by comparing installed packages against CVE databases. Enable it in /var/ossec/etc/ossec.conf:

<vulnerability-detector>
  <enabled>yes</enabled>
  <interval>12h</interval>
  <run_on_start>yes</run_on_start>
  <provider name="canonical">
    <enabled>yes</enabled>
    <os>jammy</os>
    <os>noble</os>
    <update_interval>1h</update_interval>
  </provider>
  <provider name="msu">
    <enabled>yes</enabled>
    <update_interval>1h</update_interval>
  </provider>
  <provider name="nvd">
    <enabled>yes</enabled>
    <update_interval>1h</update_interval>
  </provider>
</vulnerability-detector>

The canonical provider covers Ubuntu, msu covers Microsoft Windows updates, and nvd is the National Vulnerability Database for broader CVE coverage. Add redhat and alas providers if you run RHEL or Amazon Linux agents.

Restart the manager:

sudo systemctl restart wazuh-manager

Vulnerability data populates within an hour. View it in the dashboard under Vulnerabilities.

Active Response

Active response lets Wazuh take automatic action when specific rules trigger. Use this conservatively — an overly aggressive configuration locks out legitimate users.

A practical example: block an IP after five failed SSH authentication attempts. This is already configured by default but worth reviewing. In /var/ossec/etc/ossec.conf:

<active-response>
  <command>firewall-drop</command>
  <location>local</location>
  <rules_id>5712</rules_id>
  <timeout>1800</timeout>
</active-response>

Rule 5712 triggers on multiple SSH authentication failures. The firewall-drop command adds a firewall rule blocking the source IP for 1800 seconds (30 minutes). The local location means the block is applied on the agent that detected the attack, not on the manager.

For Windows agents, the equivalent uses the netsh command. Add a custom active response for Windows brute-force attacks:

<active-response>
  <command>netsh</command>
  <location>local</location>
  <rules_id>60122</rules_id>
  <timeout>1800</timeout>
</active-response>

Custom Rules

Wazuh's built-in ruleset covers thousands of scenarios. Add custom rules for your environment in /var/ossec/etc/rules/local_rules.xml. Never edit the default rules in /var/ossec/ruleset/ — they are overwritten on upgrade.

Example: alert when a new user is created on a Linux system:

<group name="local,syslog,useradd">
  <rule id="100001" level="10">
    <if_sid>5902</if_sid>
    <description>New user account created: $(dstuser)</description>
    <group>account_created,</group>
  </rule>
</group>

Example: alert when a critical Windows service stops:

<group name="local,windows">
  <rule id="100002" level="12">
    <if_sid>60009</if_sid>
    <field name="win.system.eventID">7036</field>
    <match>Windows Defender|WinDefend|MpsSvc</match>
    <description>Critical Windows service stopped: $(win.eventdata.param1)</description>
    <group>service_stopped,</group>
  </rule>
</group>

After adding rules, verify the syntax and restart:

sudo /var/ossec/bin/wazuh-logtest
sudo systemctl restart wazuh-manager

Use wazuh-logtest to paste a sample log line and confirm your rule triggers correctly before deploying it.

Email Alerts

Configure email notifications for high-severity alerts. Edit /var/ossec/etc/ossec.conf:

<global>
  <email_notification>yes</email_notification>
  <smtp_server>localhost</smtp_server>
  <email_from>wazuh@example.com</email_from>
  <email_to>admin@example.com</email_to>
  <email_maxperhour>12</email_maxperhour>
</global>

<email_alerts>
  <email_to>admin@example.com</email_to>
  <level>12</level>
  <do_not_delay />
</email_alerts>

This sends immediate email for alerts at level 12 or above (high severity), capped at 12 messages per hour to prevent floods. You need a local MTA (Postfix) or an SMTP relay configured.

For integration with Slack, Microsoft Teams, or PagerDuty, Wazuh supports webhook integrations. Add to /var/ossec/etc/ossec.conf:

<integration>
  <name>slack</name>
  <hook_url>https://hooks.slack.com/services/YOUR/WEBHOOK/URL</hook_url>
  <level>10</level>
  <alert_format>json</alert_format>
</integration>

Part 5 — Dashboard Usage

Key Views

After logging into the dashboard at https://YOUR_SERVER_IP:443:

Security Events — the main view. Shows all triggered alerts with severity levels, timestamps, and affected agents. Use the search bar with Wazuh Query Language (WQL) to filter: agent.name=webserver AND rule.level>=10 shows high-severity events from a specific agent.

Integrity Monitoring — file changes detected by FIM. Review this daily. Legitimate changes (package updates, configuration management) produce noise; suppress them with ignore rules. Unexpected changes — a binary modified outside a maintenance window, a new file in /etc/cron.d/ — need investigation.

Vulnerabilities — CVEs detected on each agent, sorted by severity. Focus on Critical and High vulnerabilities with known exploits. The dashboard links each CVE to its NVD entry.

MITRE ATT&CK — maps detected events to the MITRE ATT&CK framework. This view is useful for understanding what techniques an attacker might be using and which gaps in your detection exist.

Agents — lists all registered agents with their status, OS, IP address, group membership and last keep-alive time. An agent showing as disconnected for more than a few minutes needs attention.

Creating Custom Dashboards

Navigate to Dashboards Management > Dashboards and create visualisations tailored to your environment:

Save these as a custom dashboard and set it as the default view.

Part 6 — Maintenance

Index Management

The indexer stores alert data in daily indices. Without a retention policy, storage grows indefinitely. Configure index state management to delete old indices automatically.

Through the dashboard, navigate to Indexer Management > Index State Management Policies and create a policy:

For a home lab, 30 days is reasonable. For a small business, 90 days meets most compliance requirements. Adjust based on your storage capacity.

Alternatively, set this via the indexer API:

curl -k -u admin:YOUR_PASSWORD -X PUT "https://localhost:9200/_plugins/_ism/policies/wazuh-retention" -H 'Content-Type: application/json' -d '{
  "policy": {
    "description": "Wazuh index retention policy",
    "default_state": "hot",
    "states": [
      {
        "name": "hot",
        "actions": [],
        "transitions": [
          {
            "state_name": "delete",
            "conditions": {
              "min_index_age": "90d"
            }
          }
        ]
      },
      {
        "name": "delete",
        "actions": [
          {
            "delete": {}
          }
        ],
        "transitions": []
      }
    ],
    "ism_template": [
      {
        "index_patterns": ["wazuh-alerts-*"],
        "priority": 1
      }
    ]
  }
}'

Log Rotation

The manager generates its own logs. Configure rotation in /etc/logrotate.d/wazuh:

/var/ossec/logs/ossec.log
/var/ossec/logs/active-responses.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    create 0640 wazuh wazuh
}

Backups

Back up the manager configuration and agent keys daily:

#!/bin/bash
BACKUP_DIR="/var/backups/wazuh"
DATE=$(date +%F)
mkdir -p "$BACKUP_DIR"

# Manager configuration
tar czf "$BACKUP_DIR/wazuh-config-$DATE.tar.gz" \
    /var/ossec/etc/ossec.conf \
    /var/ossec/etc/rules/local_rules.xml \
    /var/ossec/etc/decoders/local_decoder.xml \
    /var/ossec/etc/shared/ \
    /var/ossec/etc/client.keys

# Indexer snapshot (optional — large)
# curl -k -u admin:YOUR_PASSWORD -X PUT "https://localhost:9200/_snapshot/wazuh_backup/snapshot-$DATE?wait_for_completion=true"

# Keep 30 days of backups
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +30 -delete

Save this as /usr/local/bin/wazuh-backup.sh, make it executable, and add a cron job:

sudo chmod +x /usr/local/bin/wazuh-backup.sh
sudo crontab -e

Add:

0 3 * * * /usr/local/bin/wazuh-backup.sh

Store backups off-server. A backup that lives only on the machine it protects is not a backup.

Updating Wazuh

Follow the official upgrade guide for version upgrades. The general process:

1. Back up the manager configuration and agent keys 2. Update the indexer, then the manager, then the dashboard — in that order 3. Verify all services restart cleanly 4. Check that agents reconnect (they are backwards-compatible within the same major version)

For the all-in-one deployment, the installation assistant supports in-place upgrades. Agent upgrades can be pushed centrally from the manager or dashboard rather than visiting each endpoint.

Summary

A Wazuh all-in-one deployment gives a home lab or small business a production-grade security monitoring platform at no licensing cost. The server runs on Ubuntu 24.04 LTS for production use, or on Docker Desktop on Windows for environments without a dedicated Linux host. Agents are lightweight and available for every major operating system. Configure file integrity monitoring for critical directories and registry keys, enable vulnerability detection against the NVD and vendor databases, set active response rules conservatively, and build a retention policy that matches your storage. The platform scales to a hundred endpoints on a single machine, and the same agents and rules carry over unchanged when you eventually split the components across dedicated servers.