sshfs backup-host:/path/to/backup/directory /mnt/backup-host
truncate -s 50G /mnt/backup-host/backup-file.luks
First written 2016-03-03; Last updated 2021-07-25
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.
Note
|
This setup does not prevent the local computer from corrupting stored backups (e.g. when the local computer is compromised). See Append-only backups with restic and rclone to protect the backups; but with higher complexity and additional software on the remote. |
(An alternative to SSHFS is NBD (network block device) over VPN, e.g. with NBD and Wireguard or OpenVPN.)
All commands must be run as root, see below for possible issues
when running with sudo
.
Note
|
This setup requires a stable internet connection. If the host 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
with rsync
.
After everything is done unmount the file system:
umount /mnt/remote-backup
cryptsetup close backup-partition
fusermount -u /mnt/backup-host
To increase the backup image use truncate
and resize2fs
.
truncate -s 200G /mnt/backup-host/backup-file.luks
Decrypt and mount the partition as described above. Then resize it.
resize2fs /dev/mapper/backup-partition
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.
Install NBD:
apt-get install nbd-server nbd-client
nbd-server
's configuration isn’t straight-forward (e.g. you can’t specify
the trim
option globally), so here’s a minimal configuration file:
[generic]
// ...
[default] // can be any name
exportname = /path/to/your/file
trim = true
Make sure to restrict access to NBD via firewall to prevent others from writing the (encrypted) file.
Then run the NBD server on the remote host (-d
runs it in the foreground):
nbd-server -d -C /path/to/config
And connect from the local host (default port is 10809):
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 cryptsetup
will
fail as FUSE prevents root
from entering the mounted file system (this is
designed to prevent attacks which confuse or hang root
processes). Either
run sshfs
as root or mount with sshfs -o allow_root
(this requires
enabling user_allow_other
in /etc/fuse.conf
which might have security
implications).
Last updated 2021-07-25