Installing Arch Linux with an encrypted root

I’ve got a ThinkPad T410. I got it off craigslist in what was a somewhat shady transaction. Regardless, it came with a 300GB spinner. Not interested in finding out how much life was left on it I got a solid state replacement from NewEgg for “Cyber Monday”. A 240GB Intel one for $110, that’s less than 50 cents per GB!

The spinner has a single unencrypted partition with Arch Linux running on it. I wanted to run Arch on an encrypted partition. The main reason: If it’s ever stolen I don’t want to have to worry about any of the data on it. Bonus reason: Geek/spy points.

So, while there are excellent guides for installing Arch, and setting up encryption, and optimizing an SSD, there don’t seem to be any combining the three. In reality it’s not that much more difficult, and if you are motivated to setup encryption on Linux in the first place you probably know what you’re doing. Still, I was disheartened a bit at the lack of information so I decided to note how I went about it in general.

Upgrading your hard disk is an excellent time to move to encryption. This is because it provides you with a backup of your data from the get-go. It allows (relatively) easy do-overs in case things go wrong.

I chose dm-crypt and to use LUKS, since this is both recommended and already included/the default. Before starting, you might want to verify that you have some hardware encrypt/decrypt support as this will greatly improve performance. Well, to be more accurate: It will greatly decrease the performance hit that encryption adds. With an SSD I can still expect much faster disk usage over the conventional spinning drive with hardware AES support. This may or may not be true if you do not have hardware acceleration.

So, after swapping hardware and booting the Arch install disc, see if you have hardware support:

$ cryptsetup benchmark
# Tests are approximate using memory only (no storage IO).
PBKDF2-sha1 794375 iterations per second
PBKDF2-sha256 549568 iterations per second
PBKDF2-sha512 377729 iterations per second
PBKDF2-ripemd160 510007 iterations per second
PBKDF2-whirlpool 167183 iterations per second
# Algorithm | Key | Encryption | Decryption
aes-cbc      128b   623.2 MiB/s  1509.2 MiB/s
serpent-cbc  128b    59.0 MiB/s   246.7 MiB/s
twofish-cbc  128b   145.4 MiB/s   199.5 MiB/s
aes-cbc      256b   467.3 MiB/s  1180.5 MiB/s
serpent-cbc  256b    59.0 MiB/s   246.9 MiB/s
twofish-cbc  256b   145.4 MiB/s   200.8 MiB/s
aes-xts      256b  1357.2 MiB/s  1356.9 MiB/s
serpent-xts  256b   219.8 MiB/s   224.6 MiB/s
twofish-xts  256b   186.8 MiB/s   184.7 MiB/s
aes-xts      512b  1069.3 MiB/s  1077.3 MiB/s
serpent-xts  512b   219.8 MiB/s   224.5 MiB/s
twofish-xts  512b   186.4 MiB/s   185.7 MiB/s

Note that AES is much faster. Which is good, since AES-XTS is the default. Now on to drive configuration and partitioning. My drive setup, from within the Live USB, is as follows:

  • /dev/sda - New drive
  • /dev/sdb1,2 - LiveUSB
  • /dev/sdc1 - Old drive (connected via eSATA)

We’ll be working with only the new drive (sda) and old (sdc), and you should be very certain you don’t format/mess with your old drive if you have it plugged in from the start, as you’re just a single mistyped character away from destroying all your old data during certain steps! Unplug it and wait till you’re ready to restore to be sure.

The general idea is:

  1. Setup partitions on new drive (/boot, root)
  2. Encrypt root partition, open, and mount it (and /boot)
  3. Format the unencrypted partition
  4. Install Arch
  5. Install bootloader, making a couple changes for encryption and the SSD
  6. Restart

That’s not bad. Compared to the normal process, the only difference is encrypting and opening the encrypted partition before mounting it, and making sure the bootloader/kernel knows about this.

Getting started

Follow the guide normally, until you get the partitioning portion of the Pre-installation section. You’ll need to plan this out a bit. With encryption, you’ll need at least two partitions. /boot and root (/). The boot partition will remain unencrypted since the kernel’s going to live there and it will prompt for the password to decrypt the other partition(s). You can also just encrypt /home by giving it its own partition, or any other directory. I chose to just encrypt the entire root file system. It’s the easiest to setup, in my opinion. Although doing just /home isn’t much more work.

Here’s my partition setup:

$ fdisk -l
Disk /dev/sda: 223.6 GiB, 240057409536 bytes, 468862128 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 9642BB03-FE03-4FCC-8FEF-BB7C2B10178E

Device    Start   End       Sectors   Size   Type
/dev/sda1 2048    1050623   1048576   512M   EFI System
/dev/sda2 1050624 468862094 467811471 223.1G Linux filesystem

Disk /dev/mapper/root: 223.1 GiB, 239517376000 bytes, 467807375 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

I’ve setup just the two. My /boot partition is larger than a typical ext2/3 boot partition since I’d like to try getting UEFI to boot the kernel directly and remove the syslinux bootloader (but that’s for another day). I also used gdisk to edit to allow for this. I just gave it the minimum EFI size and formatted it as FAT for future use. You can keep it at a 50MB and the traditional ext2 or whatever filesystem if you’d like.

