> ## Content Index
> Fetch the complete content index at: https://corelab.tech/llms.txt
> Use this file to discover other available public pages before exploring further.

# Automating OPNsense Backups: Hardened SFTP to NAS, Git Audits & REST API
- URL: https://corelab.tech/automating-opnsense-backups/
- Published: 2026-10-27T11:30:00.000Z
- Updated: 2026-11-02T03:21:56.000Z
- Description: How I automated my OPNsense firewall backups using hardened, key-only SFTP to OpenMediaVault, Git version control, and zero-dependency API scripts with full payload encryption.
- Author: Core Lab Joe
- Tags: OPNsense, OMV, Homelab, Linux, Automation, #2026, #table-of-content

You have spent hours meticulously tuning your OPNsense firewall, hardening your perimeter with CrowdSec, and dialing in a line-speed WireGuard tunnel for remote access. **Your network is a *fortress***. Or maybe it is not quite there yet: perhaps you had a gruelling afternoon just getting your basic WAN interface, VLAN trunks, and DHCP scopes functioning properly. Either way, you cannot afford to lose that work.

> When was the last time you actually **backed up** your firewall configuration? 

If your current disaster recovery plan consists of "I will remember to download the XML next time I change a rule," you are leaving your network recovery ***entirely*** to chance. It's... Also what I've done for an embarrassingly length of time, but, it's better than nothing.

![Hudson Game Over](https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExZm0yeWZ5b3l4aGF2YzdjeXBmeDc5aWUzYjY2Z3BneTNrNDh3OGkxNCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/ZuRkV9FEo1dra/giphy.gif) 

