# Wazuh Backup and Recovery - SIEM Data Protection

> Wazuh 4.14 backup procedures covering configuration, rules, decoders, agent keys, indexer snapshots, restore operations, and automation

Source: https://opennix.org/en/docs/wazuh/operations/wazuh-backup/


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)

| Element | Path | Description |
|---|---|---|
| Main configuration | `/var/ossec/etc/ossec.conf` | Manager configuration |
| Custom rules | `/var/ossec/etc/rules/local_rules.xml` | Detection rules |
| Custom decoders | `/var/ossec/etc/decoders/local_decoder.xml` | Log 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.keys` | Agent 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

| Element | Path | Description |
|---|---|---|
| Configuration | `/etc/wazuh-indexer/opensearch.yml` | Main configuration |
| JVM settings | `/etc/wazuh-indexer/jvm.options` | JVM parameters |
| Security configuration | `/etc/wazuh-indexer/opensearch-security/` | Roles, users, security settings |
| SSL certificates | `/etc/wazuh-indexer/*.pem` | TLS certificates |
| Index data | `/var/lib/wazuh-indexer/` | Indexed data (alerts, events) |

### Wazuh Dashboard

| Element | Path | Description |
|---|---|---|
| Configuration | `/etc/wazuh-dashboard/opensearch_dashboards.yml` | Main configuration |
| SSL certificates | `/etc/wazuh-dashboard/*.pem` | TLS certificates |
| Plugin configuration | `/usr/share/wazuh-dashboard/data/wazuh/config/wazuh.yml` | Wazuh plugin settings |

### Filebeat

| Element | Path | Description |
|---|---|---|
| Configuration | `/etc/filebeat/filebeat.yml` | Main configuration |
| Index template | `/etc/filebeat/wazuh-template.json` | Wazuh template for the indexer |
| SSL certificates | `/etc/filebeat/*.pem` | TLS certificates |

## Backup Methods

### Filesystem Backup

The simplest method is copying critical files and directories directly.

**Full manager configuration backup:**

```bash
#!/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`):

```yaml
path.repo: ["/mnt/snapshots"]
```

2. Create the directory and set permissions:

```bash
mkdir -p /mnt/snapshots
chown wazuh-indexer:wazuh-indexer /mnt/snapshots
```

3. Restart the indexer:

```bash
systemctl restart wazuh-indexer
```

4. Register the repository:

```bash
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:**

```bash
# 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:**

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

**Listing available snapshots:**

```bash
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:**

```bash
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:**

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

**Exporting custom rules:**

```bash
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:

```bash
systemctl stop wazuh-manager
```

2. Extract the backup:

```bash
tar xzf /backup/wazuh/20250101_120000/manager-config.tar.gz -C /
```

3. Validate the configuration:

```bash
/var/ossec/bin/wazuh-control config-test
```

4. Start the service:

```bash
systemctl start wazuh-manager
```

### Restoring Indices from a Snapshot

1. Close the target index (if it exists):

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

2. Restore the snapshot:

```bash
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
  }'
```

3. Monitor the restore progress:

```bash
curl -sk -u admin:<PASSWORD> \
  "https://localhost:9200/_cat/recovery?v&active_only=true"
```

### Restoring Indexer Configuration

1. Stop the service:

```bash
systemctl stop wazuh-indexer
```

2. Extract the configuration:

```bash
tar xzf /backup/wazuh/20250101_120000/indexer-config.tar.gz -C /
```

3. Restore the security configuration:

```bash
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](/docs/wazuh/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`:

```bash
#!/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

```bash
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:

```bash
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:

```bash
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:

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

If necessary, re-register agents through the [agent management API](/docs/wazuh/infrastructure/wazuh-agent-management/).

## Related Sections

- [Upgrading Wazuh](/docs/wazuh/operations/wazuh-upgrade/) - creating backups before upgrades
- [Troubleshooting](/docs/wazuh/operations/wazuh-troubleshooting/) - diagnosing issues after restore
- [Indexer Cluster](/docs/wazuh/infrastructure/wazuh-indexer-cluster/) - snapshots in cluster configurations

