Encrypt backups at an untrusted remote location
In a previous blog post I argued that a good backup solution includes backups at different geographical locations to compensate for local disasters. If you don’t fully trust the location, the only solution is to keep an encrypted backup.
In this tutorial we’re going to set up an encrypted, mountable backup image which allows us to use regular file system operations like
First, on any kind of permanent medium available, create a large enough file which will hold the encrypted file system. You can later grow the file system (with
resize2fs) if needed. We will use
dd to create this file and fill this file with zeros. This may take a couple of minutes, depending on the write speed of the hard drive. Here, we create a 500GB file:
dd if=/dev/zero of=/path/to/backup.img bs=100M count=5000
A quicker method to do the same (file will not be filled with zeroes) is:
fallocate -l 500G /path/to/backup.img
Now we will use LUKS to set up a virtual mapping device node for us:
apt-get install cryptsetup
First, we generate a key/secret which will be used to generate the longer symmetric encryption key which in turn protects the actual data. We tap into the entropy pool of the Linux kernel and convert 32 bytes of random data into base64 format (this may take a long time; consider installing haveged as an additional entropy source):
dd if=/dev/random bs=1 count=32 | base64
Store the Base64-encoded key in a secure location and create backups! If this key/secret is lost, you will lose the backup.
Next, we will write the LUKS header into the backup image:
echo "Base64-encoded key" | base64 --decode | cryptsetup luksFormat --key-file=- /path/to/backup.img
Next, we “open” the encrypted drive with the label “backup_crypt”:
echo "Base64-encoded key" | base64 --decode | cryptsetup luksOpen --key-file=- /path/to/backup.img backup_crypt
This will create a device node
/dev/mapper/backup_crypt which can be mounted like any other hard drive. Next, create an Ext4 file system on this raw device (“formatting”):
Now, the formatted device can be mounted like any other file system:
mkdir -p /mnt/backupspace_loop mount -o loop /dev/mapper/backup_crypt /mnt/backupspace_loop
You can inspect the mount status by typing
mount. If data is written to this mount point, it will be transparently encrypted to the underlying physical device.
If you are done writing data to it, you can unmount it as follows:
umount /mnt/backupspace_loop cryptsetup luksClose /dev/mapper/backup_crypt
To re-mount it:
echo "Base64-encoded key" | base64 --decode | cryptsetup luksOpen --key-file=- /path/to/backup.img backup_crypt mount -o loop /dev/mapper/backup_crypt /mnt/backupspace_loop
Note that we always specify the Base64-encoded key on the command line and pipe it into
cryptsetup. This is better than creating a file somewhere on the disk. Now, if the machine is powered off, the decrypted mount point is lost and only the encrypted image remains.