linuxboot / heads

A minimal Linux that runs as a coreboot or LinuxBoot ROM payload to provide a secure, flexible boot environment for laptops, workstations and servers.
https://osresearch.net/
GNU General Public License v2.0
1.41k stars 186 forks source link

Add `export CONFIG_AUTO_BOOT_TIMEOUT=5` to all board configs #1441

Closed 3hhh closed 8 months ago

3hhh commented 1 year ago

Is your feature request related to a problem? Please describe. heads doesn't start the boot process without user interaction.

Describe the solution you'd like Add an option like GRUB_TIMEOUT to execute the default boot after some time, if that's defined and all verifications succeed.

Additional context I'd also like an option to boot after that timeout even if verification fails as that would help with testing. However imho such an option breaks the heads security model as an attacker could simply enable it and then lure the user into auto-booting. EDIT: After giving it some more thought, I believe that such an option should be possible as an attacker can modify the firmware any way s/he wants anyway, The user will still have to manually check the HOTP/TOTP dongle to make sure that doesn't happen.

tlaurion commented 1 year ago

@3hhh can you enable restricted boot and test how you you would want to do this?

Recent purism merge add those possibilities, just would need a use case and a matching PR

tlaurion commented 1 year ago

Restricted boot stops attacker to get to recovery shell and flash. And if one does, counter changes and Totp is wiped. Check it out

tlaurion commented 1 year ago

Autoboot could be activated but would stop you at TPM disk unlock key?

tlaurion commented 1 year ago

Otherwise autoboot would just kexec to OS which prompts the disk decryption password. The whole idea of heads is to type that passphrase in a trusted environment, not the OS.

Waiting for your use case in which default boot should boot securely aftet timeout

3hhh commented 1 year ago

Otherwise autoboot would just kexec to OS which prompts the disk decryption password. The whole idea of heads is to type that passphrase in a trusted environment, not the OS.

Hm I'v never used heads for that. Can I not consider the OS kernel trusted once it was verified?

Waiting for your use case in which default boot should boot securely aftet timeout

A few use cases:

  1. On the machine where I use heads I currently need to manually step to the machine to hit Return on the heads prompt every day as USB is apparently deactivated and my USB keyboard doesn't work. The USB issue is fine for me for security reasons, but it's a bit annoying anyway.
  2. I have another somewhat untrusted test machine where I currently don't run heads as I just want it to boot even if there's no dongle, failed verification, whatever... heads doesn't offer that option without 20s user interaction. Plain coreboot does just that, but is super annoying to compile and somewhat trusted blobs are mostly not available (heads blobs are available, yay). So I tend to stick to some ancient coreboot version I compiled a long time ago and never update. I know there's this other coreboot spin-off with pre-compiled binaries, but imho that shouldn't be needed.
  3. If I had a server where I'd want to run heads, I'd certainly not want it to stop booting and wait for me to press return unless there's some grave issue. I could imagine going to the server to watch that green HOTP LED blink or watch it over camera, but I don't want to connect a keyboard on every boot. I know there's a non-UI variant of heads, but that's less powerful.
tlaurion commented 1 year ago

Otherwise autoboot would just kexec to OS which prompts the disk decryption password. The whole idea of heads is to type that passphrase in a trusted environment, not the OS.

Hm I'v never used heads for that. Can I not consider the OS kernel trusted once it was verified?

@3hhh I'm not sure I understand the concern here. You would trust kernel+initrd+boot parameters from preboot environment (heads) only but not booting into it?

3hhh commented 1 year ago

On 7/17/23 00:12, tlaurion wrote:

Otherwise autoboot would just kexec to OS which prompts the disk decryption password. The whole idea of heads is to type that passphrase in a trusted environment, not the OS.

Hm I'v never used heads for that. Can I not consider the OS kernel trusted once it was verified?

@3hhh I'm not sure I understand the concern here. You would trust it from preboot environment?

Yes, I do, if it was verified by heads before. Your comment indicated that it couldn't be trusted even if it was verified (= checksum checked) by heads. I was just curious why that should be the case. Maybe however we misunderstood each other, idk.

tlaurion commented 1 year ago

Two main features have been added through https://github.com/osresearch/heads/pull/1419 which might interest you here: Restricted Boot and Basic Boot modes.

