- How to boot Linux using UEFI with Secure Boot ?¶
- References¶
- Contents¶
- Prerequisite¶
- Dependencies¶
- Check Secure Boot status¶
- Backup existing certificates from the UEFI¶
- Write your own certificates¶
- Sign your own grub / kernel / initrd¶
- Update UEFI keystore with our own keys¶
- Entering setup mode (clearing keystore)¶
- Installing new keys into the keystore¶
- Sign your grub bootloader¶
- Sign your kernel¶
- Sign your initrd¶
- GRUB only load signed kernel¶
- Add a password protection to GRUB¶
- Testing phase¶
- Conclusion¶
- Annexes¶
- A) Install sbsigntools and efitools¶
How to boot Linux using UEFI with Secure Boot ?¶
In this tutorial, we will describe every steps to secure the boot of Linux on a PC. We will learn to backup existing certificates from the UEFI and write our own certificates. Moreover, you will also see how to sign our grub bootloader, kernel and initrd. Then, you will be able to configure the grub configuration file in order to only load signed kernel and initrd. Finally, we will protect the grub configuration file.
Here, I will be using a Centos 7 distribution, if you are using another check the documentation of your distribution for any problem or further information.
References¶
- For an overview of Secure Boot on Linux check Rodsbooks article.
- For further information check ArchLinux documentation on Secure Boot.
- For an EFI installation guide and how configure the Secure Boot check Gentoo documentation.
Contents¶
- Check Secure Boot status.
- Backup existing certificates from the UEFI.
- Write your own certificates.
- Sign your own grub / kernel / initrd.
- Configure your grub.cfg to only load signed kernel and initrd.
- Add a password protection to GRUB2.
- Annexes :
- A) Install sbsigntools and efitools on CentOS.
Prerequisite¶
- A Linux distribution installed and booting with UEFI on a PC.
- Disable Secure Boot in your BIOS.
You can also use a Virtual Environment following this tutorial.
Dependencies¶
If you are using Centos 7 distribution, check how to install them in Annexe A.
Check Secure Boot status¶
To verify if your computer has booted with Secure Boot, type the following command :
In order to start this tutorial you need to have it disabled. If it is not go to your BIOS and disable it.
Backup existing certificates from the UEFI¶
In this section, we will backup the public keys / certificates from the UEFI keystore :
- The Platform Key (PK) is a variable where the public key given by the hardware vendor (ex : Dell, HP, Asus, . ) is stored.
- The Key Exchange Key (KEK) is a variable which can contains one or more public keys. Usually, Microsoft store his public key here.
- The Database (db) is a variable containing a signature database commonly filled with public keys. It is used as a boot executable whitelist.
- The Database Blacklist (dbx) is a variable similar to the db, but it contains the boot executable blacklist, also called «revoked keys/signatures».
Thoose variables are used to control the Secure Boot process.
- Prepare the backup directory and give it only root access :
$ mkdir -p secu-os/backup $ chmod -v 700 secu-os/ $ cd secu-os/backup/
$ efi-readvar -v PK -o old_PK.esl $ efi-readvar -v KEK -o old_KEK.esl $ efi-readvar -v db -o old_db.esl $ efi-readvar -v dbx -o old_dbx.esl
Write your own certificates¶
Now we will create a new PK, KEK and kernel-signing keypair (db) with openssl .
- X.509 certificate format for the public key.
- RSA asymmetric cryptosystem, with a 2048 bit key length.
- Have 10 years (3650 days) to run until expiry.
- Use SHA-256 as the public key’s message digest.
$ cd secu-os/ $ mkdir efikeys $ cd efikeys/
$ openssl req -new -x509 -newkey rsa:2048 -subj "/CN=tutorial's platform key/" -keyout PK.key -out PK.crt -days 3650 -nodes -sha256 $ openssl req -new -x509 -newkey rsa:2048 -subj "/CN=tutorial's key-exchange-key/" -keyout KEK.key -out KEK.crt -days 3650 -nodes -sha256 $ openssl req -new -x509 -newkey rsa:2048 -subj "/CN=tutorial's kernel-signing key/" -keyout db.key -out db.crt -days 3650 -nodes -sha256
Sign your own grub / kernel / initrd¶
Update UEFI keystore with our own keys¶
Before signing our grub, kernel or initrd, we need to update the UEFI keystore variables with the keys that we have just created.
Some informations about keys format (source):
- .key PEM format private keys for EFI binary and EFI signature list signing.
- .crt PEM format certificates for sbsign.
- .cer DER format certificates for firmware.
- .esl Certificates in EFI Signature List for KeyTool and/or firmware.
- .auth Certificates in EFI Signature List with authentication header (i.e. a signed certificate update file) for KeyTool and/or firmware.
$ cd secu-os/efikeys/ $ uuidgen --random > GUID.txt
$ cert-to-efi-sig-list -g "$(< GUID.txt)" PK.crt PK.esl $ sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt PK PK.esl PK.auth
$ cert-to-efi-sig-list -g "$(< GUID.txt)" KEK.crt KEK.esl $ sign-efi-sig-list -g "$(< GUID.txt)" -a -k PK.key -c PK.crt KEK KEK.esl KEK.auth
$ cert-to-efi-sig-list -g "$(< GUID.txt)" db.crt db.esl $ sign-efi-sig-list -g "$(< GUID.txt)" -a -k KEK.key -c KEK.crt db db.esl db.auth
$ sign-efi-sig-list -k KEK.key -c KEK.crt dbx ../backup/old_dbx.esl old_dbx.auth
$ openssl x509 -outform DER -in PK.crt -out PK.cer $ openssl x509 -outform DER -in KEK.crt -out KEK.cer $ openssl x509 -outform DER -in db.crt -out db.cer
$ cat old_KEK.esl KEK.esl > compound_KEK.esl $ cat old_db.esl db.esl > compound_db.esl $ sign-efi-sig-list -k PK.key -c PK.crt KEK compound_KEK.esl compound_KEK.auth $ sign-efi-sig-list -k KEK.key -c KEK.crt db compound_db.esl compound_db.auth
Entering setup mode (clearing keystore)¶
Note : in some computers you will have to enable custom keys in your BIOS.
Installing new keys into the keystore¶
Variable PK has no entries Variable KEK has no entries Variable db has no entries Variable dbx has no entries
$ cd secu-os/efikeys/ $ efi-updatevar -e -f ../backup/old_dbx.esl dbx $ efi-updatevar -e -f db.esl db $ efi-updatevar -e -f KEK.esl KEK $ efi-updatevar -f PK.esl PK
$ cd ../backup/ $ efi-readvar -v PK -o new_PK.esl $ efi-readvar -v KEK -o new_KEK.esl $ efi-readvar -v db -o new_db.esl $ efi-readvar -v dbx -o new_dbx.esl
Sign your grub bootloader¶
$ su root $ cd secu-os/backup/ $ cp /boot/efi/EFI/centos/grubx64.efi grubx64.efi.bak
$ cd secu-os/efikeys/ $ sbsign --key db.key --cert db.crt --output /boot/efi/EFI/centos/grubx64.efi /boot/efi/EFI/centos/grubx64.efi
Sign your kernel¶
$ su root $ cd secu-os/backup/ $ cp /boot/vmlinuz-xxx vmlinuz-xxx.bak
$ cd secu-os/efikeys/ $ sbsign --key db.key --cert db.crt --output /boot/vmlinuz-xxx /boot/vmlinuz-xxx
Sign your initrd¶
$ su root $ cd secu-os/backup/ $ cp /boot/initramfs-xxx initramfs-xxx.bak
$ gpg --default-key GPG.key --detach-sign /boot/initramfs-xxx.img
GRUB only load signed kernel¶
$ su root $ cd secu-os/backup/ $ cp /boot/efi/EFI/centos/grub.cfg grub.cfg.bak
set check_signatures=enfore export check_signatures
Add a password protection to GRUB¶
To install password to «add» a little security on Grub2, you need to execute this command to set a new password :
After that, in the «grub.cfg» file, you have to prevent «bypass» of password by removing all arguments «—unrestricted».
It has at least two ways to bypass Grub2 password for use of unsigned load :
- Accessing the grub.cfg file by UEFI Shell and add argument/option «—unrestricted» will disable password protection.
- Or delete the file «user.cfg» (on the same directory of «grub.cfg» by accessing UEFI Shell.
Warning : you need to be aware that all manual modification (like manual password configuration or signatures check) in grub.cfg will be erase by an update of grub for example with this command :
$ grub2-mkconfig -o /boot/grub2/grub.cfg
I advise you to do all modification like setting password directly in one of the configuration files used to build «grub.cfg». These files can be found in /etc/grub.d.
For example, you can set in file «01_users» :
#!/bin/sh -e cat set superusers="root" password_pbkdf2 root "Your SHA password here" set check-signatures = enforce EOF
Like that, each time your «grub.cfg» will be regenerate, your changes will always be present to the grub configuration
Testing phase¶
Work In Progress
Conclusion¶
If you think that with the features we have done you have completly secure the boot process, then you are wrong. We just add some difficulties to break it and we will see in other articles ahow to add more protection by for example protect the grub.cfg file.
Annexes¶
A) Install sbsigntools and efitools¶
$ cd secu-os/install/ $ git clone https://git.kernel.org/pub/scm/linux/kernel/git/jejb/sbsigntools.git $ git clone https://git.kernel.org/pub/scm/linux/kernel/git/jejb/efitools.git
$ cd sbsigntools/ $ ./autogen.sh $ ./configure $ make check $ make install $ make installcheck $ cd ../efitools/ $ make $ make install
© Copyright 2019. Jerome Blanchard, Romain Brenaget and Pierre Fontaine