Wazuh Backup and Recovery - SIEM Data Protection

Wazuh backups cover component configuration, custom rules and decoders, agent keys, API settings, and indexed data. Losing any of these elements requires a full platform reconfiguration or results in the loss of historical incident data. This guide details all critical elements to back up, available backup methods, and restore procedures.

What to Back Up

Wazuh Server (Manager)

ElementPathDescription
Main configuration/var/ossec/etc/ossec.confManager configuration
Custom rules/var/ossec/etc/rules/local_rules.xmlDetection rules
Custom decoders/var/ossec/etc/decoders/local_decoder.xmlLog parsing decoders
CDB lists/var/ossec/etc/lists/IoC lists and lookup tables
Shared agent configuration/var/ossec/etc/shared/Centralized group configurations
Agent keys/var/ossec/etc/client.keysAgent authentication keys
API configuration/var/ossec/api/configuration/RESTful API settings
SSL certificates/var/ossec/etc/sslmanager.*Agent communication certificates
Keystore/var/ossec/etc/keystore/Stored credentials
Active response/var/ossec/active-response/bin/Custom response scripts
Integrations/var/ossec/integrations/Custom integration scripts

Wazuh Indexer

ElementPathDescription
Configuration/etc/wazuh-indexer/opensearch.ymlMain configuration
JVM settings/etc/wazuh-indexer/jvm.optionsJVM parameters
Security configuration/etc/wazuh-indexer/opensearch-security/Roles, users, security settings
SSL certificates/etc/wazuh-indexer/*.pemTLS certificates
Index data/var/lib/wazuh-indexer/Indexed data (alerts, events)

Wazuh Dashboard

ElementPathDescription
Configuration/etc/wazuh-dashboard/opensearch_dashboards.ymlMain configuration
SSL certificates/etc/wazuh-dashboard/*.pemTLS certificates
Plugin configuration/usr/share/wazuh-dashboard/data/wazuh/config/wazuh.ymlWazuh plugin settings

Filebeat

ElementPathDescription
Configuration/etc/filebeat/filebeat.ymlMain configuration
Index template/etc/filebeat/wazuh-template.jsonWazuh template for the indexer
SSL certificates/etc/filebeat/*.pemTLS certificates

Backup Methods

Filesystem Backup

The simplest method is copying critical files and directories directly.

Full manager configuration backup:

#!/bin/bash
BACKUP_DIR="/backup/wazuh/$(date +%Y%m%d_%H%M%S)"
mkdir -p "$BACKUP_DIR"

# Manager
tar czf "$BACKUP_DIR/manager-config.tar.gz" \
  /var/ossec/etc/ossec.conf \
  /var/ossec/etc/rules/ \
  /var/ossec/etc/decoders/ \
  /var/ossec/etc/lists/ \
  /var/ossec/etc/shared/ \
  /var/ossec/etc/client.keys \
  /var/ossec/etc/sslmanager.* \
  /var/ossec/etc/keystore/ \
  /var/ossec/api/configuration/ \
  /var/ossec/active-response/bin/ \
  /var/ossec/integrations/ \
  2>/dev/null

# Indexer
tar czf "$BACKUP_DIR/indexer-config.tar.gz" \
  /etc/wazuh-indexer/opensearch.yml \
  /etc/wazuh-indexer/jvm.options \
  /etc/wazuh-indexer/opensearch-security/ \
  /etc/wazuh-indexer/*.pem \
  2>/dev/null

# Dashboard
tar czf "$BACKUP_DIR/dashboard-config.tar.gz" \
  /etc/wazuh-dashboard/opensearch_dashboards.yml \
  /etc/wazuh-dashboard/*.pem \
  /usr/share/wazuh-dashboard/data/wazuh/config/wazuh.yml \
  2>/dev/null

# Filebeat
tar czf "$BACKUP_DIR/filebeat-config.tar.gz" \
  /etc/filebeat/filebeat.yml \
  /etc/filebeat/wazuh-template.json \
  /etc/filebeat/*.pem \
  2>/dev/null

echo "Backup completed: $BACKUP_DIR"
ls -lh "$BACKUP_DIR"

Index Snapshots

For backing up indexed data (alerts, events), use the OpenSearch snapshot mechanism. This approach is far more efficient than copying data files and supports incremental snapshots.

Configuring a snapshot repository:

  1. Define the repository path in the indexer configuration (/etc/wazuh-indexer/opensearch.yml):
path.repo: ["/mnt/snapshots"]
  1. Create the directory and set permissions:
mkdir -p /mnt/snapshots
chown wazuh-indexer:wazuh-indexer /mnt/snapshots
  1. Restart the indexer:
systemctl restart wazuh-indexer
  1. Register the repository:
curl -sk -u admin:<PASSWORD> \
  -X PUT "https://localhost:9200/_snapshot/wazuh_backup" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "fs",
    "settings": {
      "location": "/mnt/snapshots",
      "compress": true
    }
  }'

Creating a snapshot:

# Snapshot of all Wazuh indices
curl -sk -u admin:<PASSWORD> \
  -X PUT "https://localhost:9200/_snapshot/wazuh_backup/snapshot_$(date +%Y%m%d)" \
  -H "Content-Type: application/json" \
  -d '{
    "indices": "wazuh-alerts-*,wazuh-archives-*,wazuh-monitoring-*,wazuh-statistics-*",
    "ignore_unavailable": true,
    "include_global_state": false
  }'

Checking snapshot status:

curl -sk -u admin:<PASSWORD> \
  "https://localhost:9200/_snapshot/wazuh_backup/snapshot_$(date +%Y%m%d)?pretty"

Listing available snapshots:

curl -sk -u admin:<PASSWORD> \
  "https://localhost:9200/_snapshot/wazuh_backup/_all?pretty"

API-Based Backup

The Wazuh API enables programmatic export of configuration and data.

Exporting the agent list:

TOKEN=$(curl -sk -u wazuh-wui:<PASSWORD> \
  -X POST "https://localhost:55000/security/user/authenticate?raw=true")

curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/agents?limit=500" \
  | jq '.data.affected_items' > /backup/wazuh/agents.json

Exporting group configuration:

curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/groups" \
  | jq '.data.affected_items' > /backup/wazuh/groups.json

Exporting custom rules:

curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/rules/files?status=custom" \
  | jq '.data.affected_items' > /backup/wazuh/custom-rules.json

Restoring from Backups

Restoring Manager Configuration

  1. Stop the manager service:
systemctl stop wazuh-manager
  1. Extract the backup:
tar xzf /backup/wazuh/20250101_120000/manager-config.tar.gz -C /
  1. Validate the configuration:
/var/ossec/bin/wazuh-control config-test
  1. Start the service:
systemctl start wazuh-manager

Restoring Indices from a Snapshot

  1. Close the target index (if it exists):
curl -sk -u admin:<PASSWORD> \
  -X POST "https://localhost:9200/wazuh-alerts-4.x-2025.01.01/_close"
  1. Restore the snapshot:
curl -sk -u admin:<PASSWORD> \
  -X POST "https://localhost:9200/_snapshot/wazuh_backup/snapshot_20250101/_restore" \
  -H "Content-Type: application/json" \
  -d '{
    "indices": "wazuh-alerts-*",
    "ignore_unavailable": true,
    "include_global_state": false
  }'
  1. Monitor the restore progress:
curl -sk -u admin:<PASSWORD> \
  "https://localhost:9200/_cat/recovery?v&active_only=true"

Restoring Indexer Configuration

  1. Stop the service:
systemctl stop wazuh-indexer
  1. Extract the configuration:
tar xzf /backup/wazuh/20250101_120000/indexer-config.tar.gz -C /
  1. Restore the security configuration:
systemctl start wazuh-indexer
/usr/share/wazuh-indexer/bin/indexer-security-init.sh

Disaster Recovery Plan

In the event of a complete server loss, follow these steps:

  1. Install all Wazuh components from scratch (see installation )
  2. Stop all services
  3. Restore configuration from backups (manager, indexer, Dashboard, Filebeat)
  4. Start components in the standard order: indexer, manager, Filebeat, Dashboard
  5. Restore index data from snapshots
  6. Verify agent connectivity - agents will reconnect automatically if client.keys has been restored

For recovery to a different environment (different IP address):

  • Update IP addresses in each component’s configuration
  • Reissue SSL certificates if necessary
  • Update agent configuration with the new manager address

Backup Automation

Daily Backup Script

Create the script at /usr/local/bin/wazuh-backup.sh:

#!/bin/bash
set -euo pipefail

BACKUP_BASE="/backup/wazuh"
RETENTION_DAYS=30
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="$BACKUP_BASE/$DATE"
ADMIN_PASS="<PASSWORD>"

mkdir -p "$BACKUP_DIR"

# Manager configuration
tar czf "$BACKUP_DIR/manager-config.tar.gz" \
  /var/ossec/etc/ossec.conf \
  /var/ossec/etc/rules/ \
  /var/ossec/etc/decoders/ \
  /var/ossec/etc/lists/ \
  /var/ossec/etc/shared/ \
  /var/ossec/etc/client.keys \
  /var/ossec/etc/sslmanager.* \
  /var/ossec/api/configuration/ \
  2>/dev/null || true

# Indexer configuration
tar czf "$BACKUP_DIR/indexer-config.tar.gz" \
  /etc/wazuh-indexer/opensearch.yml \
  /etc/wazuh-indexer/jvm.options \
  /etc/wazuh-indexer/opensearch-security/ \
  2>/dev/null || true

# Index snapshot
curl -sk -u admin:"$ADMIN_PASS" \
  -X PUT "https://localhost:9200/_snapshot/wazuh_backup/snapshot_$DATE" \
  -H "Content-Type: application/json" \
  -d '{
    "indices": "wazuh-alerts-*,wazuh-archives-*",
    "ignore_unavailable": true,
    "include_global_state": false
  }' > /dev/null 2>&1

# Remove old backups
find "$BACKUP_BASE" -maxdepth 1 -type d -mtime +$RETENTION_DAYS -exec rm -rf {} \;

# Remove old snapshots
for snap in $(curl -sk -u admin:"$ADMIN_PASS" \
  "https://localhost:9200/_snapshot/wazuh_backup/_all" \
  | jq -r '.snapshots[] | select(.start_time < "'$(date -d "-${RETENTION_DAYS} days" +%Y-%m-%dT%H:%M:%S)'") | .snapshot'); do
  curl -sk -u admin:"$ADMIN_PASS" \
    -X DELETE "https://localhost:9200/_snapshot/wazuh_backup/$snap" > /dev/null 2>&1
done

echo "$(date): Backup completed successfully" >> /var/log/wazuh-backup.log

Cron Configuration

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

# Daily backup at 02:00
echo "0 2 * * * root /usr/local/bin/wazuh-backup.sh" > /etc/cron.d/wazuh-backup

Troubleshooting

Snapshot Creation Fails

Verify the repository registration:

curl -sk -u admin:<PASSWORD> \
  "https://localhost:9200/_snapshot/wazuh_backup?pretty"

Confirm that the snapshot directory exists and is writable by the wazuh-indexer user.

Snapshot Restore Fails

The most common cause is that an index with the same name is already open. Close or delete the existing index before restoring:

curl -sk -u admin:<PASSWORD> \
  -X POST "https://localhost:9200/wazuh-alerts-4.x-2025.01.01/_close"

Agents Do Not Connect After Restore

Verify that client.keys was restored correctly and contains entries for all agents:

wc -l /var/ossec/etc/client.keys

If necessary, re-register agents through the agent management API .

Related Sections

Last updated on