For sda2, you can create the partition but do not format it. We’re going to encrypt it first. After encryption you’ll ‘mount’ the encrypted partition which will prompt for the password and decrypt it for use. Then you format the decrypted device. You never work directly with sda2 unless you’re updating/repairing the encryption headers themselves. Bad things will happen if you do otherwise. If you are reusing a drive with sensitive data instead of a brand new one, you may want to consider wiping the old data first. My drive’s fresh and I don’t care, so onward to preparing the new encrypted partition:

$ cryptsetup luksFormat -c [cipher] -s 512 /dev/sda2

Enter a fancy passphrase (like, 16+ characters) and that’s about it. You can also use keyfiles, stored on a USB stick or wherever, but that’s not for me. Now we open the device we just created:

$ cryptsetup open --type luks /dev/sda2 root

Now your actual partition will be mapped to /dev/mapper/root. That’s the actual device you’ll be formatting.

$ mkfs.ext4 /dev/mapper/root
$ mount /dev/mapper/root /mnt
$ mkdir /mnt/boot && mount /dev/sda1 /mnt/boot

Now you can continue on with the installation guide (pacstrap and whatnot), keeping in mind where your unencrypted root device is. genfstab had no problems figuring that out though, so it’s not that big of a deal. Keep in mind that you can glaze over most of the configuration stuff since we’ll be wiping all that out when we restore the system files from the old drive. After you’ve installed and setup your system is edit a couple config files so our SSD is a bit happier.

Unlocking at boot, SSD trim, & scheduler tweaking

To have your kernel know how to handle your encrypted drive, there are a couple steps. First, you’ll need to tell mkinitcpio to generate a kernel with the crypt module (the device encryption guide seems to forget to mention this explicitly, but the other parts do). Modify the HOOKS line by adding `encrypt` to it:

# /etc/mkinitcpio.conf
HOOKS="base ... block encrypt filesystems ..."

Note that it must in that pretty much that order. After block and before filesystems, at least. More hooks are needed if you are using a non-default keyboard, etc. That tells your system run some commands needed to make a kernel that can handle encryption. After that, you’ll need to tell the kernel (via the bootloader config) where the useable, unencrypted, root filesystem resides. To do so, we’ll need a specific kernel parameter:

cryptdevice=/dev/<mapped partition>:root

We’ll also set some other parameters like SSD TRIM and the preferred IO scheduler (none!). Be aware that only certain file systems support TRIM, and that there are “security implications” if enabled on an encrypted drive. Best case, you lose plausible deniability (don’t care), worst case some file system info. Only the most dedicated data thief will be interested in this. So, first, edit your bootloader’s configuration to add some kernel arguments. We specifically need to tell dm-crypt to pass through discard commands to the block device. Then you need to tell mount to send them as well. While you’re here you can tell the kernel to use the noop scheduler to improve performance on the SSD. For Syslinux I did the following:

# /boot/syslinux/syslinux.cfg
LABEL arch
APPEND root=/dev/mapper/root rw cryptdevice=/dev/sda2:root:allow-discards elevator=noop

You might want to do that for both boot options (Normal Arch and the fallback).

After these changes are complete, you can now generate a kernel and try to boot!

mkinitcpio -p linux
  -> Running build hook: [encrypt]
umount /mnt/boot
umount /mnt
cryptsetup luksClose /dev/mapper/root

Restore system from old drive

So, exit the chroot and you can boot your system if you’d like to verify it does, in fact, boot and decrypt the drive properly. While I was in the LiveUSB environment I decided to try restoring my files immediately. Before doing so you’ll need to copy your encryption/partition relevant files first.

$ mkdir /mnt2 && mount /dev/sdc1 /mnt2
$ mv /mnt2/etc/fstab /mnt2/etc/fstab.old
$ mv /mnt2/boot/syslinux/syslinux.cfg /mnt2/boot/syslinux/syslinux.cfg.old
$ cp /mnt/etc/fstab /mnt/etc/fstab
$ cp /mnt/boot/syslinux/syslinux.cfg /mnt2/boot/syslinux/syslinux.cfg

I think that’s it. Might be one or two more, so no guarantees. Time to restore your old system. A little Googling and man reading and I think I have the proper rsync command to do so:

rsync -aHXS -delete -numeric-ids [SRC] [DEST]

$ rsync -aHXS --delete --numeric-ids /mnt2/ /mnt/

That will set “archive” mode, which just sets a bunch of other options for symlinks and device files, copy hard links, copy extended attributes, delete files that don’t exist on the source tree, and (very importantly) use numeric ids instead of going by names (that may not exist). Run that, and bask in the speed of your new SSD.

Now, the moment of truth, a restart. Unmount all your drives, and be sure to close the encrypted drive via:

$ cryptsetup close root

If all goes well your system will load the kernel, messages will fly by faster than you can read until it hits the decryption prompt, at which point it seems upset that it has to wait for human input. After entering your passphrase you should see the login prompt you’re familiar with. Ignoring inputting my passphrase, my system boots up in 2 seconds, literally. About 1.5 seconds of that is the BIOS screen.

It’s been a couple days, and I have not had any filesystem or other issues. Although, Dropbox did ask for me to reauthenticate this computer, which I thought was odd. No worries, it’s probably using a hardware hash of some type.