This repository contains Ansible roles to configure secure boot.
Currently, only one role is provided by this collection: uki_config
. It does the following
high-level things:
- Enroll a valid machine owner key (MOK) for image signing
- Configure
kernel-install
to generate a unified kernel image (UKI) instead of a separate kernel, command line and initrd - Configure a tool to automatically sign generated UKIs using the enrolled MOK
- Configure the host to boot straight from
shim
to the UKI, skipping GRUB entirely
If you're using Fedora 40, you can satisfy this entire section with:
dnf install openssl systemd-boot sbsigntools binutils systemd-ukify virt-firmware uki-direct expect
or:
- name: Install dependencies
ansible.builtin.dnf:
name:
- openssl
- systemd-boot
- sbsigntools
- systemd-ukify
- virt-firmware
- uki-direct
- expect
For every other platform, the requirements for the uki_config
role are described in the
following three sections:
- System requirements
- Package dependencies
- Argument-specific dependencies
- A UEFI firmware platform with secure boot support. This is not technically a requirement for UKIs, but is considered so by this role.
shim
This role assumes shim
is used to authenticate binaries. This should alredy come packaged in any
modern Linux distribution. Support for skipping shim is not provided, but please submit an issue
or PR if you need this.
kernel-install
Although a single UKI build can be done without it, this role assumes the use of systemd
kernel-install
version 255 or greater. This is typically provided by the "systemd-udev"
package on modern distributions, but may be too old.
virt-firmware
The virt-firmware python package is required to configure shim to boot straight to your UKI. On
Fedora 40, the tools needed are split into the virt-firmware
main package and uki-direct
subpackage.
On other platforms, you may be able to use your python package manager of choice, or get it from PyPI. If you do this without a system package, you will need to make sure:
kernel-bootcfg
is in your path99-uki-uefi-setup.install
is executable in/etc/kernel/install.d
kernel-bootcfg-boot-successful.service
is loaded
openssl
Openssl is required by the community.crypto
modules used by the role. Even if you choose to
import your own MOK, the role still checks it for validity.
systemd-stub
The systemd kernel boot stub is required to make the unified kernel image bootable. On Fedora, this is shipped with the "systemd-boot" package.
sbsign
The sbsign
utility is required to sign UKIs. This is usually provided by the "sbsigntools"
package.
ukify
ukify
is the only supported UKI generator, you should have it installed. This is usually
provided by the "systemd-ukify" package.
dracut or other initrd generator
By default, dracut
is the tool declared in uki_config_initrd_generator
, so should be
installed if you don't modify this argument. Others may be used as long as they are supported
by your system and kernel-install
. Note that some generators like dracut
and mkinitcpio
have support for UKI generation on their own; this is not supported and will cause failures.
The role expects a regular inird to be generated, and builds a UKI with it using ukify
.
mokutil
The mokutil
tool is used to validate the enrollment status of your generated or provided MOK.
expect
This role uses the expect
executable to interact with mokutil
only if you need to enroll a
new MOK. If you run the role with a MOK already enrolled through MokManager, expect
will
never be called.
This playbook may require manual administrator interaction. If you choose to generate a new MOK (the default) or import a MOK that is not already enrolled, you will be prompted twice:
- Once to define a MOK enrollment password. This should be something easy to type but still secure, as explained in prompt 2.
- Then to reboot into MokManager. The playbook will reboot for you and resume once complete, but only the administrator with physical access to a console/display can complete a new MOK enrollment.
This means this role may not be suitable for any Fedora 40 environment. Most cloud providers for example will never provide a pre-boot console or virtual display, and therefore cannot support custom MOK enrollment. Most hypervisors will support this however (this author uses Hyper-V). The reboot prompt is meant to pause and allow the caller time to bring up the proper console or display.
All arguments have default values, reflected in the following example:
- name: Test playbook
hosts: test
roles:
- role: uki_config
vars:
uki_config_initrd_generator: dracut
uki_config_cmdline: /etc/kernel/cmdline
uki_config_kernel_intall_config_root: /etc/kernel
uki_config_mok:
private_key: /etc/kernel/MOK.priv
certificate: /etc/kernel/MOK.cer
owner: root
group: root
mode: "0600"
selevel: s0
seuser: system_u
serole: object_r
setype: cert_t
Your initrd generator of choice, or dracut
by default.
You may substitute this path to any path readable by root. Passing the content of the kernel command line is not supported. Please submit an issue/PR if you want support for this.
Note: The kernel command line is ignored when dracut is the UKI generator. Please configure dracut yourself if you want a different command line.
These arguments allow you to specify where you custom configuration should be applied. You may for
example wish to keep it under /usr/lib/kernel
.
By default, a MOK is created at the path specified under private_key
and certificate
if
an adequate key/certificate pair does not already exist at that path. If you wish to bring
your own MOK instead of generating a new one for each host, either write your files to the
default paths, or provide custom paths.
Note: The author considered adding support for
pesign
as a signing engine (this would only be available with the "ukify" UKI generator), but this was refused for time's sake and for the ability to import private keys. If you want support for this, submit an issue/PR and we'll talk about it.