Skip to content

Instantly share code, notes, and snippets.

@karthicraghupathi
Last active December 30, 2024 02:01
Show Gist options
  • Save karthicraghupathi/2a11b8e9d8d8f74902cd74cb9525e445 to your computer and use it in GitHub Desktop.
Save karthicraghupathi/2a11b8e9d8d8f74902cd74cb9525e445 to your computer and use it in GitHub Desktop.
Backup OPNsense Configuration via API
#!/bin/bash
# #
# ███████╗██╗ ██╗███████╗███████╗████████╗ ██████╗ ██████╗ ██████╗ ██████╗ #
# ██╔════╝██║ ██║██╔════╝██╔════╝╚══██╔══╝██╔════╝ ██╔═══██╗██╔═══██╗██╔══██╗ #
# ███████╗██║ █╗ ██║█████╗ █████╗ ██║ ██║ ███╗██║ ██║██║ ██║██║ ██║ #
# ╚════██║██║███╗██║██╔══╝ ██╔══╝ ██║ ██║ ██║██║ ██║██║ ██║██║ ██║ #
# ███████║╚███╔███╔╝███████╗███████╗ ██║ ╚██████╔╝╚██████╔╝╚██████╔╝██████╔╝ #
# ╚══════╝ ╚══╝╚══╝ ╚══════╝╚══════╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═════╝ #
# #
# IT-Beratung mit Fokus auf Datensicherheit #
# #
# www.sweetgood.de #
# #
# Copyright : All rights reserved!
# Repository url : https://codeberg.org/SWEETGOOD/andersgood-opnsense-scripts
# Author : codiflow @ SWEETGOOD, Original sources below
# Filename : backup-opnsense-via-api.sh
# Created at : 2023-01-23
# Last changed at : 2024-01-18
# Description : Backup script for OPNsense API with optional GPG encryption
# Requirements : which, date, curl, gzip, find, gpg (optional)
# Original source: https://forum.opnsense.org/index.php?topic=15349.0
# Alternative script source: https://forum.opnsense.org/index.php?topic=18218.0
# Stop on error
set -e
###################################################
# CONFIGURE THE VARIABLES ACCORDING TO YOUR NEEDS #
###################################################
# API key and secret
# Create user in OPNsense, apply permission for "Backup API" to user or group
# and create the API key after creating the user. In newer OPNsense installations
# this permission is now "Diagnostics: Configuration History".
key="API key for backup user"
secret="API secret for backup user"
# Number of days to keep backups
daystokeep=30
# The path where you want to store your backups (can be every mounted folder)
destination="/path/to/firewall/backups"
# The hostname or IP for your firewall
# Add :PORT after the Hostname/IP if you changed the port for the webinterface
fwhost="firewall.fqdn or IP"
# Encryption (STRONGLY RECOMMENDED – change to false if you REALLY don't need it)
encrypt=true
# Only change this to true if you want to explicitly use the OLD and deprecated "os-api-backup" plugin
use_eol_endpoint=false
# Create GPG keypair beforehand and choose a secret passphrase using:
# gpg --full-gen-key
#
# Recommendation:
# Choose RSA, a key length of 4096 and don't set an expiration date on the certificate
# as the key should never leave the machine either
#
# To decrypt the file afterwards issue the following commands (make sure the GPG key of the locally stored identity is present):
# gpg -d BACKUPFILE.xml.gz.gpg > BACKUPFILE.xml.gz
# gzip -d BACKUPFILE.xml.gz
identityemail="Email address of locally stored GPG identity"
# Current date and time (for creating backup filename)
date=$(date +%Y-%m-%d-%H-%M-%S)
#####################################
# NOTHING NEEDS TO BE CHANGED BELOW #
#####################################
# Check if dependencies are installed
which curl &> /dev/null || (echo "curl is missing, please install curl to use this script (e.g using 'sudo apt install curl')."; exit 1)
which gzip &> /dev/null || (echo "gzip is missing, please install gzip to use this script (e.g using 'sudo apt install gzip')."; exit 1)
if $encrypt; then
which gpg &> /dev/null || (echo "gpg is missing and you've choosen to encrypt your backups. Please install gpg to use this script (e.g using 'sudo apt install gpg')."; exit 1)
fi
# Check if GPG key exists while encryption is enabled
if $encrypt; then
gpg -k $identityemail &> /dev/null || (echo "GPG key is missing. Please check if identity exists and the variable 'identityemail' is set correctly."; exit 1)
fi
# Create backup dir if it does not exist
[ -d "$destination" ] || mkdir -p $destination
# Select API endpoint
if $use_eol_endpoint; then
api_endpoint="/api/backup/backup/download"
else
api_endpoint="/api/core/backup/download/this"
fi
# Check if API is reachable
result=$(curl -I -s -k -u "$key":"$secret" https://$fwhost$api_endpoint | head -1)
if [[ $result != *"200"* ]]; then
echo "Result of the HTTP request was $result"
exit 1
fi
# Get current unencrypted backup via cURL and save as file
curl -s -k -u "$key":"$secret" https://$fwhost$api_endpoint > "$destination/$date.xml"
error=$?
# Check for errors
if [ $error -gt 0 ]; then
echo "cURL returned error number $error"
exit 1
fi
# Compress the backup file
gzip "$destination/$date.xml"
# If encryption is enabled
if $encrypt; then
# Encrypt the backup file
gpg -e --recipient "$identityemail" "$destination/$date.xml.gz"
# Remove unencrypted backup file (-f to prevent exit of script on error)
rm -f "$destination/$date.xml.gz"
fi
# Data retention (only backup files) (-f to prevent exit of script on error)
if $encrypt; then
find $destination/*.xml.gz.gpg -mtime +$daystokeep -exec rm -f {} \;
else
find $destination/*.xml.gz -mtime +$daystokeep -exec rm -f {} \;
fi
@karthicraghupathi
Copy link
Author

karthicraghupathi commented Dec 30, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment