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_cryptin/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_cryptin 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.
If 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/crypttabfor 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/fstabaccordingly, 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=mountto the kernel command line. - at the
busyboxprompt, edit (vi)/conf/conf.d/cryptrootand 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
initramfsstored on the (unencrypted)/bootfilesystem, 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);
cryptsetupprovides/lib/cryptsetup/scripts/passdev, which can be used to deal with such a situation. You can find more information incryptsetup'sREADME.Debianfile. - if you don't like the unencrypted
/bootpartition, 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. cryptsetupalso comes with support forPKCS#15smartcards (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.

