Skip to content

Configuration

Maximilian Stein edited this page Mar 16, 2018 · 5 revisions

Encrypted External HDD

Wanted

  • External HDD with luks encryption
  • Automatic mount when attaching drive
  • Run sysbackup automatically

Preparation

WARNING: This will DESTROY ALL YOUR DATA on the selected partition, so think before you type. In the following example, I will assume /dev/sdb1 as backup HDD.

  • Make sure /dev/sdb1 is not mounted.
  • Create luks device:
$ cryptsetup -v --verify-passphrase luksFormat /dev/sdb1
  • Open new luks device:
$ cryptsetup luksOpen /dev/sdb1 backup
  • Wipe existing data (to improve security; might take a long time):
$ dd if=/dev/zero of=/dev/mapper/backup
  • Create a filesystem: ** I recommend btrfs, see also next section about snapshots.
$ mkfs.btrfs /dev/mapper/backup
  • Mount:
$ mkdir -p /run/media/backup && mount /dev/mapper/backup /run/media/backup
  • Restrict access:
$ chmod go-rwx /run/media/backup
  • Umount and secure device:
$ umount /run/media/backup && cryptsetup luksClose backup

Enable Auto-Mount

  • Create a keyfile:
$ umask 077 && dd if=/dev/urandom of=/etc/backup.key bs=1024 count=4
  • Add key to luks volume:
$ cryptsetup luksAddKey /dev/sdb1 /etc/backup.key
  • Find UUID:
$ cryptsetup luksUUID /dev/sdb1
  • Create a mapper in /etc/crypttab:
backup UUID=d313d73b-72ab-40d4-b3f5-55b014b3a8a8 /etc/backup.key luks,noauto
  • Create systemd mount unit in /etc/systemd/system/run-media-backup.mount:
[Unit]
Conflicts=umount.target
Before=umount.target

[Mount]
What=/dev/mapper/backup
Where=/run/media/backup
Type=btrfs
Options=defaults,rw,noexec,noatime,nodiratime,compress=lzo
  • Test mount:
$ systemctl daemon-reload
$ systemctl start run-media-backup.mount
$ ls /run/media/backup
$ systemctl stop run-media-backup.mount

Automate Backup Start

  • Add dependencies to systemd unit: $ systemctl edit sysbackup.service
[Unit]
Requires=run-media-backup.mount
After=run-media-backup.mount
  • Find device IDs:
$ udevadm info -a /dev/sdb1 | less
  • Add udev rules in /etc/udev/rules.d/05-backup.rules
# run backup script when backup hdd is connected
# important: must be run only once, so match partition
ACTION=="add", SUBSYSTEM=="block", ATTR{partition}=="1", SUBSYSTEMS=="usb", ATTRS{idVendor}=="13fe", ATTRS{idProduct}=="4200", ATTRS{serial}=="01234567890ABCDEF", RUN+="/bin/systemctl --no-block start sysbackup.service"
ACTION=="remove", SUBSYSTEM=="block", ATTR{partition}=="1", SUBSYSTEMS=="usb", ATTRS{idVendor}=="13fe", ATTRS{idProduct}=="4200", ATTRS{serial}=="01234567890ABCDEF", RUN+="/bin/systemctl stop run-media-backup.mount", RUN+="/sbin/cryptsetup close backup"
  • Disable timed sysbackup:
systemctl disable --now sysbackup.timer
ln -snf /dev/null /etc/systemd/system/sysbackup.timer

Automatic Snapshots

Wanted

If you backup to a btrfs (sub)volume, you can automatically create a read-only snapshot after each run of sysbackup.

This gives you:

  • High efficiency as in incremental backups (only transfer what has changed)
  • Immediate access to snapshot data (no assembly of full and incremental backups needed)
  • Easy management of snapshots (btrfs subvolume delete ...)

How To

  • Edit systemd unit $ systemctl edit sysbackup.service and append:
[Service]
#User=root
ExecStartPre=+-/bin/btrfs subvolume create /run/media/backup/main
ExecStopPost=+/bin/mkdir -p /run/media/backup/main.snap
ExecStopPost=+/bin/sh -c "/bin/btrfs subvolume snapshot -r /run/media/backup/main /run/media/backup/main.snap/main.$(date --iso-8601=seconds)"

Snapshots without Btrfs

Wanted

For snapshots, I highly recommend using btrfs on the target side (source side doesn't matter) for ease of configuration and efficiency (see last section), but if you want incremental snapshots without using btrfs, rsync can help you.

How To

The config file /etc/sysbackup/backup.conf is simply sourced by sysbackup, so we can use some magic here. I haven't tested this setup, so tell me if I got something wrong ;).

  • Get latest snapshot:
existing_snapshots=($(ssh -i "$SSH_ID_FILE" find /path/to/target/dir -maxdepth 1 -type d))
latest_snapshot="${existing_snapshots[-1]}"
  • Tell rsync to hard-link to this directory:
[[ -n "$latest_snapshot" ]] && RSYNC_OPTIONS+=" --link-dest='$latest_snapshot'"
  • Set target path dynamically:
TARGET="/var/local/backup/backup.$(date --iso-8601=seconds)"