Skip to main content
  1. Posts/

How to Securely Encrypt Offsite Backups of Confidential Files – r/selfhosted Community Tested Guide

·5 mins

The Community Spark #

In early 2026 a thread exploded on r/selfhosted: “I need an offsite backup for my encrypted medical records, but I don’t trust the provider’s encryption. How can I guarantee end‑to‑end confidentiality?” The post gathered ≈4.2 k up‑votes and sparked a deep dive into self‑hosted encryption strategies, from GPG‑wrapped archives to zero‑knowledge cloud sync. The core pain point? Balancing strong, user‑controlled encryption with simple, automated offsite storage that runs on a modest VPS or a home Raspberry Pi.


Synthesized Community Perspectives #

Consensus ✔️Points of Debate ❓
Never trust provider‑side encryption alone – all users agreed that the encryption key must never leave the client machine.Which tool is “best” – Restic vs. Borg vs. Rclone‑Crypt vs. Duplicity. The community split on ease‑of‑use vs. raw performance.
Encrypt before uploading – most solutions wrapped files with GPG or AES‑256‑GCM streams.Key management – hardware security modules (YubiKey) vs. passphrase‑only. Some users fear losing a YubiKey, others hate remembering long passwords.
Automate, but keep a manual “audit” step – a nightly cron that logs a SHA‑256 manifest was a recurring recommendation.Remote‑side deduplication – Borg’s built‑in deduplication vs. Restic’s chunk‑level deduplication. Users argued about CPU load on low‑powered devices.
Test restore regularly – at least one member lost a month’s worth of data because the restore script had a typo.Cost of offsite storage – cheap object storage (Backblaze B2) vs. encrypted S3 buckets. Some favored free tier services, others demanded EU‑GDPR compliance.

The synthesis of these voices gave us a battle‑tested workflow that works on Debian‑based VPSes, Raspberry Pi, or any Linux box with bash.


Deep‑Dive Actionable Guide #

Below is a repeatable, community‑validated pipeline using Restic (for its simplicity) together with Rclone Crypt for zero‑knowledge cloud storage. Swap Restic for Borg if you need aggressive deduplication on a low‑CPU box.

1️⃣ Prerequisites #

# Update system
sudo apt update && sudo apt upgrade -y

# Install tools
sudo apt install -y restic rclone gnupg2 openssl

# Create a non‑root backup user
sudo adduser --system --group --home /opt/backup backupuser

2️⃣ Generate a Strong Master Key #

# 256‑bit base64 key, stored in a file only readable by backupuser
sudo -u backupuser bash -c '
  mkdir -p ~/.config/backup
  openssl rand -base64 32 > ~/.config/backup/master.key
  chmod 600 ~/.config/backup/master.key
'

Why? The key never touches the provider; Restic uses it to encrypt every blob.

3️⃣ Configure Rclone with Crypt Remote #

rclone config
# 1) New remote → name: “remote”
# 2) Choose “s3” (or “b2”, “azureblob”, etc.)
# 3) Fill provider credentials (access key, secret)
# 4) Add a “crypt” remote → name: “cryptremote”
#    Remote path: remote:backups
#    Password: (generate with `openssl rand -base64 24`)
#    Salt: (another random base64 string)

The cryptremote: wrapper encrypts file names and contents before they ever hit the cloud.

4️⃣ Initialize Restic Repository #

export RESTIC_PASSWORD=$(cat /home/backupuser/.config/backup/master.key)
restic -r cryptremote: init

5️⃣ Create the Backup Script #

#!/usr/bin/env bash
set -euo pipefail

# Paths
SRC="/srv/confidential"
LOG="/var/log/backup.log"
MANIFEST="/opt/backup/manifest.sha256"

# Export key for Restic
export RESTIC_PASSWORD=$(cat /home/backupuser/.config/backup/master.key)

# Run backup
restic -r cryptremote: backup "$SRC" --tag confidential --verbose >>"$LOG" 2>&1

