Skip to content
Notifications
Clear all

Guide: Automating OPNsense backups to a remote S3 bucket

1 Posts
1 Users
0 Reactions
1 Views
(@carolinem)
Eminent Member
Joined: 1 week ago
Posts: 15
Topic starter   [#21639]

A common operational vulnerability in firewall management is the reliance on local, on-appliance backups. A hardware failure or site disaster can render not only the firewall inoperable but also its configuration recovery mechanism. To mitigate this, I've designed a robust, automated pipeline to push OPNsense configuration backups to a remote, versioned Amazon S3 bucket. This approach provides geographical redundancy, point-in-time recovery, and a full audit trail of configuration changes, which is critical for both security forensics and rollback procedures in A/B testing scenarios for network policy changes.

The core mechanism leverages the native OPNsense config backup script (`/usr/local/opnsense/scripts/system/config_backup.php`) triggered by cron, combined with the AWS Command Line Interface (AWS CLI) for secure uploads. The following steps assume you have root SSH access to your OPNsense appliance and a pre-configured S3 bucket with appropriate IAM credentials.

**Procedure:**

1. **Install AWS CLI:** The `py38-awscli` package is available in the OPNsense repository. Install via the GUI (System > Firmware > Plugins) or via shell:
```bash
pkg install py38-awscli
```

2. **Configure AWS Credentials:** Create an IAM user with permissions only for `s3:PutObject` and `s3:ListBucket` on your target bucket. Then, on the OPNsense shell, configure the CLI:
```bash
aws configure
```
Provide the Access Key, Secret Key, region (e.g., `us-east-1`), and set default output format to `json`.

3. **Create Backup & Upload Script:** Save the following script as `/usr/local/sbin/backup_to_s3.sh`. This script creates a timestamped backup, compresses it, and uploads it to a versioned S3 bucket. The `-q` flag to the backup script ensures only the backup file path is output, which we capture for processing.
```bash
#!/bin/sh
# Backup OPNsense config and sync to S3

BACKUP_DIR="/tmp/opnsense_backup"
BUCKET="s3://your-bucket-name/opnsense-backups/"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")

mkdir -p ${BACKUP_DIR}

# Generate encrypted backup (remove -q if you want verbose output)
BACKUP_FILE=$(/usr/local/opnsense/scripts/system/config_backup.php -q)

if [ -f "${BACKUP_FILE}" ]; then
# Compress backup
GZIP_FILE="${BACKUP_DIR}/config-${TIMESTAMP}.xml.gz"
gzip -c "${BACKUP_FILE}" > "${GZIP_FILE}"

# Upload to S3 with date-based prefix
/usr/local/bin/aws s3 cp "${GZIP_FILE}" "${BUCKET}${HOSTNAME}/config-${TIMESTAMP}.xml.gz"

# Cleanup local temp files
rm -f "${BACKUP_FILE}" "${GZIP_FILE}"
rmdir "${BACKUP_DIR}" 2>/dev/null

logger -t backup_to_s3 "Configuration successfully uploaded to S3."
else
logger -t backup_to_s3 "ERROR: Backup file generation failed."
exit 1
fi
```
Make the script executable: `chmod +x /usr/local/sbin/backup_to_s3.sh`.

4. **Automate with Cron:** Add a cron job via the OPNsense GUI (System > Settings > Cron). For example, to run daily at 02:00:
```
[2] [0] [*] [*] [*] [root] /usr/local/sbin/backup_to_s3.sh
```

**Key Considerations:**

* **Security:** The IAM policy should follow the principle of least privilege. Ensure the S3 bucket has encryption enabled (SSE-S3 or SSE-KMS) and block public access. The backup file itself is encrypted with the OPNsense password.
* **Retention Management:** Rely on S3 Lifecycle Policies to automatically transition older backups to Glacier or expire them after a defined period, rather than implementing custom deletion logic in the script.
* **Monitoring:** The script uses `logger` to write to the local syslog. For production, consider extending it to send a metric to CloudWatch or a similar monitoring service upon failure, enabling automated alerting.
* **Restoration Testing:** Periodically, you should test the restoration process by downloading a backup from S3 and using the OPNsense GUI restore function (`System > Configuration > Backups`) to validate integrity.

This method transforms a reactive, local backup strategy into a proactive, geographically distributed data resilience plan. For organizations employing network-level A/B testing or staged rollouts of firewall rules, this versioned history is invaluable for causal inference, allowing you to precisely correlate network changes with observed performance or security events.

- Dr. C


Nullius in verba


   
Quote