Differences between revisions 13 and 14
Revision 13 as of 2020-11-13 02:27:26
Size: 7747
Comment: Buster -> Bullseye
Revision 14 as of 2022-08-07 11:03:43
Size: 6842
Comment: Rewrite, simplify, modernise, remove outdated information
Deletions are marked like this. Additions are marked like this.
Line 4: Line 4:
These instructions let you setup a virtual machine setup based on KVM and Tianocore which has secure boot on.
This setup has already Microsoft keys built-in and probably the Redhat ones.
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.
Line 9: Line 8:
= Requirements =
 * VT-Technology or AMD-V (virtualization) turned on on your computer
 * Debian Buster 10 amd64 installation booted from an 64-bit kernel
 * Recently the above became unnecessary. I am able to boot Debian Bullseye amd64 guest with secure boot on Debian Bullseye arm64 host. Although arm64 also has KVM acceleration, KVM is unavailable for amd64 guest on arm64 host.
= Initial setup =
Line 14: Line 10:
= Initial UEFI Setup = == Manual ==
Line 16: Line 12:
We will use separate OVMF_CODE.fd an OVMF_VARS.fd files
so that each virtual machine can have its own UEFI variables

Install kvm if we have not yet and ovmf (ovmf is not strictly needed, see [[#TO DO]] below).
Install DebPkg:ovmf and DebPkg:qemu-system-x86:
Line 21: Line 14:
sudo apt-get install qemu-kvm ovmf $ sudo apt-get install ovmf qemu-system-x86
Line 24: Line 17:
Create our virtual machine directory where its associated files live. Create a directory to store the virtual machine files:
Line 26: Line 19:
mkdir ~/gnu/secureboot-vm
cd ~/gnu/secureboot-vm
$ mkdir ~/secureboot-vm
$ cd ~/secureboot-vm
Line 30: Line 23:
= Get secureboot firmware from Fedora =
/!\ '''This is not needed any more: DebPkg:ovmf 0~20191122.bd85bf54-1 contains {{{OVMF_CODE.secboot.fd}}} and {{{OVMF_VARS.ms.fd}}}.'''

Note that there are three differences between Fedora 33's package and DebPkg:ovmf 2020.08-1

 * i386 OVMF exists in Fedora 33's edk2-ovmf-ia32 but Debian doesn't have it DebianBug:842683
 * Fedora 33's OVMF_CODE.secboot.fd supports S3 suspend and resume, but Debian doesn't DebianBug:973783 As such, Debian requires to add -global ICH9-LPC.disable_s3=1 to qemu-system-x86_64.
 * Debian's OVMF_VARS.ms.fd has the highest boot priority of UEFI shell, and UEFI shell is always booted regardless of hardware configuration. Fedora 33's OVMF doesn't have such an inconvenient feature.

First of all we get rpm package so that we can extract its contents.
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]]):
Line 41: Line 25:
sudo apt-get install rpm $ wget https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-11.4.0-amd64-netinst.iso
Line 44: Line 28:
We will create and use a temporary directory so that we don't mess too much our system. For convenience, create a script to launch the VM:
Line 46: Line 30:
mkdir tmp-fedora-rpm
cd tmp-fedora-rpm
$ 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
Line 50: Line 67:
We are interested on the Fedora's secboot version of the OVMF_CODE and OVMF_VARS fd files. So that we don't have to add secure boot keys manually. And make it executable:
Line 52: Line 69:
wget "https://download-ib01.fedoraproject.org/pub/fedora-secondary/updates/30/Everything/i386/Packages/e/edk2-ovmf-20190501stable-2.fc30.noarch.rpm"
rpm2cpio edk2-ovmf-20190501stable-2.fc30.noarch.rpm | cpio -idmv
cp ./usr/share/OVMF/UefiShell.iso ../
cp ./usr/share/edk2/ovmf/OVMF_CODE.secboot.fd ../OVMF_CODE.fd
cp ./usr/share/edk2/ovmf/OVMF_VARS.secboot.fd ../OVMF_VARS.fd
$ chmod a+x start-vm
Line 59: Line 72:
Now we can remove temporary stuff. 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.

