Summary: This guide shows how to back up a Linux server to Backblaze B2 using Restic with Rclone as the transport. You will set up encryption, implement a retention policy, automate runs with systemd timers, and test restores. The result is a fast, encrypted, and low-cost off-site backup that you control.
Why Restic + Rclone + Backblaze B2?
Restic is a modern, deduplicating backup tool with built-in encryption. Rclone provides wide storage compatibility and reliable transfers. Backblaze B2 offers affordable object storage with per-GB pricing. Together, they form a portable, verifiable, and cost-effective backup solution that works on any Linux distribution.
Prerequisites
- A Linux server (Ubuntu/Debian/RHEL/AlmaLinux, etc.) with sudo/root access
- Backblaze B2 account
- Basic terminal familiarity
Step 1: Create a B2 Bucket and Key
1) In Backblaze, create a bucket (e.g., mycompany-backups). Leave it private.
2) Create an Application Key restricted to that bucket. Copy the KeyID and Application Key now; you will not see the secret again.
Step 2: Install Restic and Rclone
sudo apt update && sudo apt install -y restic rclone
On RHEL/Fedora-based systems:sudo dnf install -y restic rclone
Step 3: Configure Rclone for B2
We will keep Rclone’s config out of your home directory for clarity.
sudo mkdir -p /etc/rclone
sudo chmod 750 /etc/rclone
sudo rclone config create b2 b2 account <KeyID> key <ApplicationKey> hard_delete true --config /etc/rclone/rclone.conf
Verify the config:
sudo rclone lsd b2: --config /etc/rclone/rclone.conf
Step 4: Initialize the Restic Repository (via Rclone)
Create a password file and initialize the repository path inside the bucket.
sudo mkdir -p /etc/restic
echo "choose-a-strong-long-passphrase" | sudo tee /etc/restic/password > /dev/null
sudo chmod 600 /etc/restic/password
Initialize:
sudo env RCLONE_CONFIG=/etc/rclone/rclone.conf restic -r rclone:b2:mycompany-backups/restic --password-file /etc/restic/password init
Step 5: Exclusions and Environment File
Define what not to back up (caches, runtime, VM disks, etc.).
sudo tee /etc/restic/excludes.txt > /dev/null <<'EOF'
/proc/**
/sys/**
/dev/**
/run/**
/tmp/**
/var/tmp/**
/var/cache/**
*.iso
*.img
*.qcow2
EOF
Create an environment file to avoid repeating flags:
sudo tee /etc/restic/restic.env > /dev/null <<'EOF'
RESTIC_REPOSITORY=rclone:b2:mycompany-backups/restic
RESTIC_PASSWORD_FILE=/etc/restic/password
RCLONE_CONFIG=/etc/rclone/rclone.conf
RESTIC_CACHE_DIR=/var/cache/restic
EOF
sudo mkdir -p /var/cache/restic && sudo chown root:root /var/cache/restic && sudo chmod 700 /var/cache/restic
Step 6: Create a Backup Script
This script performs a backup, applies retention, and verifies the repository.
sudo tee /usr/local/bin/restic-backup.sh > /dev/null <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
# Sources to back up (adjust to your server)
SOURCES=(/etc /home /var/www)
# Nice/ionice to reduce system impact
nice -n 10 ionice -c2 -n7 \
env $(grep -v '^\s*#' /etc/restic/restic.env | xargs) \\
restic backup "${SOURCES[@]}" --exclude-file /etc/restic/excludes.txt --tag scheduled --one-file-system
# Retention policy: keep last 7 daily, 4 weekly, 6 monthly
env $(grep -v '^\s*#' /etc/restic/restic.env | xargs) \\
restic forget --prune --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --tag scheduled
# Optional consistency check (weekly via timer, or keep here for every run)
env $(grep -v '^\s*#' /etc/restic/restic.env | xargs) restic check --read-data-subset=1/20 || true
EOF
sudo chmod 750 /usr/local/bin/restic-backup.sh
Step 7: systemd Service and Timer
Create a systemd unit to run the script, and a timer to schedule it daily.
sudo tee /etc/systemd/system/restic-backup.service > /dev/null <<'EOF'
[Unit]
Description=Restic backup to Backblaze B2 (via rclone)
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
EnvironmentFile=/etc/restic/restic.env
ExecStart=/usr/local/bin/restic-backup.sh
Nice=10
IOSchedulingClass=best-effort
IOSchedulingPriority=7
PrivateTmp=yes
NoNewPrivileges=yes
ProtectSystem=full
ProtectHome=yes
ProtectKernelLogs=yes
ProtectKernelModules=yes
ProtectKernelTunables=yes
LockPersonality=yes
MemoryDenyWriteExecute=yes
[Install]
WantedBy=multi-user.target
EOF
sudo tee /etc/systemd/system/restic-backup.timer > /dev/null <<'EOF'
[Unit]
Description=Daily Restic backup timer
[Timer]
OnCalendar=03:15
RandomizedDelaySec=20m
Persistent=true
[Install]
WantedBy=timers.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer
Step 8: First Run and Verification
Trigger a manual run and watch the output:
sudo systemctl start restic-backup.service
sudo journalctl -u restic-backup.service -n 200 -f
List snapshots to confirm:
sudo env $(grep -v '^\s*#' /etc/restic/restic.env | xargs) restic snapshots
Step 9: Tune Retention and Costs
Adjust the restic forget policy to meet recovery objectives and budget. More aggressive pruning reduces storage but limits historical versions. Backblaze B2 costs depend on stored GB, transaction counts, and egress; deduplication in Restic helps keep usage low.
Step 10: Test a Restore
Never trust backups you have not restored. Create a temporary restore folder and recover a small file.
sudo mkdir -p /tmp/restore-test
sudo env $(grep -v '^\s*#' /etc/restic/restic.env | xargs) restic restore latest --target /tmp/restore-test --include /etc/hostname
ls -l /tmp/restore-test/etc/hostname
Security Best Practices
- Use a long, unique Restic password stored in a root-only file.
- Restrict the Backblaze Application Key to one bucket with minimal permissions.
- Enable MFA on your Backblaze account.
- Keep /etc/rclone/rclone.conf and /etc/restic/password mode 600 and owned by root.
- Consider server-side encryption on B2 as a secondary layer if required by policy, although Restic already encrypts data client-side.
Performance Tips
- Parallel uploads: Restic auto-tunes, but you can increase concurrency on bigger servers via RESTIC_OPTIONS like --jobs 4 for backups or use Rclone env vars (RCLONE_B2_UPLOAD_CONCURRENCY).
- Bandwidth limits: Add --limit-upload 4MiB to Restic, or --bwlimit via Rclone if needed.
- Exclude large/ephemeral paths to reduce churn.
Troubleshooting
Fatal: wrong password or no key found: The password in /etc/restic/password does not match the repository. Fix the password file or re-init a new repo.
Repository locked: A previous run crashed. Remove stale locks only when you are certain no job is running:sudo env $(grep -v '^\s*#' /etc/restic/restic.env | xargs) restic unlock
Slow uploads or timeouts: Check outbound bandwidth, raise concurrency, and ensure your firewall allows long-lived HTTPS connections. Try adding a randomized delay (already in the timer) to avoid contention on shared links.
What You Achieved
You now have an automated, encrypted, off-site backup pipeline for Linux using Restic, Rclone, and Backblaze B2. Snapshots are deduplicated, retention is enforced, and restores are provable. Regularly verify snapshots, monitor storage usage, and adjust policies as your data grows.
Comments
Post a Comment