Thanks to http://madduck.net/docs/cryptdisk/
Even though the Debian installer can set up encrypted partitions, it is optimised for systems with a single data partition, unless you want to enter multiple passphrases when the system boots. The installer configures a LUKS volume using cryptsetup, but it provides no mechanism for the use of key files, only interactive passphrases.
I like partitioning my disks and use different filesystems for /tmp
, /home
, /var
, and /usr/local
for a number of reasons. I don’t like entering more passphrases than necessary. If you can identify with that, the following is for you.
Several people have pointed out to me that one can simply create a single encrypted “physical volume” with the Debian installer and place “logical volumes” for the various filesystems in there. You still need a separate /boot
partition, in any case. Kapil Hari Paranjape has described the approach, as well as Simon McVittie.
This method is much cleaner and to be preferred. It’s quite likely that it also improves the speed since only a single kcryptd
process takes care of all of the decryption and encryption needs.
Nevertheless, the following is still useful with that approach, although it’ll be less complicated.
Installing the system
The first step to setting up an encrypted Debian system is to perform a normal Debian system installation. When you are asked to partition your harddrive and create filesystems, set up all partitions as encrypted volumes (I suggest to go with the installer defaults and use dm-crypt and AES with the default settings, simply because I have no reason to doubt the installer dveeloper team’s choices). Make sure to erase the disks in the process — the installer has an option for that.
Set up the swap partition as an encrypted volume too, but don’t worry too much about the settings at this point; we will recreate the swap partition later.
Unless you want to boot off an external medium, such as a USB stick, you will need to create an unencrypted partition for /boot
. I will return to this topic, which has security implications, further down.
The installer will ask you for passphrases for each of the volumes you create. I suggest you pick a secure passphrase for the root volume (/
), but simple passphrases for all the other ones (such as “a”), since we will reconfigure them to use key files instead.
Using key files
A key file is like a passphrase stored in a file on disk; as opposed to “what you know”, it’s a “what you have” security asset. Thus, you need to store the file somewhere. When I boot up my system, I unlock the root partition with a passphrase entered interactively, which makes the root filesystem available. I store key files for all other volumes in /etc/keys
. Obviously, I need to tell cryptsetup
to use those.
The first step is to create a key file for each partition and to add it as a decryption key to the LUKS
volume. You can do all of the following without unmounting the filesystems. See the following example for hda6
, which will prompt for the simple passphrase we entered above to unlock the key ring when adding the key file:
umask 077
mkdir /etc/keys
dd if=/dev/urandom of=/etc/keys/hda6.luks bs=4k count=1
cryptsetup luksAddKey /dev/hda6 /etc/keys/hda6.luks
cryptsetup luksKillSlot /dev/hda6 0 --key-file /etc/keys/hda6.luks
The last command wipes the simple passphrase from the key ring and thus makes it unusable.
Now we need to tell cryptsetup
to use the key file by editing /etc/crypttab
and ensuring a line such as the following exists:
hda6_crypt /dev/hda6 /etc/keys/hda6.luks luks
This tells cryptsetup
to create the cryptographic volume hda6_crypt
from the base device /dev/hda6
, using the key file we created above, and letting it know that it’s dealing with a LUKS
volume.
Repeat this for every partition except your root and swap partitions.
Encrypting the swap partition
If you are using an encrypted Debian system, you likely have some security requirements to meet. If that’s the case, you must also use an encrypted swap partition.
The swap partition can be encrypted in two ways:
- it can be recreated on every boot, using a random passphrase, or
- it can be created like the other encrypted volumes with a persistent passphrase
If you want to use suspend-to-disk, you cannot use the first approach as it would overwrite your memory footprint stored in the swap partition. Furthermore, you cannot use a key file like the other partitions, since the root filesystem is not (and must not) be mounted by the time the resume process starts and needs to read the decrypted swap partition.
The way I solved this is by telling cryptsetup
to compute the passphrase of the swap partition from the decryption key of the volume holding the root filesystem; the cryptsetup
package implements this with /lib/cryptsetup/scripts/decrypt_derived. Thus, to set up the swap partition, I do the following, assuming hda2
is the partition holding the encrypted swap and the root filesystem is in hda5_crypt
:
swapoff /dev/mapper/hda2_crypt
cryptsetup luksClose hda2_crypt
dd if=/dev/urandom of=/dev/hda2
/lib/cryptsetup/scripts/decrypt_derived hda5_crypt \
| cryptsetup luksFormat /dev/hda2 --key-file -
/lib/cryptsetup/scripts/decrypt_derived hda5_crypt \
| cryptsetup luksOpen /dev/hda2 hda2_crypt --key-file -
mkswap /dev/mapper/hda2_crypt
To tell the system about this swap partition, we need to add it to /etc/crypttab
and /etc/fstab
; make sure, those files contain lines like the following:
/etc/crypttab:
hda2_crypt /dev/hda2 hda5_crypt luks,keyscript=/lib/cryptsetup/scripts/decrypt_derived
/etc/fstab:
/dev/mapper/hda2_crypt swap swap sw 0 0
With this in place, as soon as you configure the system for suspend-to-disk, the swap partition will be automatically set up alongside the root filesystem very early during the boot sequence. To figure out which swap partition to make available at that point, cryptsetup
checks the following:
- a line like
RESUME=/dev/mapper/hda2_crypt
in/etc/initramfs-tools/conf.d/resume
- a resume device setting in
/etc/uswsusp.conf
(seeuswsusp.conf(5)
) - an entry in
/etc/suspend.conf
- a
resume=/dev/mapper/hda2_crypt
in the kernel command line
You can inspect /usr/share/initramfs-tools/hooks/cryptroot if you want to know more about this.
Using UUIDs
Even though the above is all you have to do, you might want to consider replacing the device paths in /etc/crypttab
with persistent ones. One motivation might be the ability to boot off your drive via a USB adapter, which might cause it to appear as /dev/sda
instead of /dev/hda
.
udev is installed by default on Debian systems and it makes persistent links to partitions available under /dev/disk/by-uuid
, using the UUID
of the content structure (e.g. the LUKS
header). It uses /lib/udev/vol_id
to determine those link names.
If you replace the entries in /etc/crypttab
, make sure to update the initramfs
(update-initramfs -u -k all
) and consider to use the same approach for the /boot
filesystem in /etc/fstab
; you’ll note that all other filesystems use persistent device paths thanks to the dm-crypt
layer.
If you ever end up booting off the disk through a USB adapter, you might face the problem where the usb_storage
subsystem takes too long to activate, so that the cryptsetup
script does not find the devices in time. You can either solve this by adding the rootdelay=x
parameter or break=mount
to the kernel command line. The first will cause the scripts to wait x
seconds before trying to configure and mount the root filesystem; the second would give you a shell that you can exit as soon as the kernel spouted its device initialisation messages at you.
f you got this far, you might even want to take it further and replace hda5_crypt
with cr_root
or the like to abstract those silly partition numbers away even further. This is easier than it sounds, but does require several steps. Do not do this if you’re not comfortable reviving your system in case it fails to come back up!
- replace the old names with the new names in
/etc/crypttab
for all volumes except the root volume. If you are using a derived passphrase for the swap partition, make sure to put the new name for the root volume into the third column of the swap partition’s configuration line. - modify
/etc/fstab
accordingly, leave the root filesystem’s device path alone. - call
update-initramfs -u
- modify your bootloader to ask the kernel to boot off the new root volume.
- replace the root volume’s old name with the new one in
/etc/fstab
. - reboot, and add
break=mount
to the kernel command line. - at the
busybox
prompt, edit (vi
)/conf/conf.d/cryptroot
and change the first field of the root volume’s line to the new name. - exit the shell and watch the boot process complete.
- finally, replace the root volume’s old name with the new one in
/etc/crypttab
.
If the system fails to boot up again, you can use the backup initial ramdisk, which update-initramfs
left in /boot
.
Security implications
Apart from the usual security implications related to cryptosystems, passphrases, mathematics, user stupidity, and so on, the approach I outlined will leave you with a pretty well-secured system. Obviously, you should make sure to lock your screen whenever you leave the system unattended or the entire encryption is basically useless.
There are two attack vectors on your system, both involving physical access to the machine:
- theft of the machine or its RAM chip, freezing the latter, and scanning the working memory for the passphrase
- manipulation of the kernel or
initramfs
stored on the (unencrypted)/boot
filesystem, in such a way as to obtain the passphrase. To do this, you would have to have access to my machine and return it to me without me noticing; once I restart and enter the passphrase, you’d have to steal it again
Other than that, you should be careful when travelling to totalitarian countries, like the Excited States of America, China, and probably the UK. First off, encryption arouses suspicion, and second, border agents might ask you to decrypt the partitions for them to copy or scan, and refusal to do so might get your turned away at the border. When travelling to those countries, make sure to hide your data properly.
Speed implications
Obviously, having your entire system encrypted (including swap) will slow it down. I don’t have any quantitative information on that, but after several years of using full-disk encryption on my laptop (an X40, which isn’t very powerful), I can say that it remains usable, if you don’t rely on disk-intensive operations, such as compiling kernels and the like.
Alternative approaches
Several alternative approaches exist, all involving an additional device:
- if you don’t like to type in the passphrase for the root filesystem, you could store it on a USB key (or the like);
cryptsetup
provides/lib/cryptsetup/scripts/passdev
, which can be used to deal with such a situation. You can find more information incryptsetup
‘sREADME.Debian
file. - if you don’t like the unencrypted
/boot
partition, you could boot the system off a USB key, which you can keep separate from the system except for when booting and upgrading the kernel. All you need to do for that is install the bootloader and kernel onto the device and configure it to use the proper encryption volume on the harddisk as root filesystem. cryptsetup
also comes with support forPKCS#15
smartcards (opensc and openct).
I have chosen neither of these approaches, because the extra security does not make up for the inconvenience, and the danger of an unbootable system in case of loss of forgetting of the additional device.