Difference between revisions of "Secure Boot"

From Funtoo
Jump to navigation Jump to search
(Created page with "= Introduction = This page describes how to set up secure boot on Funtoo Linux with and without GRUB 2, using genkernel and boot-update. The resulting secure boot chain is:...")
 
m
Line 118: Line 118:
}}
}}


Set the value of {{c|Built-in kernel command string}} to the current kernel command line (from {{c|/proc/cmdline}}, but delete the {{c|rand_id}} parameter.  (After you run {{c|boot-update}}, the random id for the new kernel will appear in {{c|/etc/boot.d/config/kernel/random.map}}.)
Set the value of {{c|Built-in kernel command string}} to the current kernel command line (from {{c|/proc/cmdline}}), but delete the {{c|rand_id}} parameter.  (After you run {{c|boot-update}}, the random id for the new kernel will appear in {{c|/etc/boot.d/config/kernel/random.map}}.)


{{kernelop|title=Device Drivers,Graphics support,Frame buffer Devices,Support for frame buffer devices|desc=
{{kernelop|title=Device Drivers,Graphics support,Frame buffer Devices,Support for frame buffer devices|desc=

Revision as of 03:32, January 2, 2019

Introduction

This page describes how to set up secure boot on Funtoo Linux with and without GRUB 2, using genkernel and boot-update. The resulting secure boot chain is:

  • The firmware (BIOS) setup is password protected
  • The firmware has UEFI secure boot certificates installed, and you hold the corresponding private keys
  • GRUB is signed by a key registered in the UEFI secure boot signature database
  • The GRUB image has a public PGP key, for which you hold the private key
  • GRUB config file, kernels and initramfs images are signed with the GRUB PGP key
  • GRUB requires a password to do anything besides booting, e.g., to edit boot parameters or to use the command line
   Note

Many Linux secure boot guides on the Net recommend using Fedora's "shim" boot loader. I would not recommend it, for the following reasons:

  • Shim only checks signatures of the boot loader and kernel, but not the GRUB config file or initramfs, which opens your machine to attacks
  • At the time of writing (early 2019), GRUB's shim support (needed to check kernels) has been committed to the GRUB repository but is not yet in any released version
  • I don't understand the point of MOKs and am not certain about their security model

That said, shim may be useful if your machine doesn't allow you to install your own secure boot certificates.

Prerequisites

This guide assumes that:

  • your machine's firmware allows you to install your own secure boot certificates
  • you have a working Funtoo installation
  • you are using the GRUB 2 bootloader installed on the EFI boot partition
  • the boot partition is mounted on /boot
  • the EFI boot partition is separate and is mounted on /boot/efi

It is highly recommended that you use full disk encryption.

Generating and Installing Secure Boot Certificates

Enter the firmware setup utility and put secure boot in setup mode.

Install efitools and sbsigntools:

root # emerge -av app-crypt/efitools app-crypt/sbsigntools

Decide where you want to keep your keys. If you want to keep them on an eternal drive, be aware that gpg creates a socket for gpg-agent in its config directory, so it should reside on a filesystem that supports sockets (i.e., not FAT) and be mounted read-write for signing.

Save old secure boot certificates:

root # efi-readvar -v PK  -o old_PK.esl
root # efi-readvar -v KEK -o old_KEK.esl
root # efi-readvar -v db  -o old_db.esl
root # efi-readvar -v dbx -o old_dbx.esl

Generate new certificates valid for 27 years:

root # openssl req -new -x509 -newkey rsa:2048 -subj "/CN=PK/"  -keyout PK.key  -out PK.crt  -days 10000 -nodes -sha256
root # openssl req -new -x509 -newkey rsa:2048 -subj "/CN=KEK/" -keyout KEK.key -out KEK.crt -days 10000 -nodes -sha256
root # openssl req -new -x509 -newkey rsa:2048 -subj "/CN=db/"  -keyout db.key  -out db.crt  -days 10000 -nodes -sha256

Prepare certificate lists:

root # cert-to-efi-sig-list PK.crt  PK.esl
root # cert-to-efi-sig-list KEK.crt KEK.esl
root # cert-to-efi-sig-list db.crt  db.esl

If you want to dual boot preinstalled OSes, add old KEK and db certificates to the new lists:

root # cat old_KEK.esl >>KEK.esl
root # cat old_db.esl  >>db.esl

Sign the certificate lists:

root # sign-efi-sig-list -k PK.key  -c PK.crt  PK  PK.esl      PK.auth
root # sign-efi-sig-list -k PK.key  -c PK.crt  KEK KEK.esl     KEK.auth
root # sign-efi-sig-list -k KEK.key -c KEK.crt db  db.esl      db.auth
root # sign-efi-sig-list -k KEK.key -c KEK.crt dbx old_dbx.esl old_dbx.auth

Remount the efivars partition read-write:

root # mount -o remount,rw /sys/firmware/efi/efivars

Install the certificates into EFI:

root # efi-updatevar -f old_dbx.esl dbx 
root # efi-updatevar -f db.auth     db
root # efi-updatevar -f KEK.auth    KEK
root # efi-updatevar -f PK.auth     PK

Create a Rescue Kernel (Optional)

Before you start playing with GRUB, it's a good idea to prepare a kernel that is bootable directly from EFI.

Enable the following kernel configuration variables:

   
CONFIG_EFI_STUB=y
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="..."
CONFIG_CMDLINE_OVERRIDE=y
CONFIG_FB_SIMPLE=y

Under Processor type and features:

[*] EFI runtime service support
[*]   EFI stub support
[*] Built-in kernel command line
(...) Built-in kernel command string
[*]   Built-in command line overrides boot loader arguments

Set the value of Built-in kernel command string to the current kernel command line (from /proc/cmdline), but delete the rand_id parameter. (After you run boot-update, the random id for the new kernel will appear in /etc/boot.d/config/kernel/random.map.)

Under Device Drivers-->Graphics support-->Frame buffer Devices-->Support for frame buffer devices:

[*]   Simple framebuffer support

If you have early microcode, extract it to a temporary location:

root # mount /boot
root # mkdir /tmp/early
root # cd /tmp/early
root # cpio -i </boot/early_ucode.cpio

Compile and install the kernel with integrated initramfs. This command will further modify the kernel config file.

root # genkernel --no-clean --no-save-config --integrated-initramfs --initramfs-overlay=/tmp/early --fullname=rescue all

Sign the kernel with the secure boot key and copy it to the EFI partition:

root # sbsign --key /path/to/db.key --cert /path/to/db.crt -o /boot/kernel-rescue /boot/kernel-rescue
root # mount /boot/efi
root # cp /boot/kernel-rescue /boot/efi/EFI/Funtoo\ Linux\ \[GRUB\]/rescue.efi

Add the kernel to the EFI boot order. Replace EFIBOOTDEVICE below with the device mounted on /boot/efi.

root # efibootmgr -c -l '\EFI\Funtoo Linux [GRUB]\rescue.efi' -L 'Funtoo Linux [Rescue Kernel]' -d /dev/EFIBOOTDEVICE

Shutdown, enter the firmware setup, enable secure boot and boot using the rescue kernel to make sure that it works.

   Note

In fact, you can use the scheme above to install new kernels and forego GRUB entirely. The downside is that you won't be able to use the command line, e.g., to enter the single user mode, in case anything goes wrong.

Installing GRUB

   Warning

Work in progress

Generate a PGP key pair:

root # TODO

Create the initial GRUB config file which will be embedded into the GRUB image:

   grub-initial.cfg - Initial GRUB config
if loadfont /grub/fonts/unicode.pf2; then
   set gfxmode=800x600
   terminal_output gfxterm
fi

set superusers="root"
export superusers
password_pbkdf2 root grub.pbkdf2.sha512.10000.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

set root=ROOTDISK
search --no-floppy --fs-uuid --set FSUUID
configfile /grub/grub.cfg

echo grub.cfg did not boot the system but returned to initial.cfg.
echo Exiting in 10 seconds.
sleep 10
exit

You will have to edit the config file in three places:

  1. Use grub-mkpasswd-pbkdf2 to generate a password hash to replace the zeroes.
  2. Replace ROOTDISK with the value of the root variable from /boot/grub/grub.cfg.
  3. Replace FSUUID with the filesystem UUID from a search line in /boot/grub/grub.cfg.

Mount /boot and /boot/efi:

root # mount /boot
root # mount /boot/efi

Make a standalone GRUB image:

root # grub-mkimage -O x86_64-efi -p "ROOTDISK/grub" -c /path/to/grub-initial.cfg -k /path/to/grub.pub -o "/boot/efi/EFI/Funtoo Linux [GRUB]/grubx64.efi" configfile loadenv part_gpt ext2 linux gcry_rsa gcry_sha256 password_pbkdf2 all_video gfxterm videoinfo search minicmd test echo reboot sleep
root ## sbsign --key /path/to/db.key --cert /path/to/db.crt -o "/boot/efi/EFI/Funtoo Linux [GRUB]/grubx64.efi" "/boot/efi/EFI/Funtoo Linux [GRUB]/grubx64.efi"

See Also

Secure Boot with GRUB 2 and signed Linux images and initrds