Privacy Tools Guide

Restic encrypts every backup with AES-256-CTR before it leaves your machine. Even if your backup storage is compromised, the attacker gets ciphertext. This guide covers installation, initializing repositories on local storage, S3-compatible buckets, and Backblaze B2, plus automating backups with systemd or cron.

Why Restic for Privacy-Focused Backups

Most backup tools treat encryption as an afterthought — an option you enable after the fact. Restic treats it as mandatory. There is no unencrypted restic repository; you cannot accidentally create one. Every pack file written to disk, every blob transferred over the network, is encrypted before it leaves your machine.

This matters because storage providers, hosting companies, and cloud services have access to the data you store with them. Zero-knowledge encryption means the provider can comply with a subpoena, get breached, or go rogue — and your data remains protected. Restic achieves this with AES-256-CTR for confidentiality, authenticated with HMAC-SHA256.

For comparison: rsync, Duplicati in default mode, and most cloud backup clients upload plaintext or use server-side encryption (which the server controls). Restic is client-side by design.

The deduplicated, content-addressed storage model means restic is also efficient: only changed 1MB chunks are re-uploaded across snapshots, making it competitive with proprietary services even for large datasets.

Install Restic

# Debian/Ubuntu
sudo apt install restic

# Fedora/RHEL
sudo dnf install restic

# macOS
brew install restic

# Or download a binary directly
curl -L https://github.com/restic/restic/releases/latest/download/restic_linux_amd64.bz2 | bunzip2 > restic
chmod +x restic
sudo mv restic /usr/local/bin/

Verify:

restic version

Concepts

Store your repository password in a password manager. Do not rely on memory alone.

Option 1: Local Repository

Initialize a repository on a local drive or external disk:

restic init --repo /mnt/backup/restic-repo

Restic asks for a password twice. Store this password securely.

Back up your home directory:

restic -r /mnt/backup/restic-repo backup ~/

The first backup transfers everything. Subsequent backups are incremental — only changed blocks are uploaded.

Option 2: S3-Compatible Storage (Wasabi, MinIO, etc.)

Set environment variables for credentials:

export AWS_ACCESS_KEY_ID=your-access-key
export AWS_SECRET_ACCESS_KEY=your-secret-key
export RESTIC_REPOSITORY=s3:https://s3.wasabisys.com/your-bucket-name
export RESTIC_PASSWORD=your-strong-password

Initialize the repository:

restic init

Run a backup:

restic backup ~/Documents ~/Projects

For AWS S3, use:

export RESTIC_REPOSITORY=s3:s3.amazonaws.com/your-bucket-name

Choosing a private S3-compatible host: AWS S3 is US-jurisdiction. Wasabi is also US-based. For stronger jurisdictional privacy, consider Hetzner Object Storage (Germany, GDPR-governed) or Exoscale (Switzerland). The encryption means the provider sees only ciphertext regardless, but jurisdiction matters if you want to minimize subpoena risk on metadata.

Option 3: Backblaze B2

Backblaze B2 has native restic support and is inexpensive (~$0.006/GB/month):

export B2_ACCOUNT_ID=your-account-id
export B2_ACCOUNT_KEY=your-application-key
export RESTIC_REPOSITORY=b2:your-bucket-name:/restic
export RESTIC_PASSWORD=your-strong-password

Initialize and back up:

restic init
restic backup ~/Documents

B2 is a solid default for most users. The pricing is predictable and the latency is low from North America and Europe. Backblaze’s privacy policy is less aggressive than AWS — they do not mine data from the objects stored. Since restic encrypts everything client-side, this is a minor point, but it is worth knowing.

Using a Password File

Typing the password every time is tedious for automation. Store it in a file with restricted permissions:

echo "your-strong-password" > ~/.restic-password
chmod 600 ~/.restic-password

Use it with every command:

restic -r /mnt/backup/restic-repo --password-file ~/.restic-password backup ~/Documents

Or set an environment variable:

export RESTIC_PASSWORD_FILE=~/.restic-password

For production systems, consider using a secrets manager (HashiCorp Vault, AWS Secrets Manager, or systemd credentials) rather than a plaintext file on disk. On servers where you control the environment, the file approach is acceptable if the filesystem permissions are correct and disk encryption (LUKS, FileVault) is enabled.

Exclude Files and Directories

Create an exclusions file:

nano ~/.restic-excludes
/home/user/.cache
/home/user/.local/share/Trash
/home/user/Downloads
*.tmp
*.log
node_modules/
.git/

Run backup with exclusions:

restic -r /mnt/backup/restic-repo backup ~/ --exclude-file=~/.restic-excludes

Good exclusion hygiene reduces backup size dramatically. node_modules/ alone can be gigabytes. .git/ histories are better managed with git bundles separately. Browser caches and ~/.cache directories are rarely worth backing up.

List and Browse Snapshots

List all snapshots:

restic -r /mnt/backup/restic-repo snapshots

Output:

