Chapter 3. Managing kernel modules
The following sections explain what kernel modules are, how to display their information, and how to perform basic administrative tasks with kernel modules.
3.1. Introduction to kernel modules
The Red Hat Enterprise Linux kernel can be extended with optional, additional pieces of functionality, called kernel modules, without having to reboot the system. On Red Hat Enterprise Linux 8, kernel modules are extra kernel code which is built into compressed <KERNEL_MODULE_NAME>.ko.xz
object files.
The most common functionality enabled by kernel modules are:
- Device driver which adds support for new hardware
-
Support for a file system such as
GFS2
orNFS
- System calls
On modern systems, kernel modules are automatically loaded when needed. However, in some cases it is necessary to load or unload modules manually.
Like the kernel itself, the modules can take parameters that customize their behavior if needed.
Tooling is provided to inspect which modules are currently running, which modules are available to load into the kernel and which parameters a module accepts. The tooling also provides a mechanism to load and unload kernel modules into the running kernel.
3.2. Introduction to bootloader specification
The BootLoader Specification (BLS) defines a scheme and the file format to manage the bootloader configuration for each boot option in the drop-in directory without the need to manipulate the bootloader configuration files. Unlike earlier approaches, each boot entry is now represented by a separate configuration file in the drop-in directory. The drop-in directory extends its configuration without having the need to edit or regenerate the configuration files. The BLS extends this concept for the boot menu entries.
Using BLS, you can manage the bootloader menu options by adding, removing, or editing individual boot entry files in a directory. This makes the kernel installation process significantly simpler and consistent across the different architectures.
The grubby
tool is a thin wrapper script around the BLS and it supports the same grubby
arguments and options. It runs the dracut
to create an initial ramdisk image. With this setup, the core bootloader configuration files are static and are not modified after kernel installation.
This premise is particularly relevant in Red Hat Enterprise Linux 8 because the same bootloader is not used in all architectures. GRUB2
is used in most of them such as the 64-bit ARM, but little-endian variants of IBM Power Systems with Open Power Abstraction Layer (OPAL) uses Petitboot
and the IBM Z architecture uses zipl
.
Additional Resources
-
For more information about
grubby
utility, see What is grubby. - For more details for boot entries, see What are Boot Entries
-
For more details, see the
grubby(8)
manual page.
3.3. Kernel module dependencies
Certain kernel modules sometimes depend on one or more other kernel modules. The /lib/modules/<KERNEL_VERSION>/modules.dep
file contains a complete list of kernel module dependencies for the respective kernel version.
The dependency file is generated by the depmod
program, which is a part of the kmod
package. Many of the utilities provided by kmod
take module dependencies into account when performing operations so that manual dependency-tracking is rarely necessary.
The code of kernel modules is executed in kernel-space in the unrestricted mode. Because of this, you should be mindful of what modules you are loading.
Additional resources
-
For more information about
/lib/modules/<KERNEL_VERSION>/modules.dep
, refer to themodules.dep(5)
manual page. -
For further details including the synopsis and options of
depmod
, see thedepmod(8)
manual page.
3.4. Listing currently loaded kernel modules
The following procedure describes how to view the currently loaded kernel modules.
Prerequisites
-
The
kmod
package is installed.
Procedure
To list all currently loaded kernel modules, execute:
$ lsmod Module Size Used by fuse 126976 3 uinput 20480 1 xt_CHECKSUM 16384 1 ipt_MASQUERADE 16384 1 xt_conntrack 16384 1 ipt_REJECT 16384 1 nft_counter 16384 16 nf_nat_tftp 16384 0 nf_conntrack_tftp 16384 1 nf_nat_tftp tun 49152 1 bridge 192512 0 stp 16384 1 bridge llc 16384 2 bridge,stp nf_tables_set 32768 5 nft_fib_inet 16384 1 …
In the example above:
- The first column provides the names of currently loaded modules.
- The second column displays the amount of memory per module in kilobytes.
- The last column shows the number, and optionally the names of modules that are dependent on a particular module.
Additional resources
-
For more information about
kmod
, refer to the/usr/share/doc/kmod/README
file or thelsmod(8)
manual page.
3.5. Listing all installed kernels
The following procedure describes how to use the command line tool grubby
to list the GRUB2
boot entries.
Procedure
To list the boot entries of the kernel:
To list the boot entries of the kernel, execute:
# grubby --info=ALL | grep title
The command displays the boot entries of the kernel. The
kernel
field shows the kernel path.The following procedure describes how to use
grubby
utility to list all installed kernels in their systems using the kernel command line.
As an example, consider listing grubby-8.40-17
, from the Grub2
menu on both the BLS and non-BLS installs.
Procedure
To list all installed kernel modules:
Execute the following command:
# grubby --info=ALL | grep title
The list of all installed kernels is displayed as follows:
title=Red Hat Enterprise Linux (4.18.0-20.el8.x86_64) 8.0 (Ootpa) title=Red Hat Enterprise Linux (4.18.0-19.el8.x86_64) 8.0 (Ootpa) title=Red Hat Enterprise Linux (4.18.0-12.el8.x86_64) 8.0 (Ootpa) title=Red Hat Enterprise Linux (4.18.0) 8.0 (Ootpa) title=Red Hat Enterprise Linux (0-rescue-2fb13ddde2e24fde9e6a246a942caed1) 8.0 (Ootpa)
The above output displays the list of all installed kernels for grubby-8.40-17
, using the Grub2
menu.
3.6. Setting a kernel as default
The following procedure describes how to set a specific kernel as default using the grubby
command-line tool and GRUB2
.
Procedure
- Setting the kernel as default, using the
grubby
tool -
Execute the following command to set the kernel as default using the
grubby
tool:
# grubby --set-default $kernel_path
The command uses a machine ID without the
.conf
suffix as an argument.NoteThe machine ID is located in the
/boot/loader/entries/
directory.-
Execute the following command to set the kernel as default using the
- Setting the kernel as default, using the
id
argument -
List the boot entries using the
id
argument and then set an intended kernel as default:
# grubby --info ALL | grep id # grubby --set-default /boot/vmlinuz-<version>.<architecture>
NoteTo list the boot entries using the
title
argument, execute the# grubby --info=ALL | grep title
command.-
List the boot entries using the
- Setting the default kernel for only the next boot
-
Execute the following command to set the default kernel for only the next reboot using the
grub2-reboot
command:
# grub2-reboot <index|title|id>
WarningSet the default kernel for only the next boot with care. Installing new kernel RPM’s, self-built kernels, and manually adding the entries to the
/boot/loader/entries/
directory may change the index values.-
Execute the following command to set the default kernel for only the next reboot using the
3.7. Displaying information about kernel modules
When working with a kernel module, you may want to see further information about that module. This procedure describes how to display extra information about kernel modules.
Prerequisites
-
The
kmod
package is installed.
Procedure
To display information about any kernel module, execute:
$ modinfo <KERNEL_MODULE_NAME> For example: $ modinfo virtio_net filename: /lib/modules/4.18.0-94.el8.x86_64/kernel/drivers/net/virtio_net.ko.xz license: GPL description: Virtio network driver rhelversion: 8.1 srcversion: 2E9345B281A898A91319773 alias: virtio:d00000001v* depends: net_failover intree: Y name: virtio_net vermagic: 4.18.0-94.el8.x86_64 SMP mod_unload modversions … parm: napi_weight:int parm: csum:bool parm: gso:bool parm: napi_tx:bool
The
modinfo
command displays some detailed information about the specified kernel module. You can query information about all available modules, regardless of whether they are loaded or not. Theparm
entries show parameters the user is able to set for the module, and what type of value they expect.NoteWhen entering the name of a kernel module, do not append the
.ko.xz
extension to the end of the name. Kernel module names do not have extensions; their corresponding files do.
Additional resources
-
For more information about the
modinfo
, refer to themodinfo(8)
manual page.
3.8. Loading kernel modules at system runtime
The optimal way to expand the functionality of the Linux kernel is by loading kernel modules. The following procedure describes how to use the modprobe
command to find and load a kernel module into the currently running kernel.
Prerequisites
- Root permissions
-
The
kmod
package is installed. - The respective kernel module is not loaded. To ensure this is the case, list the loaded kernel modules.
Procedure
Select a kernel module you want to load.
The modules are located in the
/lib/modules/$(uname -r)/kernel/<SUBSYSTEM>/
directory.Load the relevant kernel module:
# modprobe <MODULE_NAME>
NoteWhen entering the name of a kernel module, do not append the
.ko.xz
extension to the end of the name. Kernel module names do not have extensions; their corresponding files do.Optionally, verify the relevant module was loaded:
$ lsmod | grep <MODULE_NAME>
If the module was loaded correctly, this command displays the relevant kernel module. For example:
$ lsmod | grep serio_raw serio_raw 16384 0
The changes described in this procedure will not persist after rebooting the system.
Additional resources
-
For further details about
modprobe
, see themodprobe(8)
manual page.
3.9. Unloading kernel modules at system runtime
At times, you find that you need to unload certain kernel modules from the running kernel. The following procedure describes how to use the modprobe
command to find and unload a kernel module at system runtime from the currently loaded kernel.
Prerequisites
- Root permissions
-
The
kmod
package is installed.
Procedure
Execute the
lsmod
command and select a kernel module you want to unload.If a kernel module has dependencies, unload those prior to unloading the kernel module. For details on identifying modules with dependencies, see Section 3.4, “Listing currently loaded kernel modules”.
Unload the relevant kernel module:
# modprobe -r <MODULE_NAME>
When entering the name of a kernel module, do not append the
.ko.xz
extension to the end of the name. Kernel module names do not have extensions; their corresponding files do.WarningDo not unload kernel modules when they are used by the running system. Doing so can lead to an unstable or non-operational system.
Optionally, verify the relevant module was unloaded:
$ lsmod | grep <MODULE_NAME>
If the module was unloaded successfully, this command does not display any output.
After finishing this procedure, the kernel modules that are defined to be automatically loaded on boot, will not stay unloaded after rebooting the system. For information on how to counter this outcome, see Preventing kernel modules from being automatically loaded at system boot time.
Additional resources
-
For further details about
modprobe
, see themodprobe(8)
manual page.
3.10. Loading kernel modules automatically at system boot time
The following procedure describes how to configure a kernel module so that it is loaded automatically during the boot process.
Prerequisites
- Root permissions
-
The
kmod
package is installed.
Procedure
Select a kernel module you want to load during the boot process.
The modules are located in the
/lib/modules/$(uname -r)/kernel/<SUBSYSTEM>/
directory.Create a configuration file for the module:
# echo <MODULE_NAME> > /etc/modules-load.d/<MODULE_NAME>.conf
NoteWhen entering the name of a kernel module, do not append the
.ko.xz
extension to the end of the name. Kernel module names do not have extensions; their corresponding files do.Optionally, after reboot, verify the relevant module was loaded:
$ lsmod | grep <MODULE_NAME>
The example command above should succeed and display the relevant kernel module.
The changes described in this procedure will persist after rebooting the system.
Additional resources
-
For further details about loading kernel modules during the boot process, see the
modules-load.d(5)
manual page.
3.11. Preventing kernel modules from being automatically loaded at system boot time
The following procedure describes how to add a kernel module to a blacklist so that it will not be automatically loaded during the boot process.
Prerequisites
- Root permissions
-
The
kmod
package is installed. - Ensure that a blacklisted kernel module is not vital for your current system configuration.
Procedure
Select a kernel module that you want to blacklist:
$ lsmod Module Size Used by fuse 126976 3 xt_CHECKSUM 16384 1 ipt_MASQUERADE 16384 1 uinput 20480 1 xt_conntrack 16384 1 …
The
lsmod
command displays a list of modules loaded to the currently running kernel.Alternatively, identify an unloaded kernel module you want to prevent from potentially loading.
All kernel modules are located in the
/lib/modules/<KERNEL_VERSION>/kernel/<SUBSYSTEM>/
directory.
Create a blacklist configuration file:
# vim /etc/modprobe.d/blacklist.conf # Blacklists <KERNEL_MODULE_1> blacklist <MODULE_NAME_1> install <MODULE_NAME_1> /bin/false # Blacklists <KERNEL_MODULE_2> blacklist <MODULE_NAME_2> install <MODULE_NAME_2> /bin/false # Blacklists <KERNEL_MODULE_n> blacklist <MODULE_NAME_n> install <MODULE_NAME_n> /bin/false …
The example shows the contents of the
blacklist.conf
file, edited by thevim
editor. Theblacklist
line ensures that the relevant kernel module will not be automatically loaded during the boot process. Theblacklist
command, however, does not prevent the module from being loaded as a dependency for another kernel module that is not blacklisted. Therefore theinstall
line causes the/bin/false
to run instead of installing a module.The lines starting with a hash sign are comments to make the file more readable.
NoteWhen entering the name of a kernel module, do not append the
.ko.xz
extension to the end of the name. Kernel module names do not have extensions; their corresponding files do.Create a backup copy of the current initial ramdisk image before rebuilding:
# cp /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r).bak.$(date +%m-%d-%H%M%S).img
The command above creates a backup
initramfs
image in case the new version has an unexpected problem.Alternatively, create a backup copy of other initial ramdisk image which corresponds to the kernel version for which you want to blacklist kernel modules:
# cp /boot/initramfs-<SOME_VERSION>.img /boot/initramfs-<SOME_VERSION>.img.bak.$(date +%m-%d-%H%M%S)
Generate a new initial ramdisk image to reflect the changes:
# dracut -f -v
If you are building an initial ramdisk image for a different kernel version than you are currently booted into, specify both target
initramfs
and kernel version:# dracut -f -v /boot/initramfs-<TARGET_VERSION>.img <CORRESPONDING_TARGET_KERNEL_VERSION>
Reboot the system:
$ reboot
The changes described in this procedure will take effect and persist after rebooting the system. Improper blacklisting of a key kernel module can result in an unstable or non-operational system.
Additional resources
-
For further details concerning the
dracut
utility, refer to thedracut(8)
manual page.
3.12. Signing kernel modules for secure boot
You can enhance the security of your system by using signed kernel modules. The following sections describe how to self-sign privately built kernel modules for use with RHEL 8 on UEFI-based build systems where Secure Boot is enabled. These sections also provide an overview of available options for importing your public key into a target system where you want to deploy your kernel modules.
To sign and load kernel modules, you need to:
If Secure Boot is enabled, the UEFI operating system boot loaders, the Red Hat Enterprise Linux kernel, and all kernel modules have to be signed with a private key and authenticated with the corresponding public key. If they are not signed and authenticated, the system will not be allowed to finish the booting process.
The RHEL 8 distribution 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 8 to install, boot, and run with the Microsoft UEFI Secure Boot Certification Authority keys that are provided by the UEFI firmware on systems that support UEFI Secure Boot. Note that not all UEFI-based systems include support for Secure Boot.
Prerequisites
To be able to sign externally built kernel modules, install the utilities listed in the following table on the build system.
Table 3.1. Required utilities
Utility | Provided by package | Used on | Purpose |
---|---|---|---|
|
| Build system | Generates public and private X.509 key pair |
|
| Build system | Executable file used to sign a kernel module with the private key |
|
| Target system | Optional utility used to manually enroll the public key |
|
| Target system | Optional utility used to display public keys in the system keyring |
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.
3.12.1. Authenticating kernel modules with X.509 keys
In RHEL 8, when a kernel module is loaded, the module’s signature is checked using the public X.509 keys on the kernel’s system keyring (.builtin_trusted_keys
), excluding keys on the kernel’s system black-list keyring. The following sections provide an overview of sources of keys/keyrings and examples of loaded keys from different sources in the system. Also, the user can see what it takes to authenticate a kernel module.
3.12.1.1. Authentication requirements
This section explains what conditions have to be met for loading kernel modules on systems with enabled UEFI Secure Boot functionality.
If UEFI Secure Boot is enabled or if the module.sig_enforce
kernel parameter has been specified, you can only load signed kernel modules that are authenticated using a key on the system keyring (.builtin_trusted_keys
). In addition, the public key must not be on the system black-list keyring.
If UEFI Secure Boot is disabled and if the module.sig_enforce
kernel parameter has not been specified, you can load unsigned kernel modules and signed kernel modules without a public key. This is summarized in the table below.
Table 3.2. Kernel module authentication requirements for loading
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 |
3.12.1.2. Sources for public keys
During boot, the kernel loads X.509 keys into the system keyring (.builtin_trusted_keys
) or the system black-list keyring from a set of persistent key stores as shown in the table below.
Table 3.3. Sources for system keyrings
Source of X.509 keys | User ability to add keys | UEFI Secure Boot state | Keys loaded during boot |
---|---|---|---|
Embedded in kernel | No | - |
|
UEFI Secure Boot "db" | Limited | Not enabled | No |
Enabled |
| ||
Embedded in | No | Not enabled | No |
Enabled |
| ||
Machine Owner Key (MOK) list | Yes | Not enabled | No |
Enabled |
|
UEFI Secure Boot db is a signature database which stores keys (hashes) of UEFI applications, UEFI drivers, and bootloaders that can be loaded on the machine. Similarly, there exists UEFI Secure Boot dbx. This is a revoked signature database which prevents keys from being loaded.
.builtin_trusted_keys
is a keyring that is built on boot and contains trusted public keys. The keys are viewable by a user with root
privileges.
If the system is not UEFI-based or if UEFI Secure Boot is not enabled, then only the keys that are embedded in the kernel are loaded onto the system keyring (.builtin_trusted_keys
). In that case you have no ability to augment that set of keys without rebuilding the kernel.
The system black-list keyring is a list of X.509 keys which have been revoked. If your module is signed by a key on the black-list then it will fail authentication even if your public key is in the system keyring (.builtin_trusted_keys
).
You can display information about the keys on the system keyring (.builtin_trusted_keys
) using the keyctl
utility. The following is a shortened example output from a RHEL 8 system where UEFI Secure Boot is not enabled.
# keyctl list %:.builtin_trusted_keys
3 keys in keyring:
...asymmetric: Red Hat Enterprise Linux Driver Update Program (key 3): bf57f3e87...
...asymmetric: Red Hat Enterprise Linux kernel signing key: 4249689eefc77e95880b...
...asymmetric: Red Hat Enterprise Linux kpatch signing key: 4d38fd864ebe18c5f0b7...
The following is a shortened example output from a RHEL 8 system where UEFI Secure Boot is enabled.
# keyctl list %:.builtin_trusted_keys
6 keys in keyring:
...asymmetric: Red Hat Enterprise Linux Driver Update Program (key 3): bf57f3e87...
...asymmetric: Red Hat Secure Boot (CA key 1): 4016841644ce3a810408050766e8f8a29...
...asymmetric: Microsoft Corporation UEFI CA 2011: 13adbf4309bd82709c8cd54f316ed...
...asymmetric: Microsoft Windows Production PCA 2011: a92902398e16c49778cd90f99e...
...asymmetric: Red Hat Enterprise Linux kernel signing key: 4249689eefc77e95880b...
...asymmetric: Red Hat Enterprise Linux kpatch signing key: 4d38fd864ebe18c5f0b7...
The above output 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.efi
boot loader. You can also look for the kernel console messages that identify the keys with an UEFI Secure Boot related source. These include UEFI Secure Boot db, embedded shim, and MOK list.
# dmesg | grep 'EFI: Loaded cert'
[5.160660] EFI: Loaded cert 'Microsoft Windows Production PCA 2011: a9290239...
[5.160674] EFI: Loaded cert 'Microsoft Corporation UEFI CA 2011: 13adbf4309b...
[5.165794] EFI: Loaded cert 'Red Hat Secure Boot (CA key 1): 4016841644ce3a8...
3.12.1.3. Generating a public and private key pair
You need to generate a public and private X.509 key pair to succeed in your efforts of using kernel modules on a Secure Boot-enabled system. You will later use the private key to sign the kernel module. You will also have to add the corresponding public key to the Machine Owner Key (MOK) for Secure Boot to validate the signed module.
Some of the parameters for this key pair generation are best specified with a configuration file.
Procedure
Create a configuration file with parameters for the key pair generation:
# cat << EOF > configuration_file.config [ req ] default_bits = 4096 distinguished_name = req_distinguished_name prompt = no string_mask = utf8only x509_extensions = myexts [ req_distinguished_name ] O = Organization CN = Organization signing key emailAddress = E-mail address [ myexts ] basicConstraints=critical,CA:FALSE keyUsage=digitalSignature subjectKeyIdentifier=hash authorityKeyIdentifier=keyid EOF
Create an X.509 public and private key pair as shown in the following example:
# openssl req -x509 -new -nodes -utf8 -sha256 -days 36500 \ -batch -config configuration_file.config -outform DER \ -out my_signing_key_pub.der \ -keyout my_signing_key.priv
The public key will be written to the
my_signing_key_pub.der
file and the private key will be written to themy_signing_key.priv
file.ImportantIn RHEL 8, 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. For example, a key that is only valid in 2019 can be used to authenticate a kernel module signed in 2019 with that key. However, users cannot use that key to sign a kernel module in 2020.
Optionally, you can review the validity dates of your public keys like in the example below:
# openssl x509 -inform der -text -noout -in <my_signing_key_pub.der> Validity Not Before: Feb 14 16:34:37 2019 GMT Not After : Feb 11 16:34:37 2029 GMT
- Enroll your public key on all systems where you want to authenticate and load your kernel module.
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.
Additional resources
-
For more information about the
openssl
utility, see theopenssl(1)
manual page. -
For more information about using
openssl
, see the RHEL Security Guide - For details about enrolling public keys into target systems, see Section 3.12.2.2, “Manually adding public key to the MOK list”.
3.12.2. Enrolling public key on target system
When RHEL 8 boots on a UEFI-based system with Secure Boot enabled, the kernel loads onto the system keyring (.builtin_trusted_keys
) all public keys that are in the Secure Boot db key database. At the same time the kernel excludes the keys in the dbx database of revoked keys. The sections below describe different ways of importing a public key on a target system so that the system keyring (.builtin_trusted_keys
) is able to use the public key to authenticate a kernel module.
3.12.2.1. Factory firmware image including public key
To facilitate authentication 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.
3.12.2.2. Manually adding public key to the MOK list
The Machine Owner Key (MOK) facility feature can be used to expand the UEFI Secure Boot key database. When RHEL 8 boots on a UEFI-enabled system with Secure Boot enabled, the keys on the MOK list are also added to the system keyring (.builtin_trusted_keys
) in addition to the keys from the key database. The MOK list keys are also stored persistently and securely in the same fashion as the Secure Boot database keys, but these are two separate facilities. The MOK facility is supported by shim.efi
, MokManager.efi
, grubx64.efi
, and the mokutil
utility.
Enrolling a MOK key requires manual interaction by a user at the UEFI system console on each target system. Nevertheless, the MOK facility provides a convenient method for testing newly generated key pairs and testing kernel modules signed with them.
Procedure
Request the addition of your public key to the MOK list:
# mokutil --import my_signing_key_pub.der
You will be asked to enter and confirm a password for this MOK enrollment request.
Reboot the machine.
The pending MOK key enrollment request will be noticed by
shim.efi
and it will launchMokManager.efi
to allow you to complete the enrollment from the UEFI console.Enter the password you previously associated with this request 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 system keyring on this and subsequent boots when UEFI Secure Boot is enabled.
3.12.3. Signing kernel modules with the private key
Users are able to obtain enhanced security benefits on their systems by loading signed kernel modules if the UEFI Secure Boot mechanism is enabled. The following sections describe how to sign kernel modules with the private key.
Prerequisites
- You generated a public and private key pair and know the validity dates of your public keys. For details, see Section 3.12.1.3, “Generating a public and private key pair”.
- You enrolled your public key on the target system. For details, see Section 3.12.2, “Enrolling public key on target system”.
- You have a kernel module in ELF image format available for signing.
Procedure
Execute the
sign-file
utility with parameters as shown in the example below:# /usr/src/kernels/$(uname -r)/scripts/sign-file \ sha256 \ my_signing_key.priv \ my_signing_key_pub.der \ my_module.ko
sign-file
computes and appends the signature directly to the ELF image in your kernel module file. Themodinfo
utility can be used to display information about the kernel module’s signature, if it is present.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
readelf
will not be able to display the signature on your kernel module.Your kernel module is now ready for loading. Note that your signed kernel module is also loadable on systems where UEFI Secure Boot is disabled or on a non-UEFI system. That means you do not need to provide both a signed and unsigned version of your kernel module.
ImportantIn RHEL 8, 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 2019 can be used to authenticate a kernel module signed in 2019 with that key. However, users cannot use that key to sign a kernel module in 2020.
Additional resources
-
For details on using
modinfo
to obtain information about kernel modules, see Section 3.7, “Displaying information about kernel modules”.
3.12.4. Loading signed kernel modules
Once your public key is enrolled in the system keyring (.builtin_trusted_keys
) and the MOK list, and after you have signed the respective kernel module with your private key, you can finally load your signed kernel module with the the modprobe
command as described in the following section.
Prerequisites
- You have generated the public and private keypair. For details, see Section 3.12.1.3, “Generating a public and private key pair”.
- You have enrolled the public key into the system keyring. For details, see Section 3.12.2.2, “Manually adding public key to the MOK list”.
- You have signed a kernel module with the private key. For details, see Section 3.12.3, “Signing kernel modules with the private key”.
Procedure
Verify that your public keys are on the system keyring:
# keyctl list %:.builtin_trusted_keys
Copy the kernel module into the
/extra/
directory of the kernel you want:# cp my_module.ko /lib/modules/$(uname -r)/extra/
Update the modular dependency list:
# depmod -a
Load the kernel module and verify that it was successfully loaded:
# modprobe -v my_module # lsmod | grep my_module
Optionally, to load the module on boot, add it to the
/etc/modules-loaded.d/my_module.conf
file:# echo "my_module" > /etc/modules-load.d/my_module.conf
Additional resources
- For further information about loading kernel modules, see the relevant sections of Chapter 3, Managing kernel modules.