Full Disk Encryption - noobient/noobuntu GitHub Wiki

Passphrase

After installation, find the encrypted disk's device name:

luks_device="/dev/$(lsblk --fs | grep crypto_LUKS | awk '{print $1}' | tr -cd '[:alnum:]')"

Add a new proper LUKS key:

sudo cryptsetup luksAddKey "${luks_device}"

Then remove the default placeholder key:

sudo cryptsetup luksRemoveKey "${luks_device}"

Do not use luksChangeKey, it's broken on Ubuntu 20.04.2.

Automatic Unlock

TPM 2

Make sure that TPM2 (Trusted Platform Module, Trusted Computing, Security Device, ...) is enabled in UEFI. Also check if it's detected by the OS:

$ dmesg | grep -i tpm
[    1.438823] tpm_tis MSFT0101:00: 2.0 TPM (device-id 0x1A, rev-id 16)

Verify that it's a TPM2 device, 1.2 or below will not work.

Boot into Linux, and bind LUKS to the TPM2 module. Example:

sudo clevis luks bind -d "${luks_device}" tpm2 '{"pcr_ids":"7"}'

If you receive the following warning, just accept it with y:

You are about to initialize a LUKS device for metadata storage.
Attempting to initialize it may result in data loss if data was
already written into the LUKS header gap in a different format.
A backup is advised before initialization is performed.

Do you wish to initialize /dev/nvme0n1p3? [yn] y

Then apply the changes to the initrd:

sudo update-initramfs -c -k all

Tang

If the computer has wired connectivity, set up a Tang server and use that for network unlock:

sudo clevis luks bind -d "${luks_device}" tang '{"url": "http://tang.foobar.com"}'
sudo update-initramfs -c -k all

If DNS resolution fails during boot (and this the disk is not unlocked), create the /etc/initramfs-tools/hooks/fix_add_dns file, make it executable, and add the following:

#!/bin/sh
. /usr/share/initramfs-tools/hook-functions

local_libdir="/lib/x86_64-linux-gnu"
local_found="" lib="" f=""
for lib in libnss_files libnss_dns libresolv; do
    local_found=""
    for f in "$local_libdir/$lib.so".?; do
        [ -e "$f" ] || continue
        [ "$verbose" = "y" ] && echo "dns: $lib: $f"
        copy_file library "$f"
        local_found="$f"
    done
    [ -n "$local_found" ] || echo "WARNING: no $local_libdir/$lib.? file" 1>&2
done

If the machine has multiple interfaces, the boot environment might try to bring up the wrong interface during unlock. In this case, you can force the proper interface to be used by editing /etc/default/grub like so (eno1 is an example interface, change as needed):

GRUB_CMDLINE_LINUX="ip=:::::eno1:dhcp:"

Then run

sudo update-grub

Password

If wired networking is not an option, you need to add a manual key to the device, e.g.:

sudo cryptsetup luksAddKey "${luks_device}"

Troubleshooting

If something goes wrong with the bind, e.g. automatic unlock doesn't happen during boot, you can check LUKS state with:

sudo cryptsetup luksDump "${luks_device}"

The slot being used by Clevis can be determined with:

clevis_slot=$(sudo cryptsetup luksDump "${luks_device}" | grep -i clevis -A1 | grep -iv clevis | awk '{print $2}')

Then you can perform the unbind with:

sudo clevis luks unbind -d "${luks_device}" -s "${clevis_slot}"
sudo cryptsetup luksKillSlot "${luks_device}" "${clevis_slot}"