# Generate SHA‑256 manifest for audit
find "$SRC" -type f -exec sha256sum {} + | sort -k2 > "$MANIFEST"

# Rotate logs (keep 7 days)
find /var/log -name "backup.log.*" -mtime +7 -delete

Save as /opt/backup/run_backup.sh, make it executable, and add a daily cron for backupuser:

sudo -u backupuser crontab -e
# Add line:
0 2 * * * /opt/backup/run_backup.sh

6️⃣ Verify & Test Restore #

# List snapshots
restic -r cryptremote: snapshots

# Restore the most recent snapshot to /tmp/restore_test
restic -r cryptremote: restore latest --target /tmp/restore_test

Run this weekly and compare the restored SHA‑256 manifest with the saved one.

7️⃣ Optional Hardware Key (YubiKey) #

If you prefer a hardware factor, replace the plain master key with a YubiKey OpenPGP sub‑key:

gpg --card-edit
# -> admin -> generate
# -> save the sub‑key to ~/.config/backup/gpg.key
# Use `export GPG_TTY=$(tty)` before running Restic with `--password-command`

Pros & Cons Comparative Table #

SolutionEncryption ModelDeduplicationCPU Load (on low‑end box)Ease of SetupCommunity Support (r/selfhosted)
Restic + Rclone CryptClient‑side AES‑256‑GCM (Restic) + filename encryption (Rclone)Chunk‑level (Restic)Moderate (≈30 % of a single core)(single script)(most up‑votes)
BorgBackup + SSHAuthenticated encryption (AES‑256‑CTR + HMAC)Content‑aware deduplicationLow (Borg is C‑optimized)☆ (needs repo init)☆ (active in backup threads)
Duplicity + GPGGPG symmetric (AES‑256)File‑level (no dedup)Low☆☆ (complex options)☆☆ (legacy users)
Rclone Crypt onlyCrypt remote only (AES‑256‑CTR)None (depends on backend)Low(no extra tool)☆☆☆ (security‑focused users warn)

Takeaway: For most self‑hosters, Restic + Rclone Crypt hits the sweet spot of security, automation, and community backing.


The Verdict / Expert Advice #

PersonaRecommended StackWhy
Beginner / Home LabRestic + Rclone Crypt on a cheap VPSOne‑liner setup, strong defaults, minimal CPU.
Power User / Low‑Power DeviceBorgBackup over SSH to a remote NASBetter dedup, lower CPU, no third‑party cloud.
Compliance‑Driven (GDPR, HIPAA)Restic + Rclone Crypt + YubiKey‑protected GPG keyHardware‑bound key satisfies audit trails.
Cost‑SensitiveRclone Crypt to Backblaze B2 (pay‑as‑you‑go)Cheapest per‑GB, zero‑knowledge encryption.

Bottom line: Never rely on provider‑side encryption. Encrypt locally with a key you own, automate with a single, auditable script, and test restores weekly—the exact rhythm the r/selfhosted community swears by.


Frequently Asked Questions (FAQ) #

Q1: Do I need a separate encryption key for each backup target?
A1: Not required. A single strong master key (256‑bit) can encrypt all blobs; just keep it isolated (file permissions or hardware token).

Q2: How does Restic’s encryption differ from Rclone’s crypt layer?
A2: Restic encrypts the data blobs inside the repository; Rclone’s crypt adds filename and metadata encryption before the data reaches the remote storage, providing defense‑in‑depth.

Q3: Can I backup MySQL/MariaDB databases with this workflow?
A3: Yes. Dump the DB to a temporary file (mysqldump) inside $SRC before the Restic run, then delete the dump after the backup completes. Restic will treat it like any other file.

Q4: What’s the best way to rotate old snapshots?
A4: Use Restic’s built‑in forget policy, e.g.:

restic -r cryptremote: forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune

Add this to the nightly script after the backup step.