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):
- 4 CPU cores
- 8 GB RAM
- 50 GB storage (SSD strongly recommended)
Small business (10–50 agents):
- 4–8 CPU cores
- 16 GB RAM
- 200 GB SSD storage
Upper limit for all-in-one (50–100 agents):
- 8 CPU cores
- 16–32 GB RAM
- 500 GB SSD storage
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:
- 1514/tcp — agent communication (event data)
- 1515/tcp — agent enrolment
- 443/tcp — Wazuh dashboard (HTTPS)
- 55000/tcp — Wazuh API
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:
- User: admin
- Password: SecretPassword
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:
wazuh_api_configuration— API settingswazuh_etc— manager configurationwazuh-indexer-data— indexed alert datawazuh_logs— manager logs
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:
- A pie chart of alerts by agent for spotting noisy or compromised endpoints
- A line graph of authentication failures over time for detecting brute-force campaigns
- A table of FIM events filtered to critical directories for change management auditing
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:
- Hot phase — current day's index, optimised for writes
- Delete phase — remove indices older than your retention period
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.