Linux: Encrypt external HDD

#PrivacyByDefault #MassEncryption

There are two kinds of users: The ones, who encrypt their stuff and the ones, who never had lost something or never got something stolen.
Imagine your Laptop being stolen on the train. Not only, you probably lost all of your data (Backups!), but also there is now a stranger that has access to potentially very private data - Pictures of your last birthday, company records you need to keep secret or the new piece of code that is awesome and the capital of your startup you just wanted to create.
Plenty of reasons for investing a little bit of time in your digital self-defence, and a sane full-disk encryption is a major part of it.

I personally have two different approaches: VeraCrypt (successor of TrueCrypt after they surprisingly closed, leaving lots of speculations about their non-commitment to build in a secret backdoor for a large state agency, but that is based on pure speculation and is on the list of conspiracy theorems that probably turn out to be at least somehow concise enough to be taken seriously.) seems to be sane enough to be used or LUKS. In this article I'm gonna cover LUKS, as I consider this the canonical way for every mature Linux environment.


Assuming the HDD is /dev/sdb and you want to call it Cryptodisk

  1. Reformat the external HDD. Create a single partition with any filesystem (we will overwrite this in the next step)
  2. Make sure all filesystems for that disk are unmounted.
  3. cryptsetup -y -v luksFormat /dev/sdb1
    1. Enter passphrase.
    2. Write the passphrase on a sheet of paper and store it on a safe place.
    3. REALLY do it. You probably will forget the passphrase and then you can cry your data goodbye
  4. Open the crypdevice: cryptsetup luksOpen /dev/sdb1 Cryptodisk
  5. mkfs.xfs /dev/sdb1
  6. cryptsetup luksClose Cryptodisk
  7. Plug the disk out and re-plug it in. In caja/nemo it should appear as encrypted device.
    If you click on it, it asks for the passphrase and it will be mounted.
    Alternatively, user cryptsetup cryptsetup luksOpen /dev/sdb1 Cryptodisk
    mount /dev/mapper/Cryptodisk /mnt/Cryptodisk

Note: It's possible to compartmentalize multiple partitions by putting a LVM volume atop cryptsetup.
This is more advanced but pretty much straightforward.

Step by Step guide

I plug in my HDD and assume it's gonna be recognised as /dev/sdb.

First, We need to make sure that it's unmounted

Next, format the HDD. I normally use parted, but gparted seems to be the nicer way, as it's graphical and pretty easy. So, start gparted on the disk

MAKE SURE IT's THE RIGHT DISK. Do the partitions look like the ones expected? Is there anything fishy? Once you clear your partition table or (even worse) wrote a new filesystem, it's unlikely you can fetch your data without any losses. Take a breath and double-check before doing anything.

OK, Then create the partition you want to encrypt. Select a random filesystem, as we are anyways going to delete the filesystem. It's only important to create the layout correctly. In my case it looks like the following: one partition that takes the full space (Little bit of empty space at the end is needed by GPT for the Backup table)

gparted with the newly created layout

Close gparted and encrypt the partition using cryptsetup

Congratulations, you created your first encrypted parition! Now we are gonna put a filesystem on that one, so you can actually use it 🙂

So, we are gonna "open" the cryptdevice. This means, we are putting an encryption/decryption layer, atop which we can run our filesystem

Cryptsetup asks for the Passphrase. After successfully opening the device, it will be listed as /dev/mapper/Cryptodisk

Now we create a filesystem. I chose xfs because it's a nice working horse, that runs everywhere, but you can choose whatever you want.

Great, now you've created the filesystem. Close the disk with cryptsetup

Wait until everything on the disk has been written (it stops flashing, depending on your disk) and unplug the disk.

The next time you plug your disk in, it will be recognised by caja/nemo as Encrypted Device, you type in your Passphrase and it will be automatically mounted (or with cryptstetup luksOpen and mount but the purpose was to create a convenient way to work with your external disks).

The encrypted disk appears conveniently and can be mounted with a single click

Congratulations, you just created your first fully encrypted external HDD!

The headline picture was created btw. by using the amazing dekryptize tool - a really cool ncurses animation to show how decrypting is definitely NOT working 😉

Getting VeraCrypt running on a custom build Kernel

Having your own compiled Linux Kernel is a nice thing for various reasons. First, you are not stuck with the (depending on your distribution possibly outdated) Kernel versions your distribution and you highly customize your experience. Some people want to have a super-fast lightweight Kernel, I'm more on the other side of the spectrum. But that's a matter of flavor.

A side-effect is that you learn a lot more about Linux - inevitably issues will arise, from not working KVM (upcoming post) because of iptable issues to VeraCrypt that cannot operate with Kernel support.

Getting your custom Kernel ready for VeraCrypt

I've encountered the following error

device-mapper: reload ioctl on veracrypt1 failed: Invalid argument
Command failed

I've started with that. ioctl based errors normally are a good indicator that something in your Kernel configuration is or missing or misconfigured.
In this case it was the missing support for crypto targets in the device mapper (I suppose).

Fortunately the Gentoo-Forums provide some very useful informations. Make sure you have configured the following options in your Kernel

Device Drivers --->
[*] Multiple devices driver support (RAID and LVM) --->
<*> Device mapper support
<*> Crypt target support
[*] Block Devices --->
<*> Loopback device support
File systems --->
<*> FUSE (Filesystem in Userspace) support
[*] Cryptographic API --->
<*> RIPEMD-160 digest algorithm
<*> SHA384 and SHA512 digest algorithms
<*> Whirlpool digest algorithms
<*> LRW support
<*> XTS support
<*> AES cipher algorithms
<*> Serpent cipher algorithm
<*> Twofish cipher algorithm

Re-build your Kernel, and everything should work fine 🙂