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


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=
$ 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:

$ cat > start-vm <<\EOF

set -Eeuxo pipefail

OVMF_VARS="$(basename "${OVMF_VARS_ORIG}")"

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

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

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

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


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

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

  2. Choose Q35 as Chipset and as Firmware

  3. That's all!

Change the boot order

For ovmf, it used to be necessary to change the boot order because the UEFI shell had the highest boot priority (set in OVMF_VARS*.ms.fd), 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



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

<EFI Internal Shell>
<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:

<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


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

$ mokutil --sb-state
SecureBoot enabled


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.
     Firmware: n/a (n/a)
  Secure Boot: enabled


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