I like to keep all my backups encrypted. For local backups it’s easy with LUKS, but for remote backups this is problematic as LUKS only works on the local system and I’d have to trust the remote host which is unacceptable.
There are many backup tools available for remote backups but they are quite complicated and sometimes use dubious cryptography or implementations. I prefer simple backup solutions. The following setup uses SSHFS combined with LUKS for encrypted remote backups.
(An alternative to SSHFS is NBD (network block device) over VPN, e.g. with NBD and OpenVPN.)
All commands must be run as root, see below for possible issues
when running with
|This setup requires a stable internet connection. If the hosts is disconnected during the backup then everything will hang and you’ll have to kill the sshfs process and then unmount the backup directory manually.|
Mount the target directory from the remote host with SSHFS and create a sparse file for the backup (it can be resized later at any time).
sshfs backup-host:/path/to/backup/directory /mnt/backup-host truncate -s 50G /mnt/backup-host/backup-file.luks
Now encrypt it as usual with LUKS by using
cryptsetup, add any options you
like, e.g. key files.
cryptsetup luksFormat backup-file.luks
Then we need to create a filesystem on the encrypted partition (lazy initialization is disabled to prevent performance issues until the initialization has finished in the background; instead wait once during mkfs).
cryptsetup luksOpen /mnt/backup-host/backup-file.luks backup-partition mkfs.ext4 -m0 -E lazy_itable_init=0,lazy_journal_init=0 /dev/mapper/backup-partition
That concludes the setup.
Mount the remote backup (here using a key file).
sshfs backup-host:/path/to/backup/directory /mnt/backup-host cryptsetup luksOpen /mnt/backup-host/backup-file.luks backup-partition --key-file /root/luks/backup.key mount /dev/mapper/backup-partition /mnt/remote-backup
lsblk should now look sometimes like this.
... loop0 7:0 0 100G 0 loop └─backup-partition 254:4 0 100G 0 crypt /mnt/remote-backup
Now perform the backup as usual like any other “local” backup, for example
After everything is done unmount the file system:
umount /mnt/remote-backup cryptsetup luksClose backup-partition fusermount -u /mnt/backup-host
To increase the backup image use
truncate -s 200G /mnt/backup-host/backup-file.luks
Decrypt and mount the partition as described above. Then resize it.
One remaining issue with this setup is that the sparse file on the remote host
doesn’t shrink when files are deleted. SSHFS doesn’t support TRIM (limitation
of the SFTP protocol) but
nbd-server supports it.
The following setup explains how to use TRIM over LUKS and NBD.
apt-get install nbd-server nbd-client
nbd-server's configuration isn’t straight-forward (e.g. you can’t specify
trim option globally), so here’s a minimal configuration file:
[generic] // ... [default] // can be any name exportname=/path/to/your/file trim = true
Then run the NBD server on the remote host:
nbd-server -C /path/to/config
And connect from the local host:
nbd-client -N default -n $host $port /dev/nbd0
Then mount it as usual, however note the
--allow-discards option which is
required for TRIM:
cryptsetup luksOpen --allow-discards /dev/nbd0 backup-partition mount /dev/mapper/backup-partition /mnt/remote-backup
Now you can finally TRIM deleted space:
fstrim -v /mnt/remote-backup
You don’t have to use NBD all the time and can use SSHFS for regular backups and only run TRIM once in a while; all files deleted in the meantime will be TRIMed.
If you’re starting
sshfs as non-
root user then running
fail as FUSE prevents
root from entering the mounted file system (this is
designed to prevent attacks which confuse or hang
root processes). Either
sshfs as root or mount with
sshfs -o allow_root (this requires
/etc/fuse.conf which might have security
backLast updated 2019-03-09 11:32:09 CET