On 7/17/23 00:12, tlaurion wrote: > Otherwise autoboot would just kexec to OS which prompts the disk decryption password. The whole idea of heads is to type that passphrase in a trusted environment, not the OS. > > Hm I'v never used heads for that. Can I not consider the OS kernel trusted once it was verified? @3hhh I'm not sure I understand the concern here. You would trust it from preboot environment? Yes, I do, if it was verified by heads before. Your comment indicated that it couldn't be trusted even if it was verified (= checksum checked) by heads. I was just curious why that should be the case. Maybe however we misunderstood each other, idk.

I think I get where the confusion stems

So yet again, I'm not sure what would be the advantage here of adding autoboot (GRUB_TIMEOUT) to Restricted Boot or normal Heads boot. But if I understand your need correctly, what you want for your use case is to enable usb keyboard support, that is, packing USB HID kernel driver as a module and have that module loaded at boot so that you can type your TPM disk decryption key through a USB keyboard?

Here are differences between normal, non-USB-HID enabled board config and USB HID enabled board config:

user@heads-tests-deb12:~/heads$ diff boards/x230-hotp-maximized/x230-hotp-maximized.config boards/x230-hotp-maximized_usb-kb/x230-hotp-maximized_usb-kb.config 
8c8,10
< # - Includes: Nitrokey/Librem Key HOTP Security dongle remote attestation (in addition to TOTP remote attestation through Qr Code)
---
> # - Includes: 
> #     Nitrokey/Librem Key HOTP Security dongle remote attestation (in addition to TOTP remote attestation through Qr Code)
> #     USB Keyboard support
18a21
> export CONFIG_USB_KEYBOARD=y
66c69
< export CONFIG_BOARD_NAME="Thinkpad X230-hotp-maximized"
---
> export CONFIG_BOARD_NAME="Thinkpad X230-hotp-maximized_usb-kb"

With those notions in the background, i'll reply inline below:

Waiting for your use case in which default boot should boot securely aftet timeout

A few use cases:

1. On the machine where I use heads I currently need to manually step to the machine to hit Return on the heads prompt every day as USB is apparently deactivated and my USB keyboard doesn't work. The USB issue is fine for me for security reasons, but it's a bit annoying anyway.

Enable usb keyboard for your board config as explaned above.

2. I have another somewhat untrusted test machine where I currently don't run heads as I just want it to boot even if there's no dongle, failed verification, whatever... heads doesn't offer that option without 20s user interaction. Plain coreboot does just that, but is super annoying to compile and somewhat trusted blobs are mostly not available (heads blobs are available, yay). So I tend to stick to some ancient coreboot version I compiled a long time ago and never update. I know there's this other coreboot spin-off with pre-compiled binaries, but imho that shouldn't be needed.

That would be Basic Boot without any tampering detection

3. If I had a server where I'd want to run heads, I'd certainly not want it to stop booting and wait for me to press return unless there's some grave issue. I could imagine going to the server to watch that green HOTP LED blink or watch it over camera, but I don't want to connect a keyboard on every boot. I know there's a non-UI variant of heads, but that's less powerful.

Server normally offers BMC and Heads configs already deal with that. It would be either TOTP or HOTP, where TOTP permits to verify the code remotely and where USB Security dongle is connected on the motherboard to permit detached signature on OS upgrades. BMC in that case offers a serial console to Heads shell, and permits here again to type TPM disk decryption key passphrase in the firmware and not the OS. I guess there too, you could want to use Basic Mode or come with some kind of alternative remote attestation mechanisms to make sure everything is as expected (and verified externally) prior of typing your Disk Recovery Key passphrase in LUKS slot 0 key?

TLDR: Autoboot is currently only supported on Basic Boot, and is basically Heads without security features. Having Restricted Boot with autoboot, as of today, doesn't make sense to me unless something else is implemented. I do not see a case where Autoboot could work, unless wewould totally trust Heads to unseal TPM disk unlock key without asking the user for any passphrase. That is, just like TPMTOTP is unsealed to produce HOTP/TOTP today, and would be some kind of Microsoft equivalent of bitlocker which doesn't "authenticate" the user, but only firmware and /boot integrity to boot into the OS. In that scenario, dractu recovery shell could be used to DoS the system. Just like today, without enabling Restricted Boot, an attacker can abuse of the Recovery Shell to do such DoS attack on the system (wipe disk, wipe TPM etc).

So, if I get what you would want:

@3hhh Am I getting this right?

3hhh commented 1 year ago

On 7/17/23 18:12, tlaurion wrote:

