Testing secureboot with KVM

From FedoraProject

(Difference between revisions)
Jump to: navigation, search
m (Fix a link)
 
(2 intermediate revisions by 2 users not shown)
Line 2: Line 2:
 
= Testing secureboot with KVM =
 
= Testing secureboot with KVM =
  
This page documents how to test Fedora 18 [[Secureboot]] support inside
+
This page documents how to test Fedora 18+ [[Secureboot]] support inside
 
a KVM VM. The audience here is QA folks that want to test secureboot, and
 
a KVM VM. The audience here is QA folks that want to test secureboot, and
 
any other curious parties.
 
any other curious parties.
Line 13: Line 13:
 
Unfortunately there are licensing issues which prevent us getting EDK2/OVMF
 
Unfortunately there are licensing issues which prevent us getting EDK2/OVMF
 
into Fedora (see [[#EDK2 Licensing Issues]] at the end of this document for more info). So we
 
into Fedora (see [[#EDK2 Licensing Issues]] at the end of this document for more info). So we
have to grab external packages:
+
have to grab external packages.
  
  sudo rpm -ivh http://fedorapeople.org/~crobinso/secureboot/edk2.manual-0-0.20130221.944c84a6.x86_64.rpm
+
== Running EDK2/OVMF nightly builds ==
  
== Install an F18 VM with UEFI ==
+
Gerd Hoffman, Red Hatter and QEMU developer, has a yum repo on his personal
 +
site that provides nightly builds of a whole bunch of QEMU/KVM firmware,
 +
including EDK2/OVMF.
 +
 
 +
Here's how to pull down the nightly builds:
 +
 
 +
  sudo wget http://www.kraxel.org/repos/firmware.repo -O /etc/yum.repos.d/firmware.repo
 +
 
 +
  # Disable by default, likely preferred for QA
 +
  sudo sed -i -e "s/enabled=1/enabled=0/g" /etc/yum.repos.d/firmware.repo
 +
  sudo yum --enablerepo=qemu-firmware-jenkins install edk2.git-ovmf-x64
 +
 
 +
The OVMF image is at:
 +
 
 +
  /usr/share/edk2.git/ovmf-x64/OVMF-pure-efi.fd
 +
 
 +
Since these are nightly builds, occasionally things break. To work around this, use the following commands to get the February
 +
26th 2014 nightly build:
 +
 
 +
  sudo wget http://drsmith2.fedorapeople.org/edk2.git/edk2.git-0-20140226.b491.gb9b77ab.x86_64.rpm
 +
  sudo wget http://drsmith2.fedorapeople.org/edk2.git/edk2.git-ovmf-ia32-0-20140226.b491.gb9b77ab.x86_64.rpm
 +
  sudo rpm -ivh edk2.git-0-20140226.b491.gb9b77ab.x86_64.rpm edk2.git-ovmf-ia32-0-20140226.b491.gb9b77ab.x86_64.rpm
 +
 
 +
== Install an F18+ VM with UEFI ==
  
 
First we need to install a guest using UEFI instead of traditional bios.
 
First we need to install a guest using UEFI instead of traditional bios.
Line 24: Line 47:
 
so.
 
so.
  
I recommend using a DVD, network installs seem to be sloooow using OVMF:
+
Newer OVMF builds can use a network install, older builds were slow when using a network install. If the network install seems slow, switch to using a DVD install.
 +
 
 +
Here's an example F20 install:
 +
 
 +
  sudo virt-install --name f20-uefi --ram 2048 --boot loader=/usr/share/edk2.git/ovmf-x64/OVMF-pure-efi.fd --disk /var/lib/libvirt/images/f20-uefi.qcow,format=qcow2,size=10 --os-variant fedora20 --cdrom /path/to/Fedora-20-x86_64-netinst.iso
  
  sudo virt-install --name f18-uefi --ram 2048 --boot loader=/usr/share/edk2.manual/ovmf-x64/OVMF-pure-efi.fd --disk /var/lib/libvirt/images/f18-uefi.qcow,format=qcow2,size=10 --os-variant fedora18 --cdrom /path/to/Fedora-18-x86_64-DVD.iso
+
(If you'd like to create a rawhide guest, you combine the above command with the following info: <https://fedoraproject.org/wiki/Releases/Rawhide?rd=Rawhide#Point_installer_to_Rawhide>)
  
 
Follow the install to completion, log in and do firstboot, then move along.
 
Follow the install to completion, log in and do firstboot, then move along.
 
Secure boot isn't set up yet.
 
Secure boot isn't set up yet.
 +
 +
== Booting the VM with OVMF ==
 +
 +
If Fedora doesn't boot, try the following steps. First you'll need to be at the EFI Internal Shell. If you see a 'Shell> ' prompt you are in the shell.
 +
If OVMF doesn't drop you into the EFI Internal Shell automatically, do the following:
 +
 +
# Wait until the TianoCore splash screen pops up, hit ESC
 +
# Select 'Boot Manager'
 +
# Select 'EFI Internal Shell'
 +
 +
Once in the EFI Internal Shell, here are the commands you need to boot Fedora (assuming your guest only has a CDROM attached):
 +
 +
  fs0:
 +
  \EFI\fedora\shim.efi
 +
 +
The above commands just get Fedora going, we haven't set up secure boot yet.
  
 
== Grab LockDown_ms.efi ==
 
== Grab LockDown_ms.efi ==
Line 36: Line 79:
 
install some to mimic what an MS certified UEFI machine will ship with.
 
install some to mimic what an MS certified UEFI machine will ship with.
 
But here's a crappy thing about OVMF and KVM: right now there's no way to
 
But here's a crappy thing about OVMF and KVM: right now there's no way to
persist UEFI config across VM start/stop. So if we want to test SecureBoot,
+
persist UEFI config across VM start/stop, although we'll come close with the script we'll create below.
 +
{{admon/note|Improvements in Fedora 20|
 +
With qemu 1.6 and later, a ''-pflash bios.bin'' option, is supposed to enable persistent EFI variables.  This may or may not also require ''-no-kvm''.}}
 +
So if we want to test SecureBoot,
 
we need to install the MS keys and enable secureboot on every VM restart.
 
we need to install the MS keys and enable secureboot on every VM restart.
  
Line 46: Line 92:
 
   sudo wget http://fedorapeople.org/~crobinso/secureboot/LockDown_ms.efi -O /boot/efi/EFI/fedora/LockDown_ms.efi
 
   sudo wget http://fedorapeople.org/~crobinso/secureboot/LockDown_ms.efi -O /boot/efi/EFI/fedora/LockDown_ms.efi
  
== Enable SecureBoot and verify it's all working ==
+
== Automate SecureBoot startup ==
  
As mentioned above, this needs to be done on every VM boot.
+
As mentioned above, we have to install the MS keys and enable secureboot on every VM restart. Luckily, OVMF by default runs a script at startup, called startup.nsh. We'll use this to automate startup. All we really need in the script are the following commands:
  
# Wait until the TianoCore splash screen pops up, hit ESC
+
  fs0:
# Select 'Boot Manager'
+
  \EFI\fedora\LockDown_ms.efi
# Select 'EFI Internal Shell'
+
  \EFI\fedora\shim.efi
# <code>Shell> fs0:</code>
+
 
# <code>fs0:\> \EFI\fedora\LockDown_ms.efi </code>
+
But, life is complicated by the fact that if you are rebooting the VM where LockDown_ms.efi has been loaded, it can't be loaded a second time (without powering off the VM). If you try, you'll get a "Error reported: Security Violation" message when loading LockDown_ms.efi and the script will stop. So, the script needs to check if SecureBoot is already on before trying to load LockDown_ms.efi.
# <code>fs0:\> \EFI\fedora\shim.efi </code>
+
 
# Guest boots, log in, should see 'Secure boot enabled' in dmesg
+
Inside the guest, as root edit /boot/efi/startup.nsh and add the following text:
 +
 
 +
  fs0:
 +
  # If we don't have the secure boot dmp file, assume this is the first
 +
  # time this script has been run and secure boot is off.
 +
  set __lockdown 0
 +
  if not exist SecureBoot.dmp then
 +
    set __lockdown 1
 +
  # Otherwise we check the current state of the 'SecureBoot' variable
 +
  # to see if LockDown_ms.efi has already been loaded.
 +
  else
 +
    dmpstore SecureBoot -s SecureBoot.tmp
 +
    comp SecureBoot.dmp SecureBoot.tmp
 +
    if not %lasterror% == 0 then
 +
      set __lockdown 1
 +
    endif
 +
    rm SecureBoot.tmp
 +
  endif
 +
  if %__lockdown% == 1 then
 +
    \EFI\fedora\LockDown_ms.efi
 +
    dmpstore SecureBoot -s SecureBoot.dmp
 +
  endif
 +
  \EFI\fedora\shim.efi
 +
 
 +
== Verify SecureBoot ==
  
 +
At this point reboot the guest. After logging in, you should see 'Secure boot enabled' in dmesg. Success!
  
 
= Misc bits =
 
= Misc bits =
Line 69: Line 140:
  
 
The driver is critical functionality so removing it is not an option.
 
The driver is critical functionality so removing it is not an option.
 
== Running EDK2 nightly builds ==
 
 
Gerd Hoffman, Red Hatter and QEMU developer, has a yum repo on his personal
 
site that provides nightly builds of a whole bunch of QEMU/KVM firmware,
 
including EDK2/OVMF.
 
 
Currently though, latest OVMF broke F18 SecureBoot: running the above steps
 
will give the following error when trying to boot shim.efi:
 
 
  Error reported: Security Violation
 
 
There's a fix in upstream <code>pesign</code>, but as of this writing, shim
 
in F18 hasn't been regenerated to pick up the fix.
 
 
Regardless, here's how to pull down the nightly builds:
 
 
  sudo wget http://www.kraxel.org/repos/firmware.repo -O /etc/yum.repos.d/firmware.repo
 
 
  # Disable by default, likely preferred for QA
 
  sudo sed -i -e "s/enabled=1/enabled=0/g" /etc/yum.repos.d/firmware.repo
 
  sudo yum --enablerepo=qemu-firmware-jenkings install edk2.git-ovmf-x64
 
 
The OVMF image is at:
 
 
  /usr/share/edk2.git/ovmf-x64/OVMF-pure-efi.fd
 
  
 
== Pointing an existing guest at OVMF ==
 
== Pointing an existing guest at OVMF ==
Line 106: Line 151:
 
     ...
 
     ...
 
       <loader>/path/to/OVMF-pure-efi.fd</loader>
 
       <loader>/path/to/OVMF-pure-efi.fd</loader>
 +
 +
You will also need to ensure the 'shim' package is installed in the guest.
  
 
== Testing F18 DVD Secure Boot in a VM ==
 
== Testing F18 DVD Secure Boot in a VM ==

Latest revision as of 16:53, 27 February 2014

Contents

[edit] Testing secureboot with KVM

This page documents how to test Fedora 18+ Secureboot support inside a KVM VM. The audience here is QA folks that want to test secureboot, and any other curious parties.

[edit] Install OVMF

OVMF (Open Virtual Machine Firmware) is basically UEFI for KVM. It comes from EDK2 (EFI Development Kit), which is the UEFI reference implementation.

Unfortunately there are licensing issues which prevent us getting EDK2/OVMF into Fedora (see #EDK2 Licensing Issues at the end of this document for more info). So we have to grab external packages.

[edit] Running EDK2/OVMF nightly builds

Gerd Hoffman, Red Hatter and QEMU developer, has a yum repo on his personal site that provides nightly builds of a whole bunch of QEMU/KVM firmware, including EDK2/OVMF.

Here's how to pull down the nightly builds:

 sudo wget http://www.kraxel.org/repos/firmware.repo -O /etc/yum.repos.d/firmware.repo
 # Disable by default, likely preferred for QA
 sudo sed -i -e "s/enabled=1/enabled=0/g" /etc/yum.repos.d/firmware.repo
 sudo yum --enablerepo=qemu-firmware-jenkins install edk2.git-ovmf-x64

The OVMF image is at:

 /usr/share/edk2.git/ovmf-x64/OVMF-pure-efi.fd

Since these are nightly builds, occasionally things break. To work around this, use the following commands to get the February 26th 2014 nightly build:

 sudo wget http://drsmith2.fedorapeople.org/edk2.git/edk2.git-0-20140226.b491.gb9b77ab.x86_64.rpm
 sudo wget http://drsmith2.fedorapeople.org/edk2.git/edk2.git-ovmf-ia32-0-20140226.b491.gb9b77ab.x86_64.rpm
 sudo rpm -ivh edk2.git-0-20140226.b491.gb9b77ab.x86_64.rpm edk2.git-ovmf-ia32-0-20140226.b491.gb9b77ab.x86_64.rpm

[edit] Install an F18+ VM with UEFI

First we need to install a guest using UEFI instead of traditional bios. Anaconda will put all the right bits in place for us. You can probably convert an existing bios guest to use UEFI but I haven't found steps to do so.

Newer OVMF builds can use a network install, older builds were slow when using a network install. If the network install seems slow, switch to using a DVD install.

Here's an example F20 install:

 sudo virt-install --name f20-uefi --ram 2048 --boot loader=/usr/share/edk2.git/ovmf-x64/OVMF-pure-efi.fd --disk /var/lib/libvirt/images/f20-uefi.qcow,format=qcow2,size=10 --os-variant fedora20 --cdrom /path/to/Fedora-20-x86_64-netinst.iso

(If you'd like to create a rawhide guest, you combine the above command with the following info: <https://fedoraproject.org/wiki/Releases/Rawhide?rd=Rawhide#Point_installer_to_Rawhide>)

Follow the install to completion, log in and do firstboot, then move along. Secure boot isn't set up yet.

[edit] Booting the VM with OVMF

If Fedora doesn't boot, try the following steps. First you'll need to be at the EFI Internal Shell. If you see a 'Shell> ' prompt you are in the shell. If OVMF doesn't drop you into the EFI Internal Shell automatically, do the following:

  1. Wait until the TianoCore splash screen pops up, hit ESC
  2. Select 'Boot Manager'
  3. Select 'EFI Internal Shell'

Once in the EFI Internal Shell, here are the commands you need to boot Fedora (assuming your guest only has a CDROM attached):

 fs0:
 \EFI\fedora\shim.efi

The above commands just get Fedora going, we haven't set up secure boot yet.

[edit] Grab LockDown_ms.efi

Since OVMF doesn't ship with any SecureBoot keys installed, we need to install some to mimic what an MS certified UEFI machine will ship with. But here's a crappy thing about OVMF and KVM: right now there's no way to persist UEFI config across VM start/stop, although we'll come close with the script we'll create below.

Note.png
Improvements in Fedora 20
With qemu 1.6 and later, a -pflash bios.bin option, is supposed to enable persistent EFI variables. This may or may not also require -no-kvm.

So if we want to test SecureBoot, we need to install the MS keys and enable secureboot on every VM restart.

Luckily there's a tool that does all this for us, called LockDown_ms.efi. This is derived from code in efitools.git.

Inside the guest, do:

 sudo wget http://fedorapeople.org/~crobinso/secureboot/LockDown_ms.efi -O /boot/efi/EFI/fedora/LockDown_ms.efi

[edit] Automate SecureBoot startup

As mentioned above, we have to install the MS keys and enable secureboot on every VM restart. Luckily, OVMF by default runs a script at startup, called startup.nsh. We'll use this to automate startup. All we really need in the script are the following commands:

 fs0:
 \EFI\fedora\LockDown_ms.efi
 \EFI\fedora\shim.efi

But, life is complicated by the fact that if you are rebooting the VM where LockDown_ms.efi has been loaded, it can't be loaded a second time (without powering off the VM). If you try, you'll get a "Error reported: Security Violation" message when loading LockDown_ms.efi and the script will stop. So, the script needs to check if SecureBoot is already on before trying to load LockDown_ms.efi.

Inside the guest, as root edit /boot/efi/startup.nsh and add the following text:

 fs0:
 # If we don't have the secure boot dmp file, assume this is the first
 # time this script has been run and secure boot is off.
 set __lockdown 0
 if not exist SecureBoot.dmp then
   set __lockdown 1
 # Otherwise we check the current state of the 'SecureBoot' variable
 # to see if LockDown_ms.efi has already been loaded.
 else
   dmpstore SecureBoot -s SecureBoot.tmp
   comp SecureBoot.dmp SecureBoot.tmp
   if not %lasterror% == 0 then
     set __lockdown 1
   endif
   rm SecureBoot.tmp
 endif
 if %__lockdown% == 1 then
   \EFI\fedora\LockDown_ms.efi
   dmpstore SecureBoot -s SecureBoot.dmp
 endif
 \EFI\fedora\shim.efi

[edit] Verify SecureBoot

At this point reboot the guest. After logging in, you should see 'Secure boot enabled' in dmesg. Success!

[edit] Misc bits

[edit] EDK2 Licensing Issues

EDK2 contains a FAT filesystem driver that is licensed under terms that make it not acceptable for packaging in Fedora. Particularly that there's a usage restricition only allowing the code to be used in a UEFI implementation. More details here at Edk2-fat-driver

The driver is critical functionality so removing it is not an option.

[edit] Pointing an existing guest at OVMF

To alter an existing guest to use OVMF, or change the OVMF build it uses, do sudo virsh edit $vmname and add

 <domain>
   ...
   <os>
    ...
     <loader>/path/to/OVMF-pure-efi.fd</loader>

You will also need to ensure the 'shim' package is installed in the guest.

[edit] Testing F18 DVD Secure Boot in a VM

Since we can't easily alter the DVD to add LockDown_ms.efi, we get it into the VM using a mini disk image:

 wget http://fedorapeople.org/~crobinso/secureboot/lockdown.qcow2
 sudo virsh attach-disk $VMNAME --target hdb --source lockdown.qcow2 --subdriver qcow2 --config

Then do

  • Launch the VM, drop to the EFI shell
  • If your guest only has a CDROM attached, lockdown.qcow2 should be fs0
  • Shell> fs0:
  • fs0:\> LockDown_ms.efi
  • fs0:\> exit
  • Back in the config screen, Select 'Boot Manager'
  • Select 'EFI DVD/CDROM'
  • Once anaconda starts, grab shell, log in, verify secure boot is enabled

[edit] Extra links