Differences between revisions 15 and 18 (spanning 3 versions)
Revision 15 as of 2022-08-07 12:15:26
Size: 7022
Comment: Add more ways of checking SB status
Revision 18 as of 2022-08-14 09:25:09
Size: 7557
Comment: Some minor language fixes
Deletions are marked like this. Additions are marked like this.
Line 14: Line 14:
$ sudo apt-get install ovmf qemu-system-x86 $ sudo apt install ovmf qemu-system-x86 gpg debian-keyring
Line 23: Line 23:
Download some installation media which supports UEFI and SecureBoot, e.g. a [[https://www.debian.org/CD/netinst/|Debian network install AMD64 ISO]] image (check for the latest version [[https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/|here]]):
{{{
$ wget https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-11.4.0-amd64-netinst.iso
Download and verify some installation media which supports UEFI and SecureBoot, e.g. a [[https://www.debian.org/CD/netinst/|Debian network install AMD64 ISO]] image (check for the latest version [[https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/|here]]):

{{{
$ base=https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/
$ keyring=/usr/share/keyrings/debian-role-keys.gpg
$ wget $base/SHA512SUMS $base/SHA512SUMS.sign
$ mkdir ~/.gnupg ; chmod 7
00 ~/.gnupg
$ gpg --no-options --no-default-keyring --keyring $keyring --verify SHA512SUMS.sign SHA512SUMS
$ grep 'debian-[0-9.]*
-amd64-netinst.iso$' SHA512SUMS | tr -s ' ' | cut -d' ' -f2 | head -n1 | xargs -i wget -N -c "$base/{}"
$ sha512sum --check --ignore-missing --strict SHA512SUMS
$ rm -f SHA512SUMS*
Line 72: Line 80:
This script will automatically create a QEMU image (default: `test.img`) and create a local copy of the OVMF code section (which stores writeable UEFI variables). Additional parameters for QEMU can be passed to the script on execution. This script will automatically create a QEMU image (default: `test.img`) and create a local copy of the OVMF vars section (which stores writeable UEFI variables). Additional parameters for QEMU can be passed to the script on execution.
Line 76: Line 84:
$ ./start-vm -cdrom ./debian-11.4.0-amd64-netinst.iso -boot menu=on $ ./start-vm -cdrom ./debian-*-amd64-netinst.iso -boot menu=on
Line 108: Line 116:
This might be changed in the future, see [[https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1015759|#1015759]].
Line 155: Line 164:
For subsequent boots, the installation media and boot menu delay are no longer necessary, so simply launch the VM as follows (if not using DebPkg:virt-manager) as follows: For subsequent boots, the installation media and boot menu delay are no longer necessary, so simply launch the VM as follows (if not using DebPkg:virt-manager):

Introduction

These instructions let you setup a virtual machine setup based on KVM and Tianocore which has secure boot on. This setup already has Microsoft and distribution-specific keys built-in.

These instructions should be run as a normal user. We assume sudo has been installed and the user who runs the commands can use sudo to get root privileges.

Initial setup

Manual

Install ovmf and qemu-system-x86:

$ sudo apt install ovmf qemu-system-x86 gpg debian-keyring

Create a directory to store the virtual machine files:

$ mkdir ~/secureboot-vm
$ cd ~/secureboot-vm

Download and verify some installation media which supports UEFI and SecureBoot, e.g. a Debian network install AMD64 ISO image (check for the latest version here):

$ base=https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/
$ keyring=/usr/share/keyrings/debian-role-keys.gpg
$ wget $base/SHA512SUMS $base/SHA512SUMS.sign
$ mkdir ~/.gnupg ; chmod 700 ~/.gnupg
$ gpg --no-options --no-default-keyring --keyring $keyring --verify SHA512SUMS.sign SHA512SUMS
$ grep 'debian-[0-9.]*-amd64-netinst.iso$' SHA512SUMS | tr -s ' ' | cut -d' ' -f2 | head -n1 | xargs -i wget -N -c "$base/{}"
$ sha512sum --check --ignore-missing --strict SHA512SUMS
$ rm -f SHA512SUMS*

For convenience, create a script to launch the VM:

$ echo > start-vm <<EOF
#!/bin/bash

set -Eeuxo pipefail

MACHINE_NAME="test"
QEMU_IMG="${MACHINE_NAME}.img"
SSH_PORT="5555"
OVMF_CODE="/usr/share/OVMF/OVMF_CODE_4M.ms.fd"
OVMF_VARS_ORIG="/usr/share/OVMF/OVMF_VARS_4M.ms.fd"
OVMF_VARS="$(basename "${OVMF_VARS_ORIG}")"

if [ ! -e "${QEMU_IMG}" ]; then
        qemu-img create -f qcow2 "${QEMU_IMG}" 8G
fi

if [ ! -e "${OVMF_VARS}" ]; then
        cp "${OVMF_VARS_ORIG}" "${OVMF_VARS}"
fi

qemu-system-x86_64 \
        -enable-kvm \
        -cpu host -smp cores=4,threads=1 -m 4096 \
        -object rng-random,filename=/dev/urandom,id=rng0 \
        -device virtio-rng-pci,rng=rng0 \
        -name "${MACHINE_NAME}" \
        -drive file="${QEMU_IMG}",format=qcow2 \
        -net nic,model=virtio -net user,hostfwd=tcp::${SSH_PORT}-:22 \
        -vga virtio \
        -machine q35,smm=on \
        -global driver=cfi.pflash01,property=secure,value=on \
        -drive if=pflash,format=raw,unit=0,file="${OVMF_CODE}",readonly=on \
        -drive if=pflash,format=raw,unit=1,file="${OVMF_VARS}" \
        $@
EOF

And make it executable:

$ chmod a+x start-vm

This script will automatically create a QEMU image (default: test.img) and create a local copy of the OVMF vars section (which stores writeable UEFI variables). Additional parameters for QEMU can be passed to the script on execution.

Launch the VM for the first time, with the installation media:

$ ./start-vm -cdrom ./debian-*-amd64-netinst.iso -boot menu=on

Explanation

The last five lines of the qemu-system-x86_64 invocation are the important ones:

  • -vga virtio - The Debian installer seems to have difficulties working with the standard VGA driver (and virtio should anyway have better performance)

  • -machine q35,smm=on - A machine type which supports SecureBoot

  • -global driver=cfi.pflash01,property=secure,value=on - Add a driver for virtual pflash drives containing the firmware

  • -drive if=pflash,format=raw,unit=0,file="${OVMF_CODE}",readonly=on - Create a readonly pflash drive containing the firmware

  • -drive if=pflash,format=raw,unit=1,file="${OVMF_VARS}" - Create a writeable pflash drive for storage of firmware variables

Passing -boot menu=on to qemu-system-x86_64 means that you will have more time to press ESC during boot to enter the UEFI menu.

Using if=virtio for the first drive stanza should have better performance, but it means that it won't be recognised by the UEFI firmware (it can be enabled after a system has been installed).

Once installed, you'll be able to SSH to the virtual machine by connecting to localhost, port 5555 (e.g. ssh -p5555 user@localhost).

Of course, the start-vm script above is just an example and can be adapted to suit your own needs.

Alternatively: using virt-manager

It is really easy to activate secure boot by using virt-manager, ovmf and qemu-system-x86:

  1. Choose Customize configuration before install
    http://34.83.134.122/virt-manager1.png

  2. Choose Q35 as Chipset and OVMF_CODE_4M.ms.fd as Firmware
    http://34.83.134.122/virt-manager2.png

  3. That's all!

Change the boot order

For ovmf, it is usually necessary to change the boot order because the UEFI shell has the highest boot priority (set in OVMF_VARS*.ms.fd). This might be changed in the future, see #1015759.

Press <ESC> when the machine boots and you should see a menu like this:

  Select Language: <Standard English>

▶ Device Manager
▶ Boot Manager
▶ Boot Maintenance Manager

  Continue
  Reset

Tip

Secure boot settings, including the ability to enable/disable secure boot, can be found under Device ManagerSecure Boot Configuration.

Navigate through the UEFI menus Boot Maintenance ManagerBoot OptionsChange Boot Order.

Next, you will see a list like this (the exact number and order of the items may vary):

<UEFI QEMU HARDDISK QM00001>
<EFI Internal Shell>
<UEFI QEMU DVD-ROM QM00005>
<UEFI PXEv4 (MAC:...)>
<UEFI PXEv4 (MAC:...) 2>
<UEFI PXEv6 (MAC:...)>
<UEFI HTTPv4 (MAC:...)>
<UEFI HTTPv6 (MAC:...)>

Press <enter> and use + and - to change the order of the entries so that the hard disk is first and the DVD entry is second:

<UEFI QEMU HARDDISK QM00001>
<UEFI QEMU DVD-ROM QM00005>
<EFI Internal Shell>
...

Press <enter> when finished, then <F10>, confirm with <y>, then press <ESC> until you are back at the main menu and select Continue.

The Debian netinst image should load and launch the DebianInstaller. Proceed to install your system as usual.

Subsequent boots

For subsequent boots, the installation media and boot menu delay are no longer necessary, so simply launch the VM as follows (if not using virt-manager):

$ cd ~/secureboot-vm
$ ./start-vm

Checking if secure boot is active

mokutil

You can check if secure boot is enabled (with root access) using mokutil:

$ mokutil --sb-state
SecureBoot enabled

bootctl

You can also check if secure boot is enabled by using bootctl:

$ sudo bootctl
systemd-boot not installed in ESP.
No default/fallback boot loader installed in ESP.
System:
     Firmware: n/a (n/a)
  Secure Boot: enabled
...

dmesg

When Linux has been booted with secure boot, dmesg should print:

secureboot: Secure boot enabled
Kernel is locked down from EFI Secure Boot mode

Otherwise secure boot is not activated.

Useful links