heads icon indicating copy to clipboard operation
heads copied to clipboard

Make the path to crypttab within initramfs overridable

Open root-hardenedvault opened this issue 5 years ago • 6 comments

Not all distro put crypttab under /etc/ within initramfs, but finding it at runtime needs unpacking, which may be hard to do, so it is made overridable with a file at /boot/kexec_initrd_crypttab_path.txt, whose content could be obtained with $ cpio -t < ${uncompressed_initrd} | grep crypttab .

The "target" field of the record within the crypttab stored in the root file system for the luks container which is going to be unlocked via kexec-insert-key should be modified into the same "luks-$uuid" format, otherwise the boot sequence will get stuck when OS is trying to unlock them again, in order to map them according to "target" fields written in the crypttab stored in the root fs.

root-hardenedvault avatar Nov 06 '20 06:11 root-hardenedvault

@root-hardenedvault nothing can be used under /boot grub to determine if we are into a debian OS and make this detectable at runtime?

tlaurion avatar Nov 10 '20 02:11 tlaurion

Of course the best way is to analyse the initrd with cpio -t to find the correct path of crypttab, but compression methods and microcode need to be dealt with. It's currently that crypttab is only put under /cryptroot inside initrd in Debian GNU/Linux. Feel free to analyse the initrd if you want to go with runtime detection. IMO, either general approach or dirty hacks should serve one purpose at least, which is minimize the changes in long-term maintenance because firmware isn't like a random package in GNU/Linux distro.

root-hardenedvault avatar Nov 10 '20 09:11 root-hardenedvault

@root-hardenedvault : I was questionning more of artifacts under /boot/grub that would permit to determine from Heads if crypttab is to be found under /crypttab or /etc/crypttab, so that this can be determined from Heads without the need to hardcode its path under kexec_initrd_crypttab_path.txt.

tlaurion avatar Nov 10 '20 14:11 tlaurion

@root-hardenedvault ?

tlaurion avatar Mar 23 '21 03:03 tlaurion

@Mrchromebox Debian based setup backfires?

tlaurion avatar Oct 08 '21 22:10 tlaurion

@tlaurion I don't understand the question

MrChromebox avatar Oct 08 '21 23:10 MrChromebox

Sorry to review this so late @root-hardenedvault .... Testing qemu+swtpm+ubuntu into LUKS partition made me review this.

As of now, current code, specifically https://github.com/osresearch/heads/pull/894/files#diff-42674bf58097426acd0f4af0118ff6f76fae05af6c8e1fd1f52a78817129fd16R98 is not enough to boot Ubuntu with default boot option on TPM1 (goal is to be able to unlock LUKS partition with TPM2). So looking at this to understand the problem.

tlaurion avatar Jan 04 '23 23:01 tlaurion

@JonathonHall-Purism : I know that Pureboot doesn't implement TPM disk unlock key, but since based on Debian, any insight on above comment? (Ubuntu deployed inside of LUKS container: should unlock with Disk unlock key passphrase on top of Ubuntu/PureOS). Sidenote: You should push PR on Heads for detached public key signature under initrd/etc/distro/keys/ : that would be good for Heads+PureOS).

2023-01-04-184009

tlaurion avatar Jan 04 '23 23:01 tlaurion

@tlaurion Not sure I have the answers you need offhand, just a couple of thoughts.

PureOS does have a crypttab at etc/crypttab in the initrd by default. (There's also one at cryptroot/crypttab for whatever reason, the files are not identical but they are equivalent.) PureOS also defaults to encrypted root and unencrypted /boot, which IIRC is unlike any of Debian's automatic partitioning configurations.

I think Debian defaults to encrypted /boot now too, no idea about Ubuntu. I can't recall offhand exactly how it's partitioned. I'm in the habit of manually partitioning Debian, and I'm not even sure if the default behavior is the same across the netinstall and live install images (might be, just not sure).

I may be running a couple of installs today/tomorrow for a couple of other issues, if I do I can take a look at what it's doing. Ubuntu could still be completely different though, and I can't recall the last time I used Ubuntu.

JonathonHall-Purism avatar Jan 05 '23 15:01 JonathonHall-Purism

Under debian initramfs (skipping disk unlock prompt to let Heads pass additional cpio to be decompressed under /etc/crytpttab):

2023-01-16-114849

Under debian booted with disk recovery key, output of /etc/crypttab: 2023-01-16-114249 2023-01-16-113248

Basically, it seems that Debian based /scripts/local-top/cryptroot is only looking into initramfs's /cryptroot/cryptab, not caring about /etc/cryptab: 2023-01-16-134753

So basically, adding Debian-related crypttab path by default resolves the issue.

Note that the proposition here does not append the paths anymore in what is to be added into cpio to be applied on top of initramfs (overwriting what is found there anyway, passed through unseal-key when a TPM disk encryption key is defined through setting a new boot default and choosing to add a TPM disk unlock key.

diff --git a/initrd/bin/kexec-insert-key b/initrd/bin/kexec-insert-key
index 4592f698..9cceaa1b 100755
--- a/initrd/bin/kexec-insert-key
+++ b/initrd/bin/kexec-insert-key
@@ -47,7 +47,10 @@ if [ -r $bootdir/kexec_initrd_crypttab_path.txt ]; then
 else
        crypttab_path=etc/crypttab
 fi
-mkdir -p "$INITRD_DIR/$(dirname $crypttab_path)"
+
+#For most OSes, crypttab config file taken into consideration is under /etc/crypttab
+#Debian11+ looks only for /cryptroot/crypttab. We add that path by default
+mkdir -p "$INITRD_DIR/$(dirname $crypttab_path)" "$INITRD_DIR/cryptroot"
 
 # Attempt to unseal the disk key from the TPM
 # should we give this some number of tries?
@@ -95,7 +98,8 @@ if [ "$unseal_failed" = "n" ]; then
        # overwrite crypttab to mirror the behavior for in seal-key
        for uuid in `cat "$TMP_KEY_DEVICES" | cut -d\  -f2`; do
                # In Debian, the "luks" option at last should not be omitted
-               echo "luks-$uuid UUID=$uuid /secret.key luks" >> "$INITRD_DIR/$crypttab_path"
+               # crypttab files in initramfs are overwritten from the ones passed below
+               echo "luks-$uuid UUID=$uuid /secret.key luks" | tee "$INITRD_DIR/$crypttab_path" "$INITRD_DIR/cryptroot/crypttab" > /dev/null
        done
        ( cd "$INITRD_DIR" ; find . -type f | cpio -H newc -o ) >> "$SECRET_CPIO"
 fi
 

Which works without user specifying an alternative path (while he still can under board config, but impractical) 2023-01-16-145935

tlaurion avatar Jan 16 '23 20:01 tlaurion

Included under https://github.com/osresearch/heads/pull/1280

tlaurion avatar Jan 16 '23 20:01 tlaurion