Dieser Inhalt ist in der von Ihnen ausgewählten Sprache nicht verfügbar.
Chapter 21. Signing a kernel and modules for Secure Boot
You can enhance the security of your system by using a signed kernel and signed kernel modules. On UEFI-based build systems where Secure Boot is enabled, you can self-sign a privately built kernel or kernel modules. Furthermore, you can import your public key into a target system where you want to deploy your kernel or kernel modules.
If Secure Boot is enabled, all of the following components have to be signed with a private key and authenticated with the corresponding public key:
- UEFI operating system boot loader
- The Red Hat Enterprise Linux kernel
- All kernel modules
If any of these components are not signed and authenticated, the system cannot finish the booting process.
RHEL 9 includes:
- Signed boot loaders
- Signed kernels
- Signed kernel modules
In addition, the signed first-stage boot loader and the signed kernel include embedded Red Hat public keys. These signed executable binaries and embedded keys enable RHEL 9 to install, boot, and run with the Microsoft UEFI Secure Boot Certification Authority keys. These keys are provided by the UEFI firmware on systems that support UEFI Secure Boot.
- Not all UEFI-based systems include support for Secure Boot.
- The build system, where you build and sign your kernel module, does not need to have UEFI Secure Boot enabled and does not even need to be a UEFI-based system.
21.1. Prerequisites Link kopierenLink in die Zwischenablage kopiert!
To be able to sign externally built kernel modules, install the utilities from the following packages:
dnf install pesign openssl kernel-devel mokutil keyutils
# dnf install pesign openssl kernel-devel mokutil keyutilsCopy to Clipboard Copied! Toggle word wrap Toggle overflow Expand Table 21.1. Required utilities Utility Provided by package Used on Purpose efikeygenpesignBuild system
Generates public and private X.509 key pair
opensslopensslBuild system
Exports the unencrypted private key
sign-filekernel-develBuild system
Executable file used to sign a kernel module with the private key
mokutilmokutilTarget system
Optional utility used to manually enroll the public key
keyctlkeyutilsTarget system
Optional utility used to display public keys in the system keyring
21.2. What is UEFI Secure Boot Link kopierenLink in die Zwischenablage kopiert!
With the Unified Extensible Firmware Interface (UEFI) Secure Boot technology, you can prevent the execution of the kernel-space code that is not signed by a trusted key. The system boot loader is signed with a cryptographic key. The database of public keys in the firmware authorizes the process of signing the key. You can subsequently verify a signature in the next-stage boot loader and the kernel.
UEFI Secure Boot establishes a chain of trust from the firmware to the signed drivers and kernel modules as follows:
-
An UEFI private key signs, and a public key authenticates the
shimfirst-stage boot loader. A certificate authority (CA) in turn signs the public key. The CA is stored in the firmware database. -
The
shimfile contains the Red Hat public key Red Hat Secure Boot (CA key 1) to authenticate the GRUB boot loader and the kernel. - The kernel in turn contains public keys to authenticate drivers and modules.
Secure Boot is the boot path validation component of the UEFI specification. The specification defines:
- Programming interface for cryptographically protected UEFI variables in non-volatile storage.
- Storing the trusted X.509 root certificates in UEFI variables.
- Validation of UEFI applications such as boot loaders and drivers.
- Procedures to revoke known-bad certificates and application hashes.
UEFI Secure Boot helps in the detection of unauthorized changes but does not:
- Prevent installation or removal of second-stage boot loaders.
- Require explicit user confirmation of such changes.
- Stop boot path manipulations. Signatures are verified during booting but, not when the boot loader is installed or updated.
If the boot loader or the kernel are not signed by a system trusted key, Secure Boot prevents them from starting.
21.3. UEFI Secure Boot support Link kopierenLink in die Zwischenablage kopiert!
You can install and run RHEL 9 on systems with enabled UEFI Secure Boot if the kernel and all the loaded drivers are signed with a trusted key. Red Hat provides kernels and drivers that are signed and authenticated by the relevant Red Hat keys.
If you want to load externally built kernels or drivers, you must sign them as well.
Restrictions imposed by UEFI Secure Boot
- The system only runs the kernel-mode code after its signature has been properly authenticated.
- GRUB module loading is disabled because there is no infrastructure for signing and verification of GRUB modules. Allowing module loading would run untrusted code within the security perimeter defined by Secure Boot.
- Red Hat provides a signed GRUB binary that has all supported modules on RHEL 9.
21.4. Requirements for authenticating kernel modules with X.509 keys Link kopierenLink in die Zwischenablage kopiert!
In RHEL 9, when a kernel module is loaded, the kernel checks the signature of the module against the public X.509 keys from the kernel system keyring (.builtin_trusted_keys) and the kernel platform keyring (.platform). The .platform keyring provides keys from third-party platform providers and custom public keys. The keys from the kernel system .blacklist keyring are excluded from verification.
You need to meet certain conditions to load kernel modules on systems with enabled UEFI Secure Boot functionality:
If UEFI Secure Boot is enabled or if the
module.sig_enforcekernel parameter has been specified:-
You can only load those signed kernel modules whose signatures were authenticated against keys from the system keyring (
.builtin_trusted_keys) and the platform keyring (.platform). -
The public key must not be on the system revoked keys keyring (
.blacklist).
-
You can only load those signed kernel modules whose signatures were authenticated against keys from the system keyring (
If UEFI Secure Boot is disabled and the
module.sig_enforcekernel parameter has not been specified:- You can load unsigned kernel modules and signed kernel modules without a public key.
If the system is not UEFI-based or if UEFI Secure Boot is disabled:
-
Only the keys embedded in the kernel are loaded onto
.builtin_trusted_keysand.platform. - You have no ability to augment that set of keys without rebuilding the kernel.
-
Only the keys embedded in the kernel are loaded onto
| Module signed | Public key found and signature valid | UEFI Secure Boot state | sig_enforce | Module load | Kernel tainted |
|---|---|---|---|---|---|
| Unsigned | - | Not enabled | Not enabled | Succeeds | Yes |
| Not enabled | Enabled | Fails | - | ||
| Enabled | - | Fails | - | ||
| Signed | No | Not enabled | Not enabled | Succeeds | Yes |
| Not enabled | Enabled | Fails | - | ||
| Enabled | - | Fails | - | ||
| Signed | Yes | Not enabled | Not enabled | Succeeds | No |
| Not enabled | Enabled | Succeeds | No | ||
| Enabled | - | Succeeds | No |
21.5. Sources for public keys Link kopierenLink in die Zwischenablage kopiert!
During boot, the kernel loads X.509 keys from a set of persistent key stores into the following keyrings:
-
The system keyring (
.builtin_trusted_keys) -
The
.platformkeyring -
The system
.blacklistkeyring
| Source of X.509 keys | User can add keys | UEFI Secure Boot state | Keys loaded during boot |
|---|---|---|---|
| Embedded in kernel | No | - |
|
|
UEFI | Limited | Not enabled | No |
| Enabled |
| ||
|
Embedded in the | No | Not enabled | No |
| Enabled |
| ||
| Machine Owner Key (MOK) list | Yes | Not enabled | No |
| Enabled |
|
.builtin_trusted_keys- A keyring that is built on boot.
- Provides trusted public keys.
-
rootprivileges are required to view the keys.
.platform- A keyring that is built on boot.
- Provides keys from third-party platform providers and custom public keys.
-
rootprivileges are required to view the keys.
.blacklist- A keyring with X.509 keys which have been revoked.
-
A module signed by a key from
.blacklistwill fail authentication even if your public key is in.builtin_trusted_keys.
- UEFI Secure Boot
db - A signature database.
- Stores keys (hashes) of UEFI applications, UEFI drivers, and boot loaders.
- The keys can be loaded on the machine.
- UEFI Secure Boot
dbx - A revoked signature database.
- Prevents keys from getting loaded.
-
The revoked keys from this database are added to the
.blacklistkeyring.
21.6. Generating a public and private key pair Link kopierenLink in die Zwischenablage kopiert!
To use a custom kernel or custom kernel modules on a Secure Boot-enabled system, you must generate a public and private X.509 key pair. You can use the generated private key to sign the kernel or the kernel modules. You can also validate the signed kernel or kernel modules by adding the corresponding public key to the Machine Owner Key (MOK) for Secure Boot.
Apply strong security measures and access policies to guard the contents of your private key. In the wrong hands, the key could be used to compromise any system which is authenticated by the corresponding public key.
Procedure
Create an X.509 public and private key pair:
If you only want to sign custom kernel modules:
efikeygen --dbdir /etc/pki/pesign \ --self-sign \ --module \ --common-name 'CN=Organization signing key' \ --nickname 'Custom Secure Boot key'# efikeygen --dbdir /etc/pki/pesign \ --self-sign \ --module \ --common-name 'CN=Organization signing key' \ --nickname 'Custom Secure Boot key'Copy to Clipboard Copied! Toggle word wrap Toggle overflow If you want to sign custom kernel:
efikeygen --dbdir /etc/pki/pesign \ --self-sign \ --kernel \ --common-name 'CN=Organization signing key' \ --nickname 'Custom Secure Boot key'# efikeygen --dbdir /etc/pki/pesign \ --self-sign \ --kernel \ --common-name 'CN=Organization signing key' \ --nickname 'Custom Secure Boot key'Copy to Clipboard Copied! Toggle word wrap Toggle overflow When the RHEL system is running FIPS mode:
Copy to Clipboard Copied! Toggle word wrap Toggle overflow NoteIn FIPS mode, you must use the
--tokenoption so thatefikeygenfinds the default "NSS Certificate DB" token in the PKI database.The public and private keys are now stored in the
/etc/pki/pesign/directory.
It is a good security practice to sign the kernel and the kernel modules within the validity period of its signing key. However, the sign-file utility does not warn you and the key will be usable in RHEL 9 regardless of the validity dates.
21.7. Example output of system keyrings Link kopierenLink in die Zwischenablage kopiert!
You can display information about the keys on the system keyrings using the keyctl utility from the keyutils package.
Prerequisites
- You have root permissions.
-
You have installed the
keyctlutility from thekeyutilspackage.
Example 21.1. Keyrings output
The following is a shortened example output of .builtin_trusted_keys, .platform, and .blacklist keyrings from a RHEL 9 system where UEFI Secure Boot is enabled.
The .builtin_trusted_keys keyring in the example shows the addition of two keys from the UEFI Secure Boot db keys as well as the Red Hat Secure Boot (CA key 1), which is embedded in the shim boot loader.
Example 21.2. Kernel console output
The following example shows the kernel console output. The messages identify the keys with an UEFI Secure Boot related source. These include UEFI Secure Boot db, embedded shim, and MOK list.
21.8. Enrolling public key on target system by adding the public key to the MOK list Link kopierenLink in die Zwischenablage kopiert!
You must authenticate your public key on a system for kernel or kernel module access and enroll it in the platform keyring (.platform) of the target system. When RHEL 9 boots on a UEFI-based system with Secure Boot enabled, the kernel imports public keys from the db key database and excludes revoked keys from the dbx database.
The Machine Owner Key (MOK) facility allows expanding the UEFI Secure Boot key database. When booting RHEL 9 on UEFI-enabled systems with Secure Boot enabled, keys on the MOK list are added to the platform keyring (.platform), along with the keys from the Secure Boot database. The list of MOK keys is stored securely and persistently in the same way, but it is a separate facility from the Secure Boot databases.
The MOK facility is supported by shim, MokManager, GRUB, and the mokutil utility that enables secure key management and authentication for UEFI-based systems.
To get the authentication service of your kernel module on your systems, consider requesting your system vendor to incorporate your public key into the UEFI Secure Boot key database in their factory firmware image.
Prerequisites
- You have generated a public and private key pair and know the validity dates of your public keys. For details, see Generating a public and private key pair.
Procedure
Export your public key to the
sb_cert.cerfile:certutil -d /etc/pki/pesign \ -n 'Custom Secure Boot key' \ -Lr \ > sb_cert.cer# certutil -d /etc/pki/pesign \ -n 'Custom Secure Boot key' \ -Lr \ > sb_cert.cerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Import your public key into the MOK list:
mokutil --import sb_cert.cer
# mokutil --import sb_cert.cerCopy to Clipboard Copied! Toggle word wrap Toggle overflow - Enter a new password for this MOK enrollment request.
Reboot the machine.
The
shimboot loader notices the pending MOK key enrollment request and it launchesMokManager.efito enable you to complete the enrollment from the UEFI console.Choose
Enroll MOK, enter the password you previously associated with this request when prompted, and confirm the enrollment.Your public key is added to the MOK list, which is persistent.
Once a key is on the MOK list, it will be automatically propagated to the
.platformkeyring on this and subsequent boots when UEFI Secure Boot is enabled.
21.9. Signing a kernel with the private key Link kopierenLink in die Zwischenablage kopiert!
You can obtain enhanced security benefits on your system by loading a signed kernel if the UEFI Secure Boot mechanism is enabled.
Prerequisites
- You have generated a public and private key pair and know the validity dates of your public keys. For details, see Generating a public and private key pair.
- You have enrolled your public key on the target system. For details, see Enrolling public key on target system by adding the public key to the MOK list.
- You have a kernel image in the ELF format available for signing.
Procedure
On the x64 architecture:
Create a signed image:
pesign --certificate 'Custom Secure Boot key' \ --in vmlinuz-version \ --sign \ --out vmlinuz-version.signed# pesign --certificate 'Custom Secure Boot key' \ --in vmlinuz-version \ --sign \ --out vmlinuz-version.signedCopy to Clipboard Copied! Toggle word wrap Toggle overflow Replace
versionwith the version suffix of yourvmlinuzfile, andCustom Secure Boot keywith the name that you chose earlier.Optional: Check the signatures:
pesign --show-signature \ --in vmlinuz-version.signed# pesign --show-signature \ --in vmlinuz-version.signedCopy to Clipboard Copied! Toggle word wrap Toggle overflow Overwrite the unsigned image with the signed image:
mv vmlinuz-version.signed vmlinuz-version
# mv vmlinuz-version.signed vmlinuz-versionCopy to Clipboard Copied! Toggle word wrap Toggle overflow
On the 64-bit ARM architecture:
Decompress the
vmlinuzfile:zcat vmlinuz-version > vmlinux-version
# zcat vmlinuz-version > vmlinux-versionCopy to Clipboard Copied! Toggle word wrap Toggle overflow Create a signed image:
pesign --certificate 'Custom Secure Boot key' \ --in vmlinux-version \ --sign \ --out vmlinux-version.signed# pesign --certificate 'Custom Secure Boot key' \ --in vmlinux-version \ --sign \ --out vmlinux-version.signedCopy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: Check the signatures:
pesign --show-signature \ --in vmlinux-version.signed# pesign --show-signature \ --in vmlinux-version.signedCopy to Clipboard Copied! Toggle word wrap Toggle overflow Compress the
vmlinuxfile:gzip --to-stdout vmlinux-version.signed > vmlinuz-version
# gzip --to-stdout vmlinux-version.signed > vmlinuz-versionCopy to Clipboard Copied! Toggle word wrap Toggle overflow Remove the uncompressed
vmlinuxfile:rm vmlinux-version*
# rm vmlinux-version*Copy to Clipboard Copied! Toggle word wrap Toggle overflow
21.10. Signing a GRUB build with the private key Link kopierenLink in die Zwischenablage kopiert!
On a system where the UEFI Secure Boot mechanism is enabled, you can sign a GRUB build with a custom existing private key. You must do this if you are using a custom GRUB build, or if you have removed the Microsoft trust anchor from your system.
Prerequisites
- You have generated a public and private key pair and know the validity dates of your public keys. For details, see Generating a public and private key pair.
- You have enrolled your public key on the target system. For details, see Enrolling public key on target system by adding the public key to the MOK list.
- You have a GRUB EFI binary available for signing.
Procedure
On the x64 architecture:
Create a signed GRUB EFI binary:
pesign --in /boot/efi/EFI/redhat/grubx64.efi \ --out /boot/efi/EFI/redhat/grubx64.efi.signed \ --certificate 'Custom Secure Boot key' \ --sign# pesign --in /boot/efi/EFI/redhat/grubx64.efi \ --out /boot/efi/EFI/redhat/grubx64.efi.signed \ --certificate 'Custom Secure Boot key' \ --signCopy to Clipboard Copied! Toggle word wrap Toggle overflow Replace
Custom Secure Boot keywith the name that you chose earlier.Optional: Check the signatures:
pesign --in /boot/efi/EFI/redhat/grubx64.efi.signed \ --show-signature# pesign --in /boot/efi/EFI/redhat/grubx64.efi.signed \ --show-signatureCopy to Clipboard Copied! Toggle word wrap Toggle overflow Overwrite the unsigned binary with the signed binary:
mv /boot/efi/EFI/redhat/grubx64.efi.signed \ /boot/efi/EFI/redhat/grubx64.efi# mv /boot/efi/EFI/redhat/grubx64.efi.signed \ /boot/efi/EFI/redhat/grubx64.efiCopy to Clipboard Copied! Toggle word wrap Toggle overflow
On the 64-bit ARM architecture:
Create a signed GRUB EFI binary:
pesign --in /boot/efi/EFI/redhat/grubaa64.efi \ --out /boot/efi/EFI/redhat/grubaa64.efi.signed \ --certificate 'Custom Secure Boot key' \ --sign# pesign --in /boot/efi/EFI/redhat/grubaa64.efi \ --out /boot/efi/EFI/redhat/grubaa64.efi.signed \ --certificate 'Custom Secure Boot key' \ --signCopy to Clipboard Copied! Toggle word wrap Toggle overflow Replace
Custom Secure Boot keywith the name that you chose earlier.Optional: Check the signatures:
pesign --in /boot/efi/EFI/redhat/grubaa64.efi.signed \ --show-signature# pesign --in /boot/efi/EFI/redhat/grubaa64.efi.signed \ --show-signatureCopy to Clipboard Copied! Toggle word wrap Toggle overflow Overwrite the unsigned binary with the signed binary:
mv /boot/efi/EFI/redhat/grubaa64.efi.signed \ /boot/efi/EFI/redhat/grubaa64.efi# mv /boot/efi/EFI/redhat/grubaa64.efi.signed \ /boot/efi/EFI/redhat/grubaa64.efiCopy to Clipboard Copied! Toggle word wrap Toggle overflow
21.11. Signing kernel modules with the private key Link kopierenLink in die Zwischenablage kopiert!
You can enhance the security of your system by loading signed kernel modules if the UEFI Secure Boot mechanism is enabled.
Your signed kernel module is also loadable on systems where UEFI Secure Boot is disabled or on a non-UEFI system. As a result, you do not need to provide both, a signed and unsigned version of your kernel module.
Prerequisites
- You have generated a public and private key pair and know the validity dates of your public keys. For details, see Generating a public and private key pair.
- You have enrolled your public key on the target system. For details, see Enrolling public key on target system by adding the public key to the MOK list.
- You have a kernel module in ELF image format available for signing.
Procedure
Export your public key to the
sb_cert.cerfile:certutil -d /etc/pki/pesign \ -n 'Custom Secure Boot key' \ -Lr \ > sb_cert.cer# certutil -d /etc/pki/pesign \ -n 'Custom Secure Boot key' \ -Lr \ > sb_cert.cerCopy to Clipboard Copied! Toggle word wrap Toggle overflow Extract the key from the NSS database as a PKCS #12 file:
pk12util -o sb_cert.p12 \ -n 'Custom Secure Boot key' \ -d /etc/pki/pesign# pk12util -o sb_cert.p12 \ -n 'Custom Secure Boot key' \ -d /etc/pki/pesignCopy to Clipboard Copied! Toggle word wrap Toggle overflow - When the previous command prompts, enter a new password that encrypts the private key.
Export the unencrypted private key:
openssl pkcs12 \ -in sb_cert.p12 \ -out sb_cert.priv \ -nocerts \ -noenc# openssl pkcs12 \ -in sb_cert.p12 \ -out sb_cert.priv \ -nocerts \ -noencCopy to Clipboard Copied! Toggle word wrap Toggle overflow ImportantKeep the unencrypted private key secure.
Sign your kernel module. The following command appends the signature directly to the ELF image in your kernel module file:
/usr/src/kernels/$(uname -r)/scripts/sign-file \ sha256 \ sb_cert.priv \ sb_cert.cer \ my_module.ko# /usr/src/kernels/$(uname -r)/scripts/sign-file \ sha256 \ sb_cert.priv \ sb_cert.cer \ my_module.koCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Your kernel module is now ready for loading.
In RHEL 9, the validity dates of the key pair matter. The key does not expire, but the kernel module must be signed within the validity period of its signing key. The sign-file utility will not warn you of this. For example, a key that is only valid in 2021 can be used to authenticate a kernel module signed in 2021 with that key. However, users cannot use that key to sign a kernel module in 2022.
Verification
Display information about the kernel module’s signature:
modinfo my_module.ko | grep signer
# modinfo my_module.ko | grep signer signer: Your Name KeyCopy to Clipboard Copied! Toggle word wrap Toggle overflow Check that the signature lists your name as entered during generation.
NoteThe appended signature is not contained in an ELF image section and is not a formal part of the ELF image. Therefore, utilities such as
readelfcannot display the signature on your kernel module.Load the module:
insmod my_module.ko
# insmod my_module.koCopy to Clipboard Copied! Toggle word wrap Toggle overflow Remove (unload) the module:
modprobe -r my_module.ko
# modprobe -r my_module.koCopy to Clipboard Copied! Toggle word wrap Toggle overflow
21.12. Loading signed kernel modules Link kopierenLink in die Zwischenablage kopiert!
After enrolling your public key in the system keyring (.builtin_trusted_keys) and the MOK list, and signing kernel modules with your private key, you can load them using the modprobe command.
Prerequisites
- You have generated the public and private key pair. For details, see Generating a public and private key pair.
- You have enrolled the public key into the system keyring. For details, see Enrolling public key on target system by adding the public key to the MOK list.
- You have signed a kernel module with the private key. For details, see Signing kernel modules with the private key.
Install the
kernel-modules-extrapackage, which creates the/lib/modules/$(uname -r)/extra/directory:dnf -y install kernel-modules-extra
# dnf -y install kernel-modules-extraCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Procedure
Verify that your public keys are on the system keyring:
keyctl list %:.platform
# keyctl list %:.platformCopy to Clipboard Copied! Toggle word wrap Toggle overflow Copy the kernel module into the
extra/directory of the kernel that you want:cp my_module.ko /lib/modules/$(uname -r)/extra/
# cp my_module.ko /lib/modules/$(uname -r)/extra/Copy to Clipboard Copied! Toggle word wrap Toggle overflow Update the modular dependency list:
depmod -a
# depmod -aCopy to Clipboard Copied! Toggle word wrap Toggle overflow Load the kernel module:
modprobe -v my_module
# modprobe -v my_moduleCopy to Clipboard Copied! Toggle word wrap Toggle overflow Optional: To load the module on boot, add it to the
/etc/modules-loaded.d/my_module.conffile:echo "my_module" > /etc/modules-load.d/my_module.conf
# echo "my_module" > /etc/modules-load.d/my_module.confCopy to Clipboard Copied! Toggle word wrap Toggle overflow
Verification
Verify that the module was successfully loaded:
lsmod | grep my_module
# lsmod | grep my_moduleCopy to Clipboard Copied! Toggle word wrap Toggle overflow