Launch the VM for the first time, with the installation media:
Line 61: Line 76:
cd ..
rm -rf tmp-fedora-rpm
$ ./start-vm -cdrom ./debian-11.4.0-amd64-netinst.iso -boot menu=on
Line 65: Line 79:
= Updates on November 2020 (Debian Bullseye is assumed) =
== Seeing if secure boot is active ==
== Explanation ==
Line 68: Line 81:
When recent Linux ('''including Debian Buster's 4.19''') is booted with the secure boot, dmesg should print 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 DebPkg:virt-manager, DebPkg:ovmf and DebPkg:qemu-system-x86:

 1. Choose ''Customize configuration before install'' <<BR>> {{http://34.83.134.122/virt-manager1.png}}
 2. Choose ''Q35'' as Chipset and ''OVMF_CODE_4M.ms.fd'' as Firmware <<BR>> {{http://34.83.134.122/virt-manager2.png}}
 3. That's all!

== Change the boot order ==

For DebPkg: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`).

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
}}}

{{{#!wiki tip
'''Tip'''

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

Navigate through the UEFI menus `Boot Maintenance Manager` ⭢ `Boot Options` ⭢ `Change 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 DebPkg:virt-manager) as follows:
{{{
$ cd ~/secureboot-vm
$ ./start-vm
}}}

= Checking if secure boot is active =

When Linux has been booted with secure boot, ``dmesg`` should print:
Line 73: Line 168:
Otherwise the secure boot is not activated.
Line 75: Line 169:
== Change of the boot order == Otherwise secure boot is not activated.
Line 77: Line 171:
Recent Fedora RPM package does not need the change of boot order described below. For DebPkg:ovmf 2020.08-1, the change of boot order is usually necessary because the UEFI shell has the highest boot priority in `OVMF_VARS*.ms.fd`.

== QEMU options to activate secure boot ==

Start `qemu-system-x86_64` or `qemu-system-i386` with ''-machine q35,smm=on -global driver=cfi.pflash01,property=secure,value=on -drive if=pflash,format=raw,unit=0,file=OVMF_CODE.secboot.fd,readonly=on -drive if=pflash,format=raw,unit=1,file=copy_of_OVMF_VARS.secboot.fd''. Note that `OVMF*.ms.fd` in DebPkg:ovmf 2020.08-1 does not work with the above options due to DebianBug:973783

= Test a virtual machine and change its boot order =

In this case we want to test a raw image as the main hard disk with this filename:
''
/home/rescatuxs/super_grub2_disk_hybrid_secureboot_usb_2.04s2-beta1.img
''
.
You can also check if secure boot is enabled by using ``bootctl``:
Line 92: Line 173:
sudo kvm \
 -m 2048 \
 --machine pc-q35-2.5 \
 -drive if=pflash,format=raw,readonly,file=./OVMF_CODE.fd \
 -drive if=pflash,format=raw,file=./OVMF_VARS.fd \
 -drive file=/home/rescatuxs/super_grub2_disk_hybrid_secureboot_usb_2.04s2-beta1.img,format=raw,index=0,media=disk \
 -boot menu=on
$ 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
...
Line 100: Line 181:

Press ESC when the machine boots and you see:
''Start boot option''
at the bottom.

Choose the following options from the UEFI menus:
 * Boot Maintenance Manager
 * Boot Options
 * Change Boot Order
Press Enter

What you get is:
{{{
UEFI QEMU DVD-ROM
UEFI PXEv4
UEFI PXEv4
UEFI PXEv6
UEFI QEMU HARDDISK QM00001
}}}

Now, we will change the list into this order:
{{{
UEFI QEMU DVD-ROM
UEFI QEMU HARDDISK QM00001
UEFI PXEv4
UEFI PXEv4
UEFI PXEv6
}}}
.

That way we avoid having to wait for the different UEFI PXE entries to timeout.

Press enter when finished.
Commit Changes and Exit
Press ESC till you get out of the BIOS.


= Test a virtual machine =

{{{
sudo kvm \
 -m 2048 \
 --machine pc-q35-2.5 \
 -drive if=pflash,format=raw,readonly,file=./OVMF_CODE.fd \
 -drive if=pflash,format=raw,file=./OVMF_VARS.fd \
 -drive file=/home/rescatuxs/super_grub2_disk_hybrid_secureboot_usb_2.04s2-beta1.img,format=raw,index=0,media=disk \
 -boot menu=on
}}}

= What you get =

You should be able to boot secure boot enabled cdrom or hard disk images.
If any of these images are not properly signed by the Microsoft or Redhat keys then they will fail to boot.

The read only firmware for your virtual machine is located at:
''
~/gnu/secureboot-vm/OVMF_CODE.fd
''
.

The read and write state of your UEFI variables for that specific virtual machine is located at:
''
~/gnu/secureboot-vm/OVMF_VARS.fd
''
.
= Notes =
 * Apparently ''pc-q35-2.5'' qemu machine type is needed so that secureboot works or, at least, shows a graphical output.

= virt-manager =
--(I prefer using qemu or kvm rather than relying on virt-manager or another GUI. If you manage to adapt these instructions to virt-manager please write another page and link to it from this one.)--
It is really easy to activate secure boot by DebPkg:virt-manager 1:3.1.0-1, DebPkg:ovmf 2020.08-1 and DebPkg:qemu-system-x86 1:5.1-dfsg-4+b1.

 1. Choose ''Customize configuration before install'' as <<BR>> {{http://34.83.134.122/virt-manager1.png}}
 2. Choose ''Q35'' as Chipset and ''OVMF_CODE_4M.ms.fd'' as Firmware as <<BR>> {{http://34.83.134.122/virt-manager2.png}}
 3. '''That's all!'''
Line 178: Line 184:
 * https://wiki.archlinux.org/title/QEMU
Line 182: Line 189:

= TO DO =

== Debian only method with secureboot images ==
The Debian DebPkg:ovmf package provides:
 * OVMF_CODE.secboot.fd
 * OVMF_VARS.ms.fd
Just install the Debian DebPkg:ovmf package and use these files instead.

== Debian only method with UefiShell.iso from Fedora ==

If someone else manages to use default Debian files:
 * /usr/share/OVMF/OVMF_CODE.fd
 * /usr/share/OVMF/OVMF_VARS.fd
with the UefiShell.iso file from Fedora's edk2-ovmf package so that you can turn on a non secure boot vm to a secure boot one manually. Please update this page. I prefer doing that step manually than relying on:
 * OVMF_CODE.secboot.fd
 * OVMF_VARS.secboot.fd
which have those keys embedded.



= Thank you =

Thanks to the people from #debian-efi channel on OFTC for their patience because I usually make too many questions there.

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-get install ovmf qemu-system-x86

Create a directory to store the virtual machine files:

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

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

$ wget https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-11.4.0-amd64-netinst.iso

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 code 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-11.4.0-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).

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) as follows:

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

Checking if secure boot is active

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.

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
...

Useful links