Secure Boot

From NixOS Wiki
Revision as of 12:38, 1 October 2023 by imported>IgorM (Fixed syntax highlighting)

Secure Boot can be enabled on NixOS using the project Lanzaboote. Secure Boot is a UEFI feature that only allows trusted operating systems to boot. Lanzaboote has two components: lzbt and stub. lzbt signs and installs the boot files on the ESP. stub is a UEFI application that loads the kernel and initrd from the ESP.

Warning: Lanzaboote is still in development and requires some prerequisites and precautions. Currently it's only available for nixos-unstable. For more information, please see the GitHub repository or the Quick Start guide.

Requirements

The Secure Boot implementation of Lanzaboote requires a system installed in UEFI mode together with systemd-boot enabled. This can be checked by running bootctl status:

$ bootctl status
System:
     Firmware: UEFI 2.70 (Lenovo 0.4720)
  Secure Boot: disabled (disabled)
 TPM2 Support: yes
 Boot into FW: supported

Current Boot Loader:
      Product: systemd-boot 251.7
...

It is recommended to enable a BIOS password and full disc encryption to prevent attacks against UEFI and Secure Boot.

Setup

First generate Secure Boot keys using sbctl:

 $ sudo nix run nixpkgs#sbctl create-keys

After that switch from lzbt to bootspec by adding following line to the system configuration:

 
/etc/nixos/configuration.nix
boot.bootspec.enable = true;

Rebuild the system and reboot. When everything is working, you can garbage collect your old non-bootspec generations:

$ sudo nix-collect-garbage -d.

Adjust the following in your flake-enabled system flake.nix configuration by adding the input and adding the lanzaboote nixos module:

 
/etc/nixos/flake.nix
[...]
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    lanzaboote.url = "github:nix-community/lanzaboote";
  };
[...]
  outputs = { self, nixpkgs, lanzaboote, ...}: {
    nixosConfigurations = {
      yourHost = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";

        modules = [
          # This is not a complete NixOS configuration and you need to reference
          # your normal configuration here.

          lanzaboote.nixosModules.lanzaboote
[...]

In your system configuration explicitly disable systemd-boot and replace it by enabling lanzaboote:

 
/etc/nixos/configuration.nix
boot = {
  loader.systemd-boot.enable = lib.mkForce false;
  lanzaboote = {
    enable = true;
    pkiBundle = "/etc/secureboot";
  };
};

After you rebuild your system, check sbctl verify output:

$ sudo nix run nixpkgs#sbctl verify
Verifying file database and EFI images in /boot...
✓ /boot/EFI/BOOT/BOOTX64.EFI is signed
✓ /boot/EFI/Linux/nixos-generation-355.efi is signed
✓ /boot/EFI/Linux/nixos-generation-356.efi is signed
✗ /boot/EFI/nixos/0n01vj3mq06pc31i2yhxndvhv4kwl2vp-linux-6.1.3-bzImage.efi is not signed
✓ /boot/EFI/systemd/systemd-bootx64.efi is signed

It is expected that the files ending with bzImage.efi are not signed.

For the last step, your UEFI firmware needs to be set to Setup Mode to allow enrolling Secure Boot keys. This varies depending on your vendor and notebookt model.

On a Thinkpad enter the BIOS menu using the "Reboot into Firmware" entry in the systemd-boot boot menu. Once you are in the BIOS menu:

1) Select the "Security" tab.
2) Select the "Secure Boot" entry.
3) Set "Secure Boot" to enabled.
4) Select "Reset to Setup Mode".
5) Select "Clear All Secure Boot Keys".

When you are done, press F10 to save and exit.

After reboot enroll your keys to enable Secure Boot. Microsoft keys are used to avoid any booting issues.

$ sudo nix run nixpkgs#sbctl enroll-keys -- --microsoft
Enrolling keys to EFI variables...
With vendor keys from microsoft...✓
Enrolled keys to the EFI variables!

You can now reboot your system. After you've booted, Secure Boot is activated:

$ bootctl status
System:
      Firmware: UEFI 2.70 (Lenovo 0.4720)
 Firmware Arch: x64
   Secure Boot: enabled (user)
  TPM2 Support: yes
  Boot into FW: supported