jmtd → log → Frictionless external backups with systemd
Here's a description of how my monthly external backups are managed at a technical level. I didn't realise I hadn't written this all down anywhere yet.
What
I plug in one of two (prepared) external hard drives into my headless NAS. The NAS contains my primary data backup. A job automatically decrypts the encrypted filesystem on the drive, mounts it and synchronises the copy of my backup data on the drive from that on the NAS. Whilst this is going on, the blinkstick LED on the NAS switches to a colour to signal "in progress". When it's done, the light changes to green to signal "done" and I can remove it. If something goes wrong, it turns red and I get mail.
Why
I want a third-strand, off-site backup of my and my family's data in case of a disaster in our house. For it to be useful it has to be regular, so I needed to remove as much of the friction of performing the backup as possible.
I use two drives alternately so that I don't have all my eggs in one basket in the window when I bring one of them home and perform the backup.
How
As much as possible I lean on systemd
and its ability to trigger actions
based on events.
External drive is plugged in.
systemd
instantiates a corresponding device unit, nameddev-disk-by\x2duuid-aaaaaaaa\x2daaaa\x2daaaa\x2daaaa\x2daaaaaaaaaaaa.device
, whereaaaa…
is the UUID of a partition on the deviceThe backup job is a
systemd
service which has aWantedBy
relationship on the device unit, so when the device appears,systemd
starts the backup service.The backup service has
Requires
andAfter
relationships onsystemd-cryptsetup@extbackup.service
, a service created bysystemd
's cryptsetup generator on start-up (but slightly customised, see below). The encrypted device is therefore unlocked.The backup service defines multiple start and stop commands with
ExecStart
andExecStop
. These are used to:- set the blinkstick to the working colour (blue-ish)
- mount the now-decrypted filesystem
- get a lock on the backup repository (so nothing else writes to it) and synchronise the files
- unmount the filesystem
- set the blinkstick to the success colour (green)
Finally, the
systemd-cryptsetup@extbackup.service
unit realises it is not required any more. It has been customised withStopWhenUnneeded=true
1, so the encrypted filesystem is closed, ready for the drive to be removed.I notice the LED colour is green, remove the drive, and take it to its off-site home.
If anything goes wrong, all my custom systemd
units have,
as a matter of course,
OnFailure=status-email-user@%n.service blinkstick-fail.service
Preparing a new backup disk
This is mostly just a standard dm-crypt/cryptsetup/LUKS encrypted device, on top of a standard partition on the underlying disk, with a normal filesystem sitting on top: Basically, the most common way to encrypt a drive in Linux. See places like the cryptsetup docs for how to set something like that up. The key things here are
- set up a decryption key file as well as (or instead of) a pass- phrase and store that somewhere on the filesystem of the NAS
- back up the LUKS header, as the cryptsetup documentation stresses you should
- make a note of the underlying partition UUID: it's needed for
the
WantedBy
line in the backup service file. (look in/dev/disk/by-uuid
before and after inserting it and see what was added) - label the filesystem on top of the encrypted device for convenience
- set up a
/etc/crypttab
line with all the info needed to decrypt - set up a
/etc/fstab
line with all the info needed to mount (yes, really; see "Issues" below)
The backup service
Here's the backup service unit definition in its entirety:
[Unit]
OnFailure=status-email-user@%n.service blinkstick-fail.service
Requires=systemd-cryptsetup@extbackup.service backup.mount
After=systemd-cryptsetup@extbackup.service backup.mount
[Service]
Type=oneshot
ExecStart=/usr/local/bin/blinkstick --index 1 --limit 10 --set-color 33c280
ExecStart=/bin/mount /extbackup
ExecStart=/home/jon/bin/phobos-backup-monthly
ExecStop=/bin/umount /extbackup
ExecStop=/usr/local/bin/blinkstick --index 1 --limit 10 --set-color green
[Install]
WantedBy=dev-disk-by\x2duuid-aaaaaaaa\x2daaaa\x2daaaa\x2daaaa\x2daaaaaaaaaaaa.device
The dashes in the UUID in WantedBy=
need to be encoded as \x2d
and then
the slashes from the path bit as dashes. Using dashes to encode
slashes is possibly the single most frustrating systemd
design decision.
Issues
Sadly (as detailed in Blinkenlights, part 2) there are
2 some frustrating limitations with trying to handle the mount
(and unmount) of the filesystem in systemd
-land, so instead, it's done
using the traditional mount
, umount
and fstab
.
If you can point out any improvements to this approach, please let me know!
-
I customized mine a while ago by copying the generated service file to a
static file, but nowadays I think you could do
systemd edit systemd-cryptsetup@extbackup.service
to add theStopWhenUnneeded
to an override file and not need the rest.↩ - or at least were. It's been a while since I revisited this part.↩
Comments