[Solid-state drives degrade, flash drives fry](https://corelab.tech/ssd-deaths-nas-upgrades-ghost-cms-home-assistant-and-massive-real-debrid-shock-awe/), and late-night syntax errors can lock you out of your web GUI without a rollback path. The default advice across many homelab forums is to ship un-encrypted configuration files directly to commercial cloud buckets like Google Drive or Nextcloud. That hands a complete blueprint of your network topology, internal IP scheme, WireGuard private keys, and administrative password hashes to a third party. 

> Someone's cloud storage inevitably suffers a credential leak, and you do not want it to be the bucket holding your firewall's brain.

**I prefer an air-gapped (*cloudless*), sovereign (privacy first!) approach**. In this guide, I break down three local, automated methods to secure your OPNsense configuration with zero external cloud dependencies:

1. **Hardened SFTP to OpenMediaVault (My Primary Architecture):** Using the native `os-sftp-backup` plugin to push encrypted, key-authenticated configuration snapshots straight to an isolated directory on your local NAS.
2. **Version-Controlled History with `os-git-backup`:** For homelabs running a private Git server (like Gitea or Forgejo) where off-box revision tracking and searchable commit logs are valuable.
3. **The Zero-Dependency API Script:** A standalone cron job using curl and OPNsense core API endpoints when you want backups without running additional plugins.

---

Learning Path • Firewall & Defensive Architecture 

### Mastering OPNsense Firewall Architecture 

Deploy enterprise-grade routing on bare metal, construct resilient alias hierarchies, enforce Layer 7 threat defence, and automate encrypted off-site disaster recovery. 

Lesson 7 of 7 100% Complete 

Difficulty Curve Advanced 

Beginner Advanced 

[ ✓ Lesson 01 · Planning & Hardware Completed The Ultimate OPNsense Architecture & Hardware Setup Guide → ](https://corelab.tech/opnsensept1/) [ ✓ Lesson 02 · Firewall Rules & NAT Completed Firewall Rules, NAT Configuration, and Traffic Flows → ](https://corelab.tech/opnsensept2/) [ ✓ Lesson 03 · Threat Defence & GeoIP Completed Advanced Threat Protection, CrowdSec & GeoIP Blocking → ](https://corelab.tech/opnsensept3/) [ ✓ Lesson 04 · Deep Packet Inspection Completed Suricata IDS/IPS in 26.4+: Inline vs Divert Mode Architecture → ](https://corelab.tech/opnsense-ids-ips-suricata-inline-vs-divert-mode/) [ ✓ Lesson 05 · Remote Access VPN Completed OPNsense WireGuard Road Warrior & Remote Access Guide → ](https://corelab.tech/opnsense-wireguard-guide/) [ ✓ Lesson 06 · Multi-Gigabit WAN Completed UGREEN USB 3.0 to 2.5GbE Adapter as OPNsense WAN Interface → ](https://corelab.tech/ugreen-usb-2-5g-opnsense-wan/) 

07 

Lesson 07 · Disaster Recovery Capstone Current Lesson 

Automating OPNsense Backups: Hardened SFTP, Git Audits & REST API 

Tested in production on bare-metal hardware 

Core Lab Learning Track · Zero Tracking & Direct Implementation 

---

## Method 1: Hardened SFTP Backups to OpenMediaVault (My Primary Architecture)

If your homelab already hosts a centralized storage server, sending encrypted firewall backups straight to it over SFTP is the cleanest, most durable architecture available. There are no third-party accounts, no external SaaS dependencies, and your snapshots land on storage pools that you already protect with your master backup routine.

Done carelessly, though, this connection can turn your NAS into an attack vector. If OPNsense authenticates to your storage server with root or an ***over-privileged*** account, any potential firewall compromise grants access to your entire storage array. In my lab, I enforce a strict **least-privilege, key-only architecture**. The firewall connects without a password, authenticates strictly via an ED25519 key, and is confined to a **single *dedicated* backup folder with no traversal rights elsewhere.**

Here is the automated workflow from memory encryption to storage retention:

flowchart TD
    subgraph OPN ["OPNsense Firewall (10.0.0.1)"]
        direction TB
        CFG["Config Change / Cron Trigger"] --> ENC["In-Memory AES Payload Encryption"]
        ENC --> SFTP_C["SFTP Client (ED25519 Private Key)"]
    end

    subgraph OMV ["OpenMediaVault 8 NAS (10.0.0.42)"]
        direction TB
        SSHD["OpenSSH Server (Port 22)"] --> AUTH["Auth via /var/lib/openmediavault/ssh/authorized_keys"]
        AUTH --> LZ["Isolated Landing Zone (/brain/home/omvbackup/opnsense)"]
        LZ --> ROT["Auto-Pruning Retention (Keep 30 Copies)"]
    end

    SFTP_C -- "Encrypted Transport (SSH Tunnel)" --> SSHD

### Phase 1: Preparing the OMV Service User & Landing Zone

Before touching OPNsense, establish the destination directory and restricted service user on your OpenMediaVault server.

1. **Create a Dedicated Service Account:** In OMV, navigate to **Users > Users** and click **\+ (Create)**. Name the account `srv-opnsense-backup`. The `srv-` naming standard clarifies that this is an automated system account rather than an interactive human user.
  - **Group Membership:** Add the user to the `_ssh` group (Debian and OMV require membership in `_ssh` for remote shell and SFTP access). Also ensure it belongs to the standard `users` group.
  - **Password Policy:** Leave the password empty or disabled. Authentication will happen strictly through cryptographic SSH keys.
  - **Shell:** Set the shell to `/usr/bin/bash` or `/bin/sh`. I set mine to `/usr/bin/bash`.
2. **Establish the Directory on Disk:** Create a dedicated subfolder inside your backup share specifically for the router (for example, `/brain/home/omvbackup/opnsense`). Avoid pointing OPNsense directly to the root of a broad backup share that houses container databases or bare-metal host images.

**Apply Native Linux Permissions (Bypassing the OMV ACL Trap):** Assign ownership and set permissions from the server terminal:

```bash
sudo chown -R srv-opnsense-backup:users /brain/home/omvbackup/opnsense
sudo chmod 2770 /brain/home/omvbackup/opnsense
```

![OpenMediaVault user edit screen showing srv-opnsense-backup with _ssh group membership and password disabled.](https://corelab.tech/content/images/2026/10/OPNsense-backup-user-in-OMV.webp)

Don't show the pub key to anyone, no need and especially not the private key in the OPN side!

⚠️ 

**Real-World Gotcha: The ZFS POSIX ACL Trap** In the OMV Web GUI under **Storage > Shared Folders**, there is an **ACL** action button. If your storage pool is formatted with ZFS (where `acltype=off` is standard) or mounted with `noacl`, clicking Save in that dialog will throw an unhandled `Server Error 500: setfacl: Operation not supported`. Do not use the GUI ACL tool. Setting standard Linux ownership (`chown srv-opnsense-backup:users`) and directory permissions (`chmod 2770`) as shown above is completely reliable and avoids breaking underlying permissions. 

### Phase 2: Generating the ED25519 SSH Keypair & OMV Configuration

The `os-sftp-backup` plugin requires an SSH key for authentication. Generate a clean, dedicated ED25519 keypair on your firewall or management machine. When prompted for a passphrase, **press Enter twice to leave it empty** (automated backup jobs run non-interactively in the background and cannot prompt for a passphrase):

```bash
ssh-keygen -t ed25519 -C "srv-opnsense-backup@codex" -f opnsense_sftp_key
```

This command generates two files:

- `opnsense_sftp_key`: The **Private Key** (which is pasted directly into OPNsense).
- `opnsense_sftp_key.pub`: The **Public Key** (which is registered in OpenMediaVault).

Next, install the public key into [OpenMediaVault](https://corelab.tech/setup-omv/):

1. In OMV, open **Users > Users**, select `srv-opnsense-backup`, and click the **Edit (Pencil)** icon.
2. Paste the entire single-line contents of `opnsense_sftp_key.pub` into the **SSH Public Keys** text field. Click **Save**.
3. **Apply the Pending Configuration Changes:** Look at the top of your OMV screen for the yellow confirmation banner ("Pending configuration changes"). **You must click the checkmark to apply changes.**

⚠️ 

**Real-World Gotcha: The OMV Staging Trap & Monit Namespace Rot** **1\. Staged vs Live:** When you paste an SSH key into OMV, it only writes to `/etc/openmediavault/config.xml`. The live authentication file at `/var/lib/openmediavault/ssh/authorized_keys/srv-opnsense-backup` is not written until you confirm the yellow banner. If you skip this, incoming SSH sessions fail immediately with `Connection closed by authenticating user [preauth]`.  
  
**2\. Monit Namespace Crash:** If your OMV server has been running for weeks or months, applying changes may throw an error: `Job for monit.service failed. ExecReload=/usr/bin/monit reload (code=exited, status=226/NAMESPACE)`. Systemd sandboxing causes stale mount namespaces when Docker containers and ZFS pools change over time. If this happens, run `sudo systemctl restart monit` in the OMV terminal to refresh the namespace, then re-click Apply. 

### Phase 3: Configuring the OPNsense `os-sftp-backup` Plugin

Now configure the client side on your OPNsense router.

1. **Install the Plugin:** Navigate to **System > Firmware > Plugins**. Search for `os-sftp-backup` and click **\+ (Install)**. Refresh your browser once the package finishes installing.
2. **Establish Host Key Trust (Known Hosts):** Before OPNsense can connect to an SFTP endpoint non-interactively, it must recognize and trust your NAS server's SSH host key. If you have never initiated an SSH connection from OPNsense to your NAS, the connection will be aborted. You can verify the host key by running an initial connection test or ensuring your NAS IP (e.g. `10.0.0.42`) has its host key fingerprint accepted.
3. **Configure the SFTP Backup Form:** Go to **System > Configuration > Backups > SFTP Backup** and populate the fields:
  - **Enabled:** Checked.
  - **SSH Private Key:** Open your private key file (`opnsense_sftp_key`) in a text editor, copy the entire block including the `-----BEGIN OPENSSH PRIVATE KEY-----` and `-----END OPENSSH PRIVATE KEY-----` lines, and paste it into this field. Ensure standard Unix LF line endings are preserved.
  - **Backup Count:** Enter your desired retention limit (e.g., `30`). OPNsense automatically prunes older backups once this threshold is exceeded.
  - **Encrypt Password:** Enter a strong passphrase here. This instructs OPNsense to encrypt the configuration XML using AES before it ever leaves system RAM. Even if someone manages to compromise your storage server, the backup files remain fully encrypted at rest.

**URL:** Enter the complete SFTP connection string. Use the double slash (`//`) syntax to specify an absolute path on the target server:

```text
sftp://srv-opnsense-backup@10.0.0.42//brain/home/omvbackup/opnsense
```

*Note: The double slash immediately following the host or port indicates to the SFTP client that the path is absolute from the filesystem root, rather than relative to the user's home folder.*

![OPNsense SFTP Backup settings form showing connection URL, private key block, retention count, and encryption password.](https://corelab.tech/content/images/2026/10/OPNsense-sftp-plugin-config.webp)

OPNsense SFTP Backup settings form showing connection URL, private key block, retention count, and encryption password.

![OPNsense Plugins page showing os-sftp-backup is installed.](https://corelab.tech/content/images/2026/10/OPNsense-plugin-list-showing-os-sftp-backup.webp)

OPNsense Plugins page showing os-sftp-backup is installed.

### Phase 4: Test, Verify, and Trigger Mechanics

Click **Save**, then click **Setup and Run Backup**. OPNsense will initiate an immediate SFTP transfer. You should see a green confirmation banner indicating the backup completed successfully.

To verify the landing zone, log into your OpenMediaVault server and inspect the target directory:

```bash
ls -lh /brain/home/omvbackup/opnsense/
```

You will see a fresh, timestamped configuration file (for example, `config-1729605600.xml` or an encrypted archive). If you open the file, you will observe the AES encrypted payload rather than plaintext firewall rules.

![OPNsense screenshot showing that your backup was successful!](https://corelab.tech/content/images/2026/10/OPNsense-SFTP-Backup-Successful-1.webp)

Backup successful! This means everything worked!

```BASH
❯ ll /brain/home/omvbackup/opnsense/
.rw------- 261k srv-opnsense-backup 22 Oct 10:04 󰗀 config-1792677895.3925.xml
```

Go check in OMV / your NAS to ensure the file is there!

**How the Automated Triggers Work:** The `os-sftp-backup` plugin hooks directly into OPNsense's internal configuration management system. Every time you modify a firewall rule, alias, or interface setting and click **Apply Changes**, an event trigger queues an automated background export. 

Additionally, OPNsense runs a scheduled cron job (configured under **System > Settings > Cron**) to verify your remote backup schedule remains synchronized.

The nice thing about OPNsense configuration history tab, is you get a nice coloured CLI highlighting the differences and changes made there between versions.

![Screenshot of OPNsense webgui showing the configuration history with coloured syntax highlighting.](https://corelab.tech/content/images/2026/10/OPNsense-configuration-history-webgui.webp)

Screenshot of OPNsense webgui showing the configuration history with coloured syntax highlighting.

---

## Method 2: Version-Controlled History with `os-git-backup` (For Git-Centric Homelabs)

If you already run a self-hosted Git server (such as Gitea, Forgejo, or GitLab) or maintain a private GitHub repository, treating your firewall configuration like infrastructure-as-code is a powerful option. However, it is worth distinguishing between what Git genuinely adds versus what OPNsense already provides out of the box.

### What Git Actually Adds vs. Built-in History

OPNsense already includes a built-in configuration audit tool under **System > Configuration > History**. This built-in screen provides unified colour-coded diffs between any two points in time and supports one-click rollbacks with zero plugins required.

What the `os-git-backup` plugin provides is **off-box durability and centralized team auditing**. If the physical SSD inside your firewall appliances dies completely, your local configuration history perishes with it. A remote Git repository preserves every commit safely off-box. Furthermore, if you manage your homelab alongside a family member or co-admin, a Git repository gives you familiar pull requests, blame annotations, and commit messages.

### The Setup Workflow

1. **Create a Blank Private Repository:** On your Git server, initialize a new empty repository (for example, `opnsense-firewall-backup`). Do not add a README, license, or `.gitignore` file. Copy the SSH clone URL.
2. **Install the Plugin:** In OPNsense, go to **System > Firmware > Plugins**, install `os-git-backup`, and reload your browser tab.
3. **Generate a Deploy Key:** Navigate to **System > Configuration > Backups > Git Backup**. Click **Generate Key** to produce a dedicated SSH public key.
4. **Authorize the Deploy Key:** On your Git server repository settings, add this public key under **Deploy Keys** and ensure you check the box granting **Write / Push** permissions.
5. **Configure the Repository URL:** Return to OPNsense, enable Git Backup, paste the SSH clone URL, and click **Save** followed by **Test Connection and Push**.

Commit events occur automatically whenever changes are applied to your firewall. However, the push to your remote Git server defaults to a scheduled nightly batch. If you require immediate synchronization, create a scheduled cron job under **System > Settings > Cron** using the "Remote Backup" command.

If you run a self-hosted ****Gitea or Forgejo** instance and want to see an enterprise-grade Infrastructure-as-Code pipeline with automated Ansible provisioning, in detail, check out the walk-through by fellow Canadian tech outlet Botum!

[OPNsense Backups via Git! ](https://blog.botum.ca/opnsense-backup-config-automatise/?ref=corelab.tech) 

---

## Method 3: The Zero-Dependency API Script

If you do not run a NAS or a Git server and prefer not to install third-party plugins on your router, you can pull automated backups using a lightweight shell script and OPNsense's native REST API.

First, create an API keypair with minimal privileges: Navigate to **System > Access > Users**, select your backup service account, and generate an **API Key**. This downloads an `apikey.txt` file containing your key and secret. In the user's privilege list, grant only **Diagnostics: Configuration History**. This restricts the API token strictly to configuration exports.

You can execute the following Bash script from any remote Linux server or local cron runner:

```bash
#!/usr/bin/env bash
# Pull an encrypted-in-transit OPNsense configuration backup via Core API
# Requires API key scoped strictly to "Diagnostics: Configuration History"

KEY="YOUR_API_KEY"
SECRET="YOUR_API_SECRET"
FW_HOST="10.0.0.1"
DESTINATION="/brain/home/omvbackup/opnsense"
DAYS_TO_KEEP=30

DATE_STAMP=$(date +%Y-%m-%d_%H%M%S)
OUTFILE="${DESTINATION}/config-${DATE_STAMP}.xml"

mkdir -p "${DESTINATION}"

HTTP_STATUS=$(curl -s -k -u "${KEY}:${SECRET}"   -o "${OUTFILE}"   -w "%{http_code}"   "https://${FW_HOST}/api/core/backup/download/this")

if [ "${HTTP_STATUS}" != "200" ]; then
  echo "Backup failed with HTTP status: ${HTTP_STATUS}" >&2
  rm -f "${OUTFILE}"
  exit 1
fi

gzip -f "${OUTFILE}"

# Prune archives older than retention window
find "${DESTINATION}" -name 'config-*.xml.gz' -mtime "+${DAYS_TO_KEEP}" -delete
```

*Note: The authoritative endpoint is `/api/core/backup/download/this`. Older third-party forum posts occasionally reference legacy paths like `/api/diagnostics/backup`, which is an invalid route.*

---

## Architectural Comparison: Which Method Fits Your Lab?

The table below summarizes the trade-offs across storage locality, audit visibility, encryption capability, and maintenance complexity:

| Method                     | Setup Complexity | Off-Box Protection | Unified Diffs & Audit | Encrypted At Rest | Recommended Use Case                                          |
| -------------------------- | ---------------- | ------------------ | --------------------- | ----------------- | ------------------------------------------------------------- |
| Hardened SFTP to OMV       | Low to Moderate  | Yes (Local NAS)    | Via Local History     | Yes (Native AES)  | Best overall for homelabs running local centralised storage.  |
| Git Backup (os-git-backup) | Moderate         | Yes (Git Server)   | Yes (Commit Diffs)    | Depends on Repo   | Homelabs with multiple admins or existing Git infrastructure. |
| Zero-Dependency Script     | Low              | Yes (Any Host)     | Via Local History     | Optional (GPG)    | Lightweight fallback without plugin dependencies.             |

---

## Conclusion: Resilient Perimeter Engineering

Automating your firewall backups eliminates the single point of failure that threatens every custom homelab setup. Whether you implement the encrypted SFTP pipeline to your OpenMediaVault server, configure an off-box Git repository, or run a five-line cron script, the engineering goal remains identical: **rebuilding your entire network infrastructure after catastrophic hardware failure should take minutes, not an entire lost weekend.**

> Take **twenty minutes today** to configure least-privilege key authentication, verify that your snapshots are landing on disk, and retire manual XML downloads for good.

---

## Frequently Asked Questions

### Does OPNsense back up its configuration automatically?

Yes, locally. Every configuration change is saved to **System > Configuration > History**, providing diff viewing and one-click rollbacks. However, this history resides on the firewall's internal boot disk. If that physical disk fails or suffers corruption, your local history is lost. The automated off-box methods in this guide resolve this vulnerability.

### Do I need Git to see what changed in my firewall configuration?

No. OPNsense's built-in Configuration History screen provides colour-coded unified diffs and instant revision rollback without requiring any plugins. The primary advantage of Git is securing an off-box copy of that audit trail that survives host hardware death.

### Is backing up over SFTP to my NAS secure?

Yes, provided you enforce least-privilege access: assign a dedicated service user with SSH-key-only authentication, confine it to a dedicated subfolder with standard Linux permissions, and enable AES payload encryption in the plugin so your configuration is encrypted before transmission.

### Can I restore from just part of a backup?

OPNsense allows selective section restores from the Configuration History interface, but doing so carries risks. For instance, restoring firewall rules without the corresponding interface aliases can create broken rule references. In a disaster recovery scenario, performing a full configuration restore is significantly safer.

---

### Related Lab Blueprints to Explore Next

To further harden your homelab infrastructure, explore these Core Lab guides:

- [**How to Setup OpenMediaVault 8 (OMV8) for 2026:**](https://corelab.tech/setup-omv/) Building the storage foundation, storage pools, user management, and secure shares from scratch.
- [**Beyond Default Deny: Reducing Attack Surface & Exposure:**](https://corelab.tech/security-through-obscurity-opnsense-guide/) Hardening your perimeter and securing services behind OPNsense.
- [**The Homelab Physical: A Guide to Annual & Bi-Annual Maintenance:**](https://corelab.tech/homelab-maintenance/) Establishing automated health audits, snapshot verification, and storage testing routines.