ID        Time                 Host        Tags        Paths
-----------------------------------------------------------------------
3d8f2a1b  2026-03-21 02:00:00  myhost                  /home/user
c7e9f4d2  2026-03-20 02:00:00  myhost                  /home/user

Browse files inside a snapshot:

restic -r /mnt/backup/restic-repo ls 3d8f2a1b

Mount a snapshot as a filesystem:

mkdir /tmp/restic-mount
restic -r /mnt/backup/restic-repo mount /tmp/restic-mount
ls /tmp/restic-mount/snapshots/latest/

Mounting is useful for browsing old versions of files without committing to a full restore. It requires FUSE on Linux (fuse package) and macOS (macFUSE).

Restore Files

Restore a single file or directory from the latest snapshot:

restic -r /mnt/backup/restic-repo restore latest --target /tmp/restore --include /home/user/Documents/important.pdf

Restore an entire snapshot:

restic -r /mnt/backup/restic-repo restore latest --target /tmp/full-restore

Restore to the original path (overwrites existing files):

restic -r /mnt/backup/restic-repo restore latest --target /

Test your restore process at least quarterly. A backup you have never tested is a backup you cannot trust. A practical habit: once a month, restore a random file from a 30-day-old snapshot and verify its contents.

Snapshot Retention Policy

Keeping every snapshot forever wastes storage. Set a retention policy:

restic -r /mnt/backup/restic-repo forget \
  --keep-daily 7 \
  --keep-weekly 4 \
  --keep-monthly 6 \
  --prune

This keeps:

For compliance with data retention regulations (GDPR, HIPAA, SOC 2), adjust these numbers to match your requirements. GDPR’s right to erasure applies to backups too — if you delete a user’s data from production and need to honor an erasure request, your backup policy must account for this. Short retention windows (30–90 days) reduce the window where deleted data persists in backups.

Automate with systemd

Create a systemd service:

sudo nano /etc/systemd/system/restic-backup.service
[Unit]
Description=Restic Backup
After=network.target

[Service]
Type=oneshot
User=youruser
Environment=RESTIC_REPOSITORY=/mnt/backup/restic-repo
Environment=RESTIC_PASSWORD_FILE=/home/youruser/.restic-password
ExecStart=/usr/bin/restic backup /home/youruser --exclude-file=/home/youruser/.restic-excludes
ExecStartPost=/usr/bin/restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

Create a timer:

sudo nano /etc/systemd/system/restic-backup.timer
[Unit]
Description=Run Restic Backup Daily

[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=1h

[Install]
WantedBy=timers.target

Enable:

sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer

Check timer status:

systemctl list-timers restic-backup.timer

RandomizedDelaySec=1h spreads backup start times across an hour window, which prevents thundering-herd issues if you run the same timer on many machines.

Alerting on Backup Failures

Silent backup failures are worse than no backups at all — you discover the problem only when you need to restore. Add failure alerting to the service:

[Service]
...
OnFailure=notify-backup-failure@%n.service

Or use Healthchecks.io (a free, open-source compatible service):

# Add to ExecStart sequence — ping on success
ExecStartPost=/usr/bin/curl -fsS --retry 3 https://hc-ping.com/YOUR-UUID

If the ping does not arrive, Healthchecks.io sends you an email or webhook alert. This pattern works with restic running in any environment — local, VPS, or container.

Verify Repository Integrity

Run this regularly to detect data corruption:

restic -r /mnt/backup/restic-repo check

For a full data verification (reads all pack files):

restic -r /mnt/backup/restic-repo check --read-data

This is slow on large repos but confirms backup integrity end to end.

A lighter approach for large repositories: use --read-data-subset=5% to sample 5% of pack files on each run. Rotate the subset over weeks to get full coverage without a single long-running check.

Key Rotation

To change the repository password:

restic -r /mnt/backup/restic-repo key passwd

List all keys associated with the repo:

restic -r /mnt/backup/restic-repo key list

Remove an old key by its ID:

restic -r /mnt/backup/restic-repo key remove <key-id>

Rotate your repository password annually or whenever a credential is exposed. After rotation, the old password no longer decrypts any data — but the existing snapshots remain accessible with the new password.

Frequently Asked Questions

Can restic back up to multiple destinations simultaneously? Not natively. Run two separate backup commands pointing to two different repositories, or use a wrapper script. Backing up to two independent locations (local + cloud, or two different cloud providers) is strongly recommended for resilience.

What happens if I lose my password? The data is permanently unrecoverable. Restic’s encryption is intentional and complete — there is no backdoor, no recovery key, no support ticket you can file. Store the password in a password manager and keep an offline copy (printed or on an encrypted USB drive you store separately from the backup media).

Does restic support Windows? Yes. The binary works on Windows natively. Use Task Scheduler instead of systemd for automation. The password file approach and environment variables work the same way.

How does restic compare to Borg Backup? Both are excellent. Borg has faster deduplication and is slightly more efficient for large repos, but only supports Linux/macOS natively. Restic supports Windows and has broader storage backend support. For cross-platform environments, restic is the safer choice.

Built by theluckystrike — More at zovo.one