TLDR: Autoboot is currently only supported on Basic Boot, and is basically Heads without security features. Having Restricted Boot with autoboot, as of today, doesn't make sense to me unless something else is implemented. I do not see a case where Autoboot could work, unless wewould totally trust Heads to unseal TPM disk unlock key without asking the user for any passphrase. I think this is where the confusion stems from: I do not use a TPM disk unlock key. I use heads to verify /boot incl. initrd and then type the luks password at initrd. I believe you said that this has worse security properties than using the TPM unlock, but I currently don't understand the difference. The only minor advantage I see is in restricted boot, where an attacker couldn't boot the OS at all (assuming s/he doesn't want to remove the disk, which takes ~15s on my machine).

I agree a timeout doesn't make sense with a TPM disk unlock key as you'll have to type the TPM password anyway. Imho it makes sense for people who use the standard initrd luks prompt - even in restricted & normal boot.

Btw thank you very much for the link to basic boot! That'll indeed solve my use case for the test machine. :-)

3hhh commented 1 year ago

I just tested basic boot on my test machine and it indeed seems to work. :-)

It could use a timeout as well though. ;-)

tlaurion commented 1 year ago

I just tested basic boot on my test machine and it indeed seems to work. :-)

It could use a timeout as well though. ;-)

@3hhh sorry I didn't get back to you and now doing so while away of keyboard. Take a look at purism boards which have a timeout implemented AFAIK which is looked for in code.

tlaurion commented 1 year ago

I just tested basic boot on my test machine and it indeed seems to work. :-)

It could use a timeout as well though. ;-)

@3hhh sorry I didn't get back to you and now doing so while away of keyboard. Take a look at purism boards which have a timeout implemented AFAIK which is looked for in code.

With Basic mode enabled, that is https://github.com/osresearch/heads/blob/6e31163121d1d600047df859844ab8408cc53d2a/boards/librem_14/librem_14.config#L42

3hhh commented 1 year ago

Hm interesting. Looks like CONFIG_AUTO_BOOT_TIMEOUT is around for a long time - even for non-basic boot.

I guess then my request would be to set it to a reasonable value by default for all boards. Currently it's only enabled for Librem boards. Alternatively make it possible to edit it from the heads UI.

tlaurion commented 1 year ago

Hm interesting. Looks like CONFIG_AUTO_BOOT_TIMEOUT is around for a long time - even for non-basic boot.

I guess then my request would be to set it to a reasonable value by default for all boards. Currently it's only enabled for Librem boards. Alternatively make it possible to edit it from the heads UI.

Right, if HOTP dongle is connected and returns success. And otherwise if Basic mode enabled without validating anything.

3hhh commented 1 year ago

On 8/21/23 16:09, tlaurion wrote:

Hm interesting. Looks like CONFIG_AUTO_BOOT_TIMEOUT is around for a long time - even for non-basic boot.

I guess then my request would be to set it to a reasonable value by default for all boards. Currently it's only enabled for Librem boards. Alternatively make it possible to edit it from the heads UI.

Right, if HOTP dongle is connected and returns success. And otherwise if Basic mode enabled without validating anything.

Yes, these are exactly the two use cases I wanted covered. :-)

tlaurion commented 1 year ago

@JonathonHall-Purism and what about having this timeout being automatic without it needing to be defined under board configs?

Seems like if hotp good, we could go default boot just by changing that?

JonathonHall-Purism commented 1 year ago

I'd support changing the default behavior to automatically boot after 5 seconds :+1:

It'd still be nice to keep the variable around - I know some of our users have requested shorter or longer times, so it'd be nice to add this as an actual config-gui setting (which I have on my to-do list for next release).

So we could either change "empty" to mean "5 seconds", or write out a default value of 5 in /etc/config (if overriding to 'empty' should still mean 'don't automatically boot').

3hhh commented 1 year ago

So we could either change "empty" to mean "5 seconds"

Negative might mean infinite then. However IIRC bash uses 64 Bit Integers which should be sufficiently close to infinite for most users...

On a side note, I'd vote more for 3s than 5s as from my experience 3s is the usual maximum time frame I need to react to something on my screen, whereas 5s is long enough to get annoyed about the timeout. Anyway 5s is still way better than infinite imho. ;)

3hhh commented 8 months ago

Thanks for the implementation!

I can confirm that it works.

Tested version: ae9ed75bacbd977489992fc1ccd538b0fceb2163 heads-UNTESTED_t530-hotp-maximized-v0.2.0-1991-g90d1c2e.rom (https://github.com/linuxboot/heads/commit/90d1c2e9e30c7b2d56ff19970e14236fe3af2763)

JonathonHall-Purism commented 8 months ago

Cool, thanks for following up @3hhh !