Offsite backup with rclone to S3 or Backblaze B2 on Linux

Set up encrypted offsite backup on Linux using rclone with Backblaze B2 or Amazon S3. Includes cron scheduling, restore procedure and integrity verification.

A Linux server with important data needs offsite backup — in a physically separate location from the primary infrastructure, ideally with another provider to survive regional incidents or account compromise. Rclone solves this with optional end-to-end encryption, checksum-based deduplication and native support for S3, Backblaze B2 and more than 40 other storage backends.

This tutorial shows how to set up rclone on a Linux VPS (Ubuntu 22.04/24.04 or Debian 12) to copy directories to Backblaze B2 or Amazon S3, encrypted with a key that not even the storage provider can read. We cover installation, remote creation, the crypt layer, cron scheduling, integrity verification and restore procedure.

Estimated time: 30-40 minutes for the first setup, including creating the storage provider account. Initial backup varies depending on data volume and bandwidth.

Prerequisites

What you need before starting

Linux VPS with sudo access, outbound connection allowed on port 443 (HTTPS), at least 100 MB free in /usr/bin for the rclone binary and cache, and an active Backblaze B2 or AWS S3 account. The commands below assume Ubuntu 22.04+ or Debian 12, but work on any distribution with package manager adaptation.

Tested distribution Ubuntu 22.04 / 24.04
Minimum rclone version 1.65+
Backends covered S3, B2
Free storage ~100 MB

Have the credentials for your chosen provider ready before starting:

  • Backblaze B2: Application Key ID + Application Key (created under “App Keys” in the B2 panel, with permissions on the target bucket)
  • Amazon S3: Access Key ID + Secret Access Key (IAM user with policy allowing s3:PutObject, s3:GetObject, s3:DeleteObject and s3:ListBucket on the bucket)

Installing rclone

Rclone is distributed as a single binary — installing via the distribution package usually brings an old version (1.53 on Ubuntu 22.04, for example) with known bugs in the B2 backend. Use the official installer to get the current release.

01

Download and run the official installer:

curl https://rclone.org/install.sh | sudo bash

The script detects the architecture (amd64, arm64), downloads the binary from GitHub, installs it in /usr/bin/rclone and generates the man page. The final output prints the installed version — confirm it is above 1.65.

02

Verify the installation:

rclone version

Expected output starts with rclone v1.6x.x followed by the OS, arch and Go version lines. If “command not found” appears, /usr/bin is not in the current shell’s PATH — open a new session or run hash -r.

Setting up the remote on Backblaze B2

B2 is the default choice for beginners: storage costs about USD 6 per TB/month and egress is free up to 3x the stored volume per month (enough for occasional restores at no extra cost).

03

Create the Application Key in the B2 panel with access to the bucket that will receive the backups. Save the keyID and applicationKey — B2 only shows the applicationKey once. Also create the destination bucket (private, no server-side encryption — we will encrypt on the client side).

04

Start the rclone interactive configurator:

rclone config

Select n (new remote), name it b2-raw, choose type 5 (Backblaze B2). Paste the keyID in “account” and the applicationKey in “key”. Confirm with y when asked if you want to accept the remaining defaults.

05

Test the connection by listing the buckets:

rclone lsd b2-raw:

Output should show the account’s buckets, one per line, with the creation date. A 401 unauthorized error means incorrect keyID/applicationKey or the Application Key was revoked in the panel.

Setting up the remote on Amazon S3 (alternative)

If you prefer S3, the procedure is equivalent — the crypt layer configured later works identically over any backend.

06

Run rclone config, choose n, name it s3-raw, type 4 (Amazon S3). In “provider” select AWS. In “env_auth” leave false to paste credentials manually. Paste access_key_id and secret_access_key. In “region” choose the bucket region (e.g., us-east-1, sa-east-1). In “storage_class” leave empty for Standard or choose STANDARD_IA for infrequent access (cheaper for rarely read backup).

Storage class matters a lot for cost

For backup you rarely restore, STANDARD_IA costs half of Standard but charges retrieval. For backup that is never read unless in disaster, GLACIER_DEEP_ARCHIVE costs a tenth but takes 12-48h to restore. Don’t use Glacier for daily rotating backup — the early deletion fee (180 days) cancels the savings.

Adding the crypt layer

This is the critical part: crypt encrypts file names and content with NaCl Secretbox (XSalsa20+Poly1305) before sending to the remote backend. Without the crypt password, the storage provider only sees opaque blocks.

07

In rclone config, create another remote with n, name it b2-crypt (or s3-crypt), type 13 (crypt). In “remote” enter b2-raw:bucket-name/backups (replace with your bucket and path). In “filename_encryption” choose 1 (standard — hides names). In “directory_name_encryption” choose true.

08

When asked for the password, choose g (generate random) — generates a strong 1024-bit password. Copy and store the generated password in a password manager before continuing. Without this password, the backup is unrecoverable even with access to the bucket.

Lost password, lost backup

Crypt is symmetric — there is no recovery. Before moving data to production, do a restore test on a clean server using only the saved password. Save the password in at least two different physical locations (personal password manager + company vault).

09

For “password2” (salt), also use g to generate randomly. Save it together with the main password. Confirm with y in the summary, then q to exit the configurator.

Running the first backup

With the remotes configured, the backup is a single rclone copy call. Unlike sync, copy only adds or updates files — it never deletes from the destination.

10

Run the initial backup of /var/www and /etc:

