HOWTO - Encrypted Backups in (Debian) Linux

If you’ve ever owned a computer, you can probably imagine a few scenarios where having proper backups is helpful and to some extent, necessary. However, in many cases setting up an appropriate system for backing up your files can be either tedious or brings some air of uncertainty. Recently, I set up my own system for performing backups in (Debian) Linux, and I figured I’d write down my process for my own sake, but likewise to share with others who may not be so sure why or what they may want to backup.

NOTE: While this guide was primarily developed for Debian 7.3 (Wheezy), it should apply to just about any Debian-based distro (such as Ubuntu, Mint) and Linux in general. Some tweaks may need to be made depending on the filesystem type you want to use (more on that later) but in general it should serve as long as your distro provides the cryptsetup utility.

Preparations

Before we start getting to the nitty-gritty details, you’ll need to prepare a few things in order for this guide to be of any use to you:

  1. Obviously, a hard drive or separate partition with which you wish to backup your files. Ideally is should be big enough to fit both / and /home, so take this into consideration. Also note that this process will ENTIRELY WIPE THE DRIVE OR PARTITION. Consider that your warning, you may need to make temporary backups while we set up this one.
  2. You’ll need both cryptsetup and mkfs installed. These are typically installed by default in most distributions, so most likely you’ll be fine.
  3. You should be comfortable entering commands into the command line / terminal. I hate to add this one to the list, but this guide is pretty CLI-focused, so it needs to be said.

Step 1: Plug the Drive in and Unmount it

I’m writing this guide under the assumption that you intend to backup your files to an external drive or partition. However, it works almost the exact same way with an internal partition as well. The major difference is knowing which device you need to unmount in order to prepare this process. The easiest way to check all of your devicies / partitions is to use:

$ grep sd /proc/partitions

once your drive or parition is plugged in and mounted. From there, find the devices (sda, sdb, sdc, etc…) that corresponds to the drive or partition you want to use. For the remainder of this tutorial, I’m going to refer to /dev/sdd1 as the device we’ll be encrypting and formatting. Unmount the device with the command:

# umount /dev/sdd1

Step 2: Setting up LUKS Container for Encrypted Drive

