Full disk encryption (including boot) on Debian Bookworm
Devices that go out and about such as laptops and backup external drives should have their contents encrypted to guard against loss or theft. Plus you really want to encrypt everything (not just home
). All sorts of sensitive information can seep into logs, temp files and swap memory.
Linux installers that encrypt root
and home
and swap
usually create a separate, unencrypted boot
partition. This allows the boot loader to discover the Linux kernel before proceeding to decrypt and mount other partitions.
However, GRUB2 does support booting from an encrypted boot
courtesy of its cryptodisk
module. Debian's installer does not provide the option of encrypting boot
. But it is possible!
The following steps install a minimal Debian setup that makes use of the entire disk - minus a small OS independent efi partition - as a single Linux Unified Key Setup (LUKS) encrypted partition that is used by the Logical Volume Manager (LVM) to create "virtual partitions" (Logical Volumes or LVs). Installing LVM on top of the encrypted partition allows the creation of multiple LVs protected by a single passphrase, and dynamic resizing of LVs as needed.
My example system uses UEFI boot and the encrypted partition is vda3
.
This is how I do it ...
1. Install Debian
A visual walk-through using the Debian network installer to create a console-only base configuration using LVM on LUKS.
2. Convert LUKS2 device to LUKS1
Important! To enable GRUB to unlock a LUKS encrypted device that contains /boot
that device needs to be in LUKS format version 1. Debian's installer by default creates LUKS2 devices.
Check the LUKS format version on the root device (example: vda3
) by running luksDump
...
$ sudo cryptsetup luksDump /dev/vda3
LUKS header information
Version: 2
[...]
Keyslots:
0: luks2
Output is Version: 2
and in Keyslots
there is a single occupied slot - 0: luks2
- containing the encryption passphrase.
Existing LUKS2 devices can be converted to LUKS1, but not on a mounted filesystem.
Reboot the computer. At the GRUB menu, enter e
to edit, add break=mount
to the end of the linux
line for the kernel, then press F-10
to boot. System drops into a initramfs
shell.
Key slots need to be converted to use the PBKDF2 algorithm exclusively prior to LUKS format version downgrade ...
(initramfs) cryptsetup luksConvertKey --pbkdf pbkdf2 /dev/vda3
(initramfs) cryptsetup convert --type luks1 /dev/vda3
(initramfs) cryptsetup luksDump /dev/vda3
Running luksDump
now outputs Version: 1
and Key Slot 0: ENABLED
and key slots 1 through 7 DISABLED
.
CTRL-ALT-Delete
to reboot.
3. Read-only
Ensure data is not modified while being copied by remounting /boot
read-only ...
$ sudo mount -o remount,ro /boot
4. Move boot to root
Copy the contents of boot
to boot.tmp
residing on the root
filesystem ...
$ sudo cp -axT /boot /boot.tmp
Replace the old boot
mountpoint with the new directory ...
$ sudo umount /boot/efi && sudo umount /boot
$ sudo rmdir /boot
$ sudo mv -T /boot.tmp /boot
$ sudo mount /boot/efi
5. Fstab
Modify /etc/fstab
by commenting out the entry for the /boot
mountpoint ...
#UUID=... /boot ext2 defaults 0 2
6. GRUB
Add the CRYPTODISK
module to GRUB ...
$ echo "GRUB_ENABLE_CRYPTODISK=y" | sudo tee --append /etc/default/grub
$ sudo update-grub
$ sudo grub-install /dev/vda
Verify that grub.cfg
has entries for insmod cryptodisk
and insmod luks
...
$ sudo grep 'cryptodisk\|luks' /boot/grub/grub.cfg
Otherwise, add cryptodisk
and luks
to GRUB_PRELOAD_MODULES
in /etc/default/grub
and re-install grub.
Reboot.
System prompts Attempting to decrypt master key...
for passphrase to unlock hd0,gpt3
. Enter passphrase and after a short delay the GRUB menu appears. Later, a second prompt appears to re-enter the passphrase to unlock vda3_crypt
.
Note: GRUB stage input uses the qwerty
keyboard layout and only one attempt is allowed to enter the correct passphrase (in case of incorrect entry, a reboot is required). But when the kernel prompts a second time for the passphrase to unlock the LVM volume it does use any previously assigned keymap.
7. Keyfile
Add a keyfile to avoid having to enter the passphrase twice.
Generate an encryption keyfile and place in a LUKS key slot ...
$ sudo dd bs=512 count=4 if=/dev/random of=/keyfile iflag=fullblock
$ sudo chmod 600 /keyfile
$ sudo cryptsetup luksAddKey /dev/vda3 /keyfile
$ sudo cryptsetup luksDump /dev/vda3
Keyfile has been added to Key Slot 1: ENABLED
. Original passphrase occupies Key Slot 0: ENABLED
, and there remain 6 free slots DISABLED
.
Modify /etc/crypttab
and replace none
with the key file path (/keyfile
) and the key-slot it occupies (key-slot=1
) ...
vda3_crypt UUID=<a_long_string_of_characters> /keyfile luks,discard,key-slot=1
8. Initramfs
Modify /etc/cryptsetup-initramfs/conf-hook
with ...
KEYFILE_PATTERN="/keyfile"
In /etc/initramfs-tools/initramfs.conf
, set UMASK
to root-only access to avoid leaking key material ...
$ echo UMASK=0077 | sudo tee --append /etc/initramfs-tools/initramfs.conf
Re-generate the initramfs image ...
$ sudo update-initramfs -u -k all
Verify the image has the restrictive permissions and includes the key ...
$ stat -L -c "%A %n" /initrd.img
-rw------- /initrd.img
$ sudo lsinitramfs /initrd.img | grep "^cryptroot/keyfiles/"
cryptroot/keyfiles/vda3_crypt.key
Reboot. Now there is only the single prompt for a passphrase!
9. Helpful
- Unlocking LUKS devices from GRUB
- Arch Wiki: Encrypting an entire system
- Cryptsetup actions specific for LUKS
You can like, share, or comment on this post on Mastodon 💬
» Next: Virtualization using KVM + QEMU + libvirt
« Previous: Keep LMDE updated and tidy