The proper way to backup

I want do regular, automated backups to a raspberry pi in my homenetwork. It is sufficient to do backups, when at home.

Every singe guide I read on ‘how to do automated backups’ tells me to put a passwordless ssh-key on my pi. I don’t want to do this, because anyone with access to my pc, would have access to my backups which completely annihilates one purpose of backups.

My current solution is a password protected ssh-key and a rsync script. It took some time to make it work, but now I am prompted for the password as soon as I login at my home network, followed by a backup.

Now I want to use restic since I need some type of versioned backup. Also I want to backup other devices as well. The restic guide, again tells me to use a passwordless ssh-key.

Now, I had the idea to do it the other way around. I.e. my (offline) pi can ssh into my laptop without password (but resticted to resric use). I could run some systemd.timer with a script that checks if my laptop is reachable and start a backup, if this is the case.

However, this seems quite hacky and I am convinced that this is some common szenario. But I can’t find any guides for it.

Can you point me into a general direction? Even some terminology would help, so I can find more information on what I want to do!

Asked By: grbll

||

The idea is to have a passwordless key that’s restricted to specific operations.

For example, with Restic (which apparently stores backups via SFTP) or with plain rsync, you could have the backup server maintain Btrfs/ZFS snapshots of the backup disk, with the SSH key accessing an account without root privileges (and therefore with no way to delete snapshots). Should someone use the key to remotely delete the Restic repository, it would take a few seconds to restore it from the last snapshot and then you’d proceed with laptop restore as normal.

With programs like Borg Backup, which have their own "server" that they talk to over SSH, you can restrict the key to a specific forced remote command only, so that all it can do is start the Borg server and not SFTP nor a shell. Borg has an "append-only" option that you can use in the forced command, making the key only usable for uploading new backups but not for deleting old ones.

Arguably, however, if someone 1) has access to your laptop’s unencrypted files and 2) is connected to your home network, then you most likely have bigger problems…

Answered By: u1686_grawity

Combining restic with rclone allows you to set up a service on a backup server using rclone that serves a restic REST API that restic can connect to from the machine(s) that you want to back up. Using the REST API is usually much faster than using restic over SFTP.

This is well documented by rclone serve restic --help, including how to use SSL and how to do htpasswd authentication. You should read that documentation carefully. If your backup server is public-facing (it shouldn’t be), or if you do this for some non-personal setup, you will need to secure it with some way of authenticating individual users.

The minimum you need to set it up to be usable from outside of localhost on a local network is the following on the host that serves as the backup server:

rclone serve restic --addr :8080 /var/backup/restic

Here, /var/backup/restic is the path under which you want to store your restic repositories (the user that runs the above command needs to have write permissions there, so you might want to create a dedicated service user for that). The --addr :8080 means "bind to port 8080 on all available interfaces" (by default, rclone binds only to localhost:8080).

You may then connect to this with the following (this initializes a restic repository and creates the first snapshot of my home directory):

restic -r rest:http://backupsrv:8080/testrepo init
restic -r rest:http://backupsrv:8080/testrepo backup "$HOME"

This assumes that you want to create and use a restic repository called testrepo and that your backup server is accessible as backupsrv. You should replace that hostname with the correct name or IP number.

This will prompt you interactively for the repository password, but you can obviously pass that in the RESTIC_PASSWORD environment variable as usual (just like you can pass the restic repository in RESTIC_REPOSITORY instead of using -r ...).


On my personal Synology NAS, I run the following Docker container (this is a docker-compose.yml file):

version: '3'
services:
  rclone:
    image: rclone/rclone:latest
    container_name: rclone
    hostname: diskstation.local
    ports:
      - 18080:8080
    restart: unless-stopped
    command: ["serve","restic","/backup"]
    environment:
      - RCLONE_ADDR=0.0.0.0:8080
      - RCLONE_STATS=1h
      - RCLONE_VERBOSE=1

    volumes:
      - /volume1/Restic/backup:/backup

This serves the restic REST API on port 18080 on the NAS and lets me store my backups in /volume1/Restic/backup (by means of a bind mount into the container). Note that the security in the rclone setup is minimal as this is a personal NAS in a walled-off LAN (behind both a firewall and a carrier-grade NAT).

Answered By: Kusalananda

Every singe guide I read on ‘how to do automated backups’ tells me to put a passwordless ssh-key on my pi. I don’t want to do this, because anyone with access to my pc, would have access to my backups which completely annihilates one purpose of backups.

The first statement is correct but let me try to explain what I understand by this. (As well as handling principle of least privilege.)

  1. You have a PC that you want to backup
  2. You want to protect your backups so that someone/something with unexpected access to your PC cannot break your backups

The solution here is to drive the backups from the backups server (your Pi) rather than from your PC. If you’re going to use rsync with either ssh (to a Linux/Mac client) or with rsyncd (a Windows client) you set the scheme up so that the Pi can access the PC. (The PC need have no passwordless access to the Pi.)

A typical approach might be to use cron on the Pi to try and backup the PC on a frequent basis (four-hourly, say), but once it has succeeded not to retry until the follow day. This script is untested but should give you the bones for a solution. It’s important to note that the timeout 4h should be sufficient for a complete backup:

basedir=/data/backup_dir                      # Backups target directory
my_pc=192.168.130.33                          # Your PC name or IP address

today=$(date +'%Y-%m-%d')                     # Today
stamp=$(cat "$basedir/.stamp" 2>/dev/null)    # Date of last backup

if [ "$today" = "$stamp" ]
then
    # Last backup was today
    exit 0
fi

if ! ping -q -c1 "$my_pc"
then
    # PC not responding to ping
    exit 1
fi

# Backup your PC
if timeout 4h rsync -a "$my_pc":/…/ "$basedir/$today"
then
    # Success
    echo "$today" >"$basedir/.stamp"
    exit 0
fi
Answered By: Chris Davies
Categories: Answers Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.