Alright, provided the previous command worked (notice that it needs to be executed as root, as marked by the # instead of the $), we can move on to actually encrypting the drive. For this, we’re going to use the cryptsetup utility. Now enter:

# cryptsetup -c aes-xts-essiv:sha256 -h sha512 -s 512 -i 15000 -y luksFormat /dev/sdd1

What this does is create a new LUKS container over the entire block device. The specifics about the algorithm aren’t totally necessary, but effectively you want to use sha512 for your volume key hash, since the hash of our chosen password will be stored in the LUKS volume header. Basically, -h sha512 specifies we’ll use SHA512 to hash our volume key, -c aes-xts-essiv:sha256 specifies the cipher with which we’ll encrypt our drive (we’re using AES with SHA256). The option -y tells cryptsetup to verify the password you set on the drive, so you can confirm you typed it in properly, and luksFormat just tells cryptsetup that we’re formatting a new LUKS container onto /dev/sdd1. If you want more details on any of these options, then man cryptsetup will be your friend.

Upon running the above line, you should be prompted for a password / passphrase. This will be the password that you’ll need to get access to your drive. Make sure it’s fairly strong, and that you can remember it or store it somewhere safe so that you do not lose it. Remember: if you lose this password, your drive will be rendered useless, so take care. Assuming you’ve picked a good password, proceed to Step 3.

Step 3: Format the Filesystem Within your LUKS Container

This part is pretty straightforward. We first have to open the LUKS container (unencrypt our drive) and then format the filesystem on it to one that we want. To do this we’re going to run the following commands:

# cryptsetup luksOpen /dev/sdd1 BACKUP
# mkfs.ext4 -qL BACKUP /dev/mapper/BACKUP
# cryptsetup luksClose BACKUP
# sync

The first command unencrypts your device and then assigns it to /dev/mapper/BACKUP (you can change BACKUP here to anything, by default you could also leave it out and Debian will auto-choose a name based on the UUID for you). The second command formats the filesystem to ext4, labels your unencrypted volume as “BACKUP” (so that later we can mount it on /media/BACKUP) and then closes (re-encrypts) the LUKS container. Afterwards, the filesystem buffers are flushed with the sync command.

And that’s basically it for setting up our encrypted drive! From here, if you open Thunar or whatever other file manager you have, you should see something along the lines of “ 1.0 TB Encrypted". Click on this, and it will ask you for your passphrase. Upon entering it, you should see the empty drive mount onto `/media/BACKUP`, which you can now use.

Step 4: Make Changes to /etc/fstab for Mounting

This step is somewhat optional, as you may have preferences regarding when you want to unencrypt / mount your drive. Personally, I choose to unencrypt the drive after login, so I don’t have to enter several passwords for each encrypted block device during the boot sequence, but you may wish to enter your password for the drive every time the computer boots (therefore unencrypting the drive to any user who may login [!!!], which is a poor idea on multi-user systems).

To do this, we’re going to make some changes to the /etc/fstab file. This file is basically a table that defines how we’re going to mount filesystems in Linux by default. If you’ve set up your own partitions when installing Debian (or whatever other OS), you’ve likely encountered this before. First, we need to figure out what the UUID of our unencrypted LUKS container is. To do this, we need to (as should be obvious) unencrypt our drive. You can do so using the cryptsetup luksOpen command similar to above, or just by clicking on the drive and entering your password in Thunar / Nautilus / your file manager. From there, we want to get the block ID of the device, so we call:

# blkid /dev/mapper/BACKUP

NOTE: If you didn’t specify a name for the LUKS container to be mapped to (such as “BACKUP” that we used in the previous step using luksOpen), then the device will likely be mounted under something along the lines of /dev/mapper/udisks-luks-uuid-...-uid1000 or something similar. It should be simple enough to figure out, as you’ll be able to spot the new device that shows up when you unencrypt the LUKS container.

The output should have some line that looks similar to UUID="...". Copy the UUID sans quotes and then open /etc/fstab as root.

# vim /etc/fstab

From here, add the following lines to the bottom of the file:

## BACKUP DRIVE
UUID=<paste-the-uuid-here>    /media/BACKUP    ext4    defaults,ro,user,noauto,nofail    0    0

Alright, this allows us to mount our backup drive automatically through the file manager as a user once we unencrypt it. Because we also specified noauto and nofail, we don’t have to worry about the system bothering us for a password when we boot up. It should also be noted that we specified to mount this drive as read-only (ro). This means we can’t actually write to the disk yet once it’s mounted. This is a good thing, because we don’t want our backups to get touched or deleted willy-nilly. In the next step, I’ll show you how to get around this for when we do want to write to the drive (i.e. when we actually want to backup files), but for now, just accept it the way it is.

As an aside, it may also be a good idea to zero out the drive at this point, so that any previous data can’t be recovered, as it still needs to be overwritten before it gets encrypted. I used the following command to zero the drive:

# dd if=/dev/zero of=/media/BACKUP/zero.dd

This will write zeros to the entire drive. If you want to be more secure, you can exchange the /dev/zero above to /dev/urandom, but bear in mind that process will likely take days, and even zeroing the drive the way it is now will take a few hours at best.

Step 5: Backing up Files

Awesome, so we finally finished setting everything up, we’re ready to backup all of our files. You may decide to do things differently than myself, and if you intend to use this encrypted drive for something other than a standard backup, you can probably stop reading here. However, I figured I’d show off how I now go about backing up all of my files. I back up all my files using the following bash script:

#!/bin/bash
# Basic script to rsync root and home
echo 'Remounting BACKUP as read-write'
mount -o remount,rw /media/BACKUP/
echo 'Performing rsync backup of / and /home'
rsync -avx --delete /       /media/BACKUP/
rsync -avx --delete /home/  /media/BACKUP/home
echo 'Remounting BACKUP as read-only'
mount -o remount,ro /media/BACKUP

Save this into a file called backup-script.sh and run it as root. It will remount the drive so that it has read-write permissions, and then rsync everything (in archive mode, so all permissions, modes, and ownerships are preserved), and then it remounts the drive as read-only, so you can’t accidentaly delete something. An interesting note about rsync as well, is that it copies things incrementally, so while the first time you run this script it will take a long time (depending on the size of /home and /), it will eventually only modify the files that changed every time you backup. In this way, I keep an ongoing daily backup of modifications to my file system (only when I know I haven’t broken anything).

NOTE: I have /home and / on separate partitions, which means I have to use two commands to backup both of them. In this case, this is because I called rsync with the -x flag. This is necesary, because the -x flag prohibits rsync from crossing filesystems. If you don’t have this flag enabled (as I do with -avx), then rsync will also backup copies of whatever is mounted in /media as well, which will eventually lead you to backing up your files in circles. If you want to back up other mount points similar to how I did above, experiment with rsync first and read the man page on how folder copying works, and then uniquely specify which folders you want synced and add them to the script above.

As a final task, I also keep monthly backups on a separate, likewise encrypted drive. I keep this drive mounted read only as well, and run the following bash script (monthly-archive.sh):

#!/bin/bash
# Takes the entirety of my backups and zips them
echo 'Mounting MONTHLY read-write.'
mount -o remount,rw /media/MONTHLY
tar c /media/BACKUP/ | xz --verbose --stdout -9e > /media/MONTHLY/backup_$(date +%F).txz
echo 'Mounting MONTHLY read-only'
mount -o remount,ro /media/MONTHLY

This script usually takes a LOOOOOOOOONG time to run. So be prepared to sit back while it does. If you want it to run a little faster, remove the -9e flag in the xz command above. This will get you a bit less compression, but it will run a little bit faster.

Conclusion

In this article I showed one method of performing backups on an encrypted LUKS container in Debian Linux. Hopefully this helps somebody in the horrible scenario that they accidentally delete /bin or /home or something. As a final note, I would like to thank Aaron on irc.rizon.net for assisting me with everything regarding block encryption with cryptsetup. I would also like to make mention that while I did show one method of encrypted backups, this is only the system I am currently using, and there are probably a few others out there that work just as well for their intended purpose. If this method doesn’t meet your needs, it’s always possible to find other ways to do what you want to accomplish.

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.