Backup on LUKS-encrypted external HDD

One of my strategies to prevent important (electronic-form) information from becoming too ephemeral…    #backups #rsync #luks #usb #drive    [Source code]

The goal of this text is to share with you a simple strategy to backup your important data to an encrypted external drive. (LUKS, which stands for Linux Unified Key Setup, is the disk encryption framework that we will use to encrypt the external drive.)

Scenario. More specifically, the goal is to create a backup of a set of locations—say, /home/<user>/folder1, /home/<user>/folder_2, etc.—where <user> is your username. The bash script I will provide also gives you the possibility of quickly restoring that external backup onto your computer—on which more later.

Prerequisites. An external hard drive, of course, and in addition, a machine with a Linux installation that isn’t ancient. As already hinted above, the bash shell is required, and furthermore, the cryptsetup package is also a requirement (this is what we’ll actually use to create and manage the LUKS encrypted volume). Finally, the user which will do the backups must have sudo privileges.

To avoid the perilous path of partioning, I shall assume that your entire external drive is to be formatted as a LUKS container. This, of course, needn’t be so: it is perfectly feasible to create multiple partions in said external drive, and use just one of them as a LUKS container for your backups. But I am afraid that you must look elsewhere for instructions on how to do that.1

Hereinafter, I shall assume that your external drive is /dev/sdb—modify as required for your own system. The first step, as I said, is to turn your whole drive into a LUKS container. But before that, there is an

IMPORTANT CAVEAT: if your drive has some previous data in it, setting it up as a LUKS container will render any such data inaccessible. But, just to make matters worse, it might not actually delete said pre-existing data. So, on the one hand, please backup any previous data that you want to keep. On the other hand, do not assume that the format process will wipe the drive of its previous contents.2

Setup. LUKS encryption can be done either using a passphrase, or a key file—here we are going for the latter. The key file it self can be anything really—an image, a PDF file, etc.—but here, we are going for a randomly generated hunk of bits (note that this has to be done as root):

# dd bs=512 count=4 if=/dev/random of=/path/to/keyfile iflag=fullblock

Needless to say, anyone who gets access to this file (keyfile), can trivially decrypt the LUKS container to be created—so be sure to keep it safe!! It is already owned by root, but just for good measure, I also make sure that only root can read it:3

# chmod 400 /path/to/keyfile

Now, to format the drive as a LUKS container, do:

# cryptsetup luksFormat /dev/sdb /path/to/keyfile

Now we have to open the encrypted volume we just created, and format that with an actual file system. Here I will use ext4, even despite its annoying lost+found folder.4

# cryptsetup --key-file=/path/to/file open /dev/sdb backupdev

This creates a new (“virtual”) device under /dev/mapper, more specifically /dev/mapper/backupdev. To dump an ext4 file system on it:

# mkfs.ext4 /dev/mapper/backupdev

And now mount it:

# mount /dev/mapper/backupdev /mnt

By default, the owner of your new partion will be root—which will mean that any copying of files therein must also be done as root. To avoid this, change its owner to you:5

# chown -R <user> /mnt

Moving on, you can choose to store the backup data directly into the root of your drive (i.e., its top folder), but I prefer to create a specific folder, and name it something like <USER>-BACKUP. Then, all of your backup data will be inside that folder. This leaves you free to, for example, use any remaining space on your drive to store other things. It is done like so:

# mkdir /mnt/<USER>-BACKUP

The setup of the external drive is done! All that is left is to unmount it, close the encrypted container—and then proceed to setup the bash script. (Note that below, umount is not a typo—the command really is named like that…)

# umount /mnt
# cryptsetup close backupdev

OK, onto the script! The code is fairly simple (see source code link above)—save it into a file with the .sh extension (below I will use backup_script.sh).6 There are variables to set up (they are at the top of the file):

Usage. Just run the script:7

$ sh /path/to/backup_script.sh

Without any arguments, as shown above, it creates/syncs a backup. With -r, it restores the data in the backup to its original location—but without overwriting files that, while present in the backup, have been modified (in the original location) after the backup was done. I.e., restoring a backup preserves files that are newer than the version that exists in the backup.8

In either case, adding the -y option does a --dry-run (i.e., a simulation) of the task that would have been done, if the -y had not been given. (So giving -y alone simulates a backup; giving -y -r—the order does not matter—simulates restoring a backup.)

March 8, 2022.


  1. The Arch Wiki might be a good place to start digging for information on partioning drives.↩︎

  2. This is actually a fairly complex issue, that I cannot hope to cover adequately here. An elucidating read on the some of the problems, might be cryptsetup’s own FAQ, specifically question 5.19.↩︎

  3. There is no need to ever write to this file, so writing permissions make no sense (to give the owner writing permissions, we would use 600 instead of 400; cf. man chmod). Furtermore, root permissions are needed to mount the encrypted volume, so making this file readable by root only, should cause no problem.↩︎

  4. The ext4 file system uses a lost+found folder, that it creates on the root of the device, to store information that might help to repair the file system, if it becomes corrupted, or whatever. Which is all nice and well, except that, for the life of me, I cannot understand why the designers did chose to store said information… in a hidden folder! Anyway, as this is a backup device, you can probably just delete the folder (rm -rf lost+found) and move on… (it will be recreated only when and if you run the fsck file system repair program on the drive). Or just use any other file system…↩︎

  5. If you subsequently mount the drive again, the contents will still be owned by you, i.e., this change is permanent. So this chown thing needs to be done only once.↩︎

  6. I don’t expect to modify this script very much (it at all), so I store it in a static fashion, rather than placing it on github, say.↩︎

  7. This assumes that the sh command points to the bash shell, as is now customary. If this not the case, either run the script replacing sh with /bin/bash, or make the script executable ($ chmod u+x /path/to/backup_script.sh) and then run it like this:

    $ ./path/to/backup_script.sh
    ↩︎
  8. This is useful in the following kind of scenarios: say you back up your entire home directory, and then one day—some time after you last updated your backup—you accidentally delete a couple of family vacation photos. No sweat: just run this script with -r, and presto: the deleted photos are restored, but any files on which you have worked—and thus modified—after the last backup are left undisturbed.↩︎