rclone copy /var/www b2-crypt:var-www \
  --progress \
  --transfers 4 \
  --checkers 8 \
  --bwlimit 50M

The --progress flag shows ETA and throughput in real time. --transfers 4 defines how many files are uploaded in parallel. --bwlimit 50M limits to 50 MB/s to avoid saturating the server’s network (adjust to your bandwidth).

First backup may take hours

On a 100 Mbit/s link, transferring 100 GB takes about 2h30 without overhead. Use tmux or screen to avoid losing progress if the SSH session drops. Or run with nohup ... & redirecting output to a file.

Scheduling daily backups via cron

After the initial backup, schedule incremental runs — rclone only transfers new or modified files (checks modtime + size, or checksum with --checksum).

11

Create a wrapper script at /usr/local/bin/backup-offsite.sh:

sudo tee /usr/local/bin/backup-offsite.sh > /dev/null <<'EOF'
#!/bin/bash
set -euo pipefail

LOG=/var/log/rclone-backup.log
exec >> "$LOG" 2>&1

echo "=== Backup started at $(date -Iseconds) ==="

rclone copy /var/www b2-crypt:var-www \
  --transfers 4 \
  --checkers 8 \
  --bwlimit 50M \
  --log-level INFO

rclone copy /etc b2-crypt:etc \
  --transfers 2 \
  --log-level INFO

echo "=== Backup completed at $(date -Iseconds) ==="
EOF

sudo chmod +x /usr/local/bin/backup-offsite.sh

The set -euo pipefail makes the script abort on any error. The exec >> redirects stdout and stderr to the log at once.

12

Add an entry to root’s crontab to run every day at 3 AM:

sudo crontab -e

Add the line:

0 3 * * * /usr/local/bin/backup-offsite.sh

Save and exit. Cron reads the crontab automatically — no need to restart the service.

Verifying integrity

rclone check compares checksums between source and destination. For crypt, it decrypts the remote hashes and compares them with the local ones — any corruption in transit or in storage shows up.

13

Run the verification:

rclone check /var/www b2-crypt:var-www --one-way

The --one-way flag only verifies that every local file exists on the remote — useful because crypt may add metadata that confuses bidirectional checks. Output 0 differences found means every file matches.

Testing the restore

An untested backup is not a backup. Do a partial restore to a temporary directory to confirm the entire chain (encrypt → upload → download → decrypt) is functional.

14

Restore a test directory:

mkdir -p /tmp/restore-test
rclone copy b2-crypt:var-www/example-site /tmp/restore-test --progress

After downloading, compare some files with diff or md5sum against the source at /var/www/example-site. If they match, the chain is intact. Delete /tmp/restore-test afterwards.

Next steps

Offsite backup solves the case of server loss, but it is only one layer — combine it with frequent local snapshots (LVM, Btrfs or ZFS) for fast restore from operational errors. Suggestions to evolve:

  • Configure Object Lock on S3 or write-only Application Key on B2 to mitigate ransomware
  • Add job monitoring via webhook (send cron status to a healthcheck endpoint)
  • Implement version rotation with --backup-dir pointing to date-based folders
  • Document the crypt password in a redundant vault (personal manager + company vault)

If you are putting this into production, a Hostini VPS comes with generous bandwidth and regular snapshots at the hypervisor level — a solid base to combine with the offsite layer described here.

Frequently asked questions

Is S3 or Backblaze B2 better for small backups?

For volumes under 1 TB with occasional restores, Backblaze B2 is much cheaper — storage costs about a quarter of S3 Standard and egress is free up to 3x the stored volume per month. S3 only makes sense if you already have the AWS ecosystem, need specific storage classes (Glacier Deep Archive) or native integration with other AWS services.

Does rclone crypt protect against ransomware on the source server?

Not directly. Crypt encrypts data in transit and at rest, but if the source server is compromised the attacker can run rclone delete or sync with an empty folder and destroy the backup. Mitigation: use Object Lock on S3 (COMPLIANCE mode) or B2 Application Keys restricted to write-only (no deleteFiles), plus bucket versioning.

Can I restore a specific file without downloading everything?

Yes. Rclone with crypt preserves the directory structure (with encrypted but navigable names). Use rclone ls remote-crypt:path/ to list and rclone copy remote-crypt:path/file.tar.gz /local/ to download only what you need. Crypt decrypts in stream — no need to download the entire backup.

Why is rclone sync more dangerous than copy?

Sync mirrors source to destination — files that disappear from the source are deleted from the destination. If the server disk fails and you run sync pointing to an empty folder, you lose everything on the remote. For safe incremental backup use copy (only adds/updates) or sync with --backup-dir pointing to a folder versioned by date.

How do I verify the backup is not corrupted without doing a full restore?

Use rclone check source: destination: to compare checksums (MD5/SHA1 depending on the backend) between local and remote files. For periodic end-to-end testing, mount the remote-crypt with rclone mount and open a few random files — if they decrypt and read without errors, the chain is intact.

Does rclone use a lot of CPU encrypting before uploading?

On modern servers with AES-NI the overhead is typically 5-15% during upload — the bottleneck is usually network bandwidth, not crypt. On 1 vCPU VPS with upload above 100 Mbit/s you may see saturation; in that case adjust --transfers 2 and --checkers 4 to reduce parallelism.

Topics:
Next steps Ryzen cloud with NVMe storage and always-on DDoS protection.Go live on a Hostini VPS →
Was this tutorial helpful?
Chat on WhatsApp