Are you curious about what a boot is and how it works? Look no further! Check out this informative article on Oracle Linux where you can learn about boot options, available kernels, and more. Plus, you’ll get to play with exciting tools and applications that will make your life easier. Discover how to change your booting kernel and even remove and reinstall a kernel from your system. Expand your knowledge and skills with Oracle Linux.
Let’s start with some essential definitions you should know, like:
- Linux Kernel – A kernel is the lowest level of easily replaceable software that interfaces with the hardware in your computer. It is responsible for interfacing all of your applications running in “user mode” down to the physical hardware and allowing processes, known as servers, to get information from each other using inter-process communication (IPC).
- Unbreakable Enterprise Kernel (UEK) – Oracle’s flavour of Linux kernel distro. It is a Linux kernel that has undergone some exciting modifications to make it more stable and secure when compared with other distros in the market. It also improves performance when using Oracle products within.
- Red Hat Compatible Kernel (RHCK) – As Oracle Linux is an open-source and fully binary compatible with Red Hat Enterprise Linux (RHEL), consequently, Oracle made available to anyone that requires to continue running their Linux systems as RHEL a version of its kernel called Red Hat Compatible Kernel (RHCK) that does not require you to continue paying licenses and support to Red Hat.
- Legacy BIOS firmware is a legacy boot process that uses BIOS firmware. It stores a list of bootable installed storage devices (such as Floppy Disk Drives, Hard Disk Drives, Optical Disk Drives, etc.) according to a configurable order of priority.
- UEFI-Based firmware – UEFI stands for Unified Extensible Firmware Interface. It does the same job as a BIOS, but with one fundamental difference: it contains data about the boot process (initialization and startup) in a boot loader executable .efi file, instead of storing it on the firmware.
- GRUB boot loader stands for Grand Unified Bootloader, available from the GNU project. GRUB is the default bootloader for many Linux distributions in the market. It is responsible for transferring the control to the operating system kernel after loading it into memory. Note that GRUB 2 is the default bootloader program used on Oracle Linux, and it can load many different operating systems in addition to Oracle Linux.
- grubby command – It is a command-line tool used to control and manage all of your boot requirements for brub, lilo, elilo (ia64), yaboot (PowerPC), and zipl (s390) boot loaders. In addition, this tool offers the benefit of being scriptable and can use the bootloader configuration added by the user.
- vmlinuz – The name of the bootable compressed Linux kernel executable.
- initramfs – A root filesystem embedded into the Linux kernel and loaded early in the boot process.
- Power-on self-test (POST) is a set of routines performed by firmware or software immediately after the hardware is powered on.
- GUID Partition Table (GPT) – it’s a way of storing partitioning information on a drive that includes information like where partitions begin and end on a physical disk for example. GPT is a new standard that gradually replaces the Master Boot Record (MBR) standard previously widely used. GPT doesn’t suffer from MBR’s limits like the number of partitions and drivers’ size, with size limits dependent on the operating system and its file systems. Note that GPT is the type of partition table required by UEFI and was initiated by Intel.
- Master Boot Record (MBR) – It is as GPT a small program executed when the hardware is booting to find the operation system and load it to memory introduced in 1983 with PC DOS 2.0. As previously discussed within GPT, MBR also holds how the file systems’ logical partitions are organized. In addition, it includes all required executable code to function as a loader for the installed operating system. The MBR code is commonly referenced as a bootloader.
- Systemd –
Systemd
provides a standard process for controlling what programs run when a Linux system boots up. Whilesystemd
is compatible withSysV
and Linux Standard Base (LSB) initialization scripts,systemd
is meant to be a drop-in replacement for these older ways of getting a Linux system running. - SysV – This is an older process introduced within the original Unix version. It was later replaced by
systemd
what many distros are moving towards. You can quickly identify if your system usessystemd
orsystemv
(SysV
) by the way, you start and stop it. If you use the command “systemctl
” to start and stop things, you are then on asystemd
system. If you use the command “/etc/init.d/
” to start and stop something, you are then on asystemv
system. - Strength of Mechanism is the ability of a mechanism to resist an intentional or unintentional failure.
- The Root of Trust (RoT) is an idempotent mechanism whose result asserts a fact or property.
- Dynamic Launch is a system launch that can be done repeatedly with the execution code residing at different locations in memory.
- Measure Boot is a system where each component involved is measured through a transitive trust sequence, for example, a trust chain, to record what firmware/software was used to launch a platform.
- The Root of Trust for Measurement (RTM) is the first component in the transitive trust chain.
- Core Root of Trust Measurement (CRTM) is the first measurement generated by the RTM.
- The kind of RoT differentiates the two common types of x86 measured boot used to establish the trust chain:
- A Static Root of Trust is typically rooted in mutable software and driven by a Static Launch.
- A Dynamic Root of Trust is typically rooted in hardware and driven by a Dynamic Launch.
By default, Oracle Linux systems are configured to boot to the most recent kernel version first. Therefore, in most cases, changing the default kernel is unnecessary.
However, the default kernel might not be the correct version to use in specific scenarios, as per example:
- The current kernel version might be incompatible with the particular hardware you are using.
- Cases involving Unbreakable Enterprise Kernel (UEK) releases on the system.
- UEK releases are typically based on kernel versions that are newer than the Red Hat Compatible Kernel (RHCK) version on which an Oracle Linux release is based. Thus, the new UEK version becomes the default kernel, unlike the Oracle Linux kernel.
- Suppose a UEK beta or technical preview release is installed on the system. In that case, the UEK kernel needs to be demoted to ensure that the kernel is used only if intentionally and manually selected as the boot kernel by an administrator.
- A UEK kernel might need to be promoted because a specific software depends on it.
These examples and similar cases would require you to switch between kernel types. In previous releases, setting the default kernel was performed by configuring the GRUB boot loader or using other alternative commands. However, you should preferably use the grubby command to control and manage all of your boot requirements.
To easily understand all these, let’s start first by taking a deeper look at the boot process itself.
The Boot Process
Understanding the Oracle Linux boot process would help you quickly troubleshoot any possible problems you could afront while booting a system. The boot process generally involves several files, and errors in these files are the usual cause of boot problems. When an Oracle Linux system boots, it performs many operations, and they vary depending on the type of firmware your hardware uses to handle the system boot. It could be UEFI firmware or legacy BIOS firmware.
The UEFI-Based Booting Sequence
The following sequence order is used by UEFI-Based booting hardware:
-
- The hardware’s UEFI firmware performs a power-on self-test (called POST) and then locates and initializes all peripheral devices, including the hard disk.
- UEFI searches for a GPT partition with a specific globally unique identifier (GUID) that identifies it as the EFI System Partition (ESP), containing EFI applications such as booters. In the case of multiple boot devices, the UEFI boot manager determines the appropriate ESP to use based on the order defined in the boot manager. With the
efibootmgr
tool, you can specify a different order if you do not use the default definition. - The UEFI boot manager checks to determine whether Secure Boot is enabled. If Secure Boot is not enabled, the Boot Manager runs the GRUB 2 boot loader on the ESP. Otherwise, the boot manager requests a certificate from the boot loader and validates this against keys stored in the UEFI Secure Boot key database. The environment is configured to perform a 2-stage boot process and shim to handle the certificate validation efi application that is responsible for the certification is loaded first before loading the GRUB 2 boot loader. If the certificate is valid, the boot loader runs and, in turn, validates the kernel that it is configured to load.
- The boot loader loads the
vmlinuz
kernel image file into memory and extracts the contents of the initramfs
image file into a temporary memory-based file system calledtmpfs
. - The kernel loads the driver modules from the
initramfs
file system that is needed to access the root file system. - The kernel starts the
systemd
process with a process ID of 1 (PID 1). - The
systemd
process will run any additional processes defined for it. You can specify any other actions to be processed during the boot process by defining yoursystemd
This method is preferred to be used instead of using the/etc/rc.local
file approach.
The Legacy BIOS Sequence
A Legacy BIOS booting hardware uses the following sequence order:
-
- The computer’s BIOS performs a power-on self-test (POST) and then locates and initializes any peripheral devices, including the hard disk.
- The BIOS reads the Master Boot Record (MBR) into memory from the boot device. The MBR stores information about the organization of partitions on that device, the partition table, and the boot signature used for error detection. Additionally, the MBR includes the pointer to the boot loader program called GRUB 2. The boot program itself can be on the same device or on another device.
- The boot loader loads the
vmlinuz
kernel image into memory and extracts the contents of theinitramfs
image file into a temporary memory-based file system calledtmpfs
. - The kernel loads the driver modules from the
initramfs
file system required to access the root file system. - The kernel starts the
systemd
process with a process ID of 1 (PID 1). - The
systemd
process runs any other processes defined for it. You can specify any additional actions to be processed during the boot process by defining yoursystemd
unit. This method is preferred to be used instead of using the/etc/rc.local
file approach.
Playing with Boot options and Kernels?
Now that we completed the basics, we can leave behind all the boring parts and get to the action. It is time to play and learn!
One of the first things we can do is determine the currently loaded kernel in our system. The following command will display all kernels that are installed and configured within our Linux system (please run as root):
# grubby -–info=ALL
Here is one example of the output:
[root@localhost falvarez]# grubby --info=ALL
index=0
kernel="/boot/vmlinuz-5.4.17-2136.302.7.2.3.el8uek.x86_64"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-5.4.17-2136.302.7.2.3.el8uek.x86_64.img $tuned_initrd"
title="Oracle Linux Server 8 (5.4.17-2136.302.7.2.3.el8uek.x86_64) "
id="c32316cc4b5241b8adb312707ae46458-5.4.17-2136.302.7.2.3.el8uek.x86_64"
index=1
kernel="/boot/vmlinuz-5.4.17-2011.7.4.el8uek.x86_64"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-5.4.17-2011.7.4.el8uek.x86_64.img $tuned_initrd"
title="Oracle Linux Server 8 (5.4.17-2011.7.4.el8uek.x86_64) "
id="c32316cc4b5241b8adb312707ae46458-5.4.17-2011.7.4.el8uek.x86_64"
index=2
kernel="/boot/vmlinuz-4.18.0-348.12.2.el8_5.x86_64"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-4.18.0-348.12.2.el8_5.x86_64.img $tuned_initrd"
title="Oracle Linux Server (4.18.0-348.12.2.el8_5.x86_64) 8.5"
id="c32316cc4b5241b8adb312707ae46458-4.18.0-348.12.2.el8_5.x86_64"
index=3
kernel="/boot/vmlinuz-4.18.0-240.el8.x86_64"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-4.18.0-240.el8.x86_64.img $tuned_initrd"
title="Oracle Linux Server (4.18.0-240.el8.x86_64) 8.3"
id="c32316cc4b5241b8adb312707ae46458-4.18.0-240.el8.x86_64"
index=4
kernel="/boot/vmlinuz-0-rescue-c32316cc4b5241b8adb312707ae46458"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-0-rescue-c32316cc4b5241b8adb312707ae46458.img"
title="Oracle Linux Server (0-rescue-c32316cc4b5241b8adb312707ae46458) 8.3"
id="c32316cc4b5241b8adb312707ae46458-0-rescue"
[root@localhost falvarez]#
We can also determine the default kernel in use by executing the following command:
#grubby -–info=DEFAULT
Here is one example of an output:
[root@localhost falvarez]# grubby --info=DEFAULT
index=0
kernel="/boot/vmlinuz-5.4.17-2136.302.7.2.3.el8uek.x86_64"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-5.4.17-2136.302.7.2.3.el8uek.x86_64.img $tuned_initrd"
title="Oracle Linux Server 8 (5.4.17-2136.302.7.2.3.el8uek.x86_64) "
id="c32316cc4b5241b8adb312707ae46458-5.4.17-2136.302.7.2.3.el8uek.x86_64"
[root@localhost falvarez]#
We can configure a specific kernel to be used as the default boot kernel by running the following command:
#grubby –-set-default <Kernel>
Here is one example of using the above command to change the default kernel in use.
[root@localhost falvarez]# grubby --set-default /boot/vmlinuz-4.18.0-348.12.2.el8_5.x86_64
The default is /boot/loader/entries/c32316cc4b5241b8adb312707ae46458-4.18.0-348.12.2.el8_5.x86_64.conf with index 2 and kernel /boot/vmlinuz-4.18.0-348.12.2.el8_5.x86_64
[root@localhost falvareZ]# grubby --info=DEFAULT
index=2
kernel="/boot/vmlinuz-4.18.0-348.12.2.el8_5.x86_64"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-4.18.0-348.12.2.el8_5.x86_64.img $tuned_initrd"
title="Oracle Linux Server (4.18.0-348.12.2.el8_5.x86_64) 8.5"
id="c32316cc4b5241b8adb312707ae46458-4.18.0-348.12.2.el8_5.x86_64"
[root@localhost falvarez]#
Another possible use of the grubby
command is to use it to update a kernel configuration entry or to add or remove boot arguments that should be passed to the kernel by default; below is one example of it, but, first, we show all kernel information of a specific kernel in the system.
[root@localhost falvarez]# grubby --info=/boot/vmlinuz-0-rescue-c32316cc4b5241b8adb312707ae46458
index=4
kernel="/boot/vmlinuz-0-rescue-c32316cc4b5241b8adb312707ae46458"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-0-rescue-c32316cc4b5241b8adb312707ae46458.img"
title="Oracle Linux Server (0-rescue-c32316cc4b5241b8adb312707ae46458) 8.3"
id="c32316cc4b5241b8adb312707ae46458-0-rescue"
[root@localhost falvarez]#
Now from the above kernel details we would remove the “rhgb quiet”
configuration from the kernel arguments and add a new one “test” by using the following command:
[root@localhost falvarez]# grubby --remove-args="rhgb quiet" --args=test --update-kernel /boot/vmlinuz-0-rescue-c32316cc4b5241b8adb312707ae46458
[root@localhost falvarez]#
As you can see above, we used the Kernel Name to update the arguments on that kernel (we used the –-remove-args
attribute to remove an argument configuration and the args
attribute to add a new one). Now we can check if the argument’s structure changed by running the grubby –-info
command again.
[root@localhost falvarez]# grubby --info=/boot/vmlinuz-0-rescue-c32316cc4b5241b8adb312707ae46458
index=4
kernel="/boot/vmlinuz-0-rescue-c32316cc4b5241b8adb312707ae46458"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap test"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-0-rescue-c32316cc4b5241b8adb312707ae46458.img"
title="Oracle Linux Server (0-rescue-c32316cc4b5241b8adb312707ae46458) 8.3"
id="c32316cc4b5241b8adb312707ae46458-0-rescue"
[root@localhost falvarez]#
Note: You can always use the command man grubby to review all options available within the grubby command.
Switching the default UEK kernel to RHCK and vice versa
As mentioned before, Oracle Linux comes with two available flavors of kernels to use, the Unbreakable Enterprise Kernel (UEK), which is Oracle’s installed by default flavor of Linux kernel distro, and the Red Hat Compatible Kernel (RHCK), which is Oracle version of Linux that is fully binary compatible within Red Hat Enterprise Linux (RHEL) kernel.
This section will teach you how to switch the default kernel (UEK) to the RHCK kernel and vice-versa. So, let’s get started.
First, once again, we will use the grubby command to check the default kernel in use and again, to check all kernels available within your system, by using the commands: grubby -–info=DEFAULT
and grubby –-info=ALL
[root@localhost falvarez]# grubby --info=DEFAULT
index=2
kernel="/boot/vmlinuz-4.18.0-348.12.2.el8_5.x86_64"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-4.18.0-348.12.2.el8_5.x86_64.img $tuned_initrd"
title="Oracle Linux Server (4.18.0-348.12.2.el8_5.x86_64) 8.5"
id="c32316cc4b5241b8adb312707ae46458-4.18.0-348.12.2.el8_5.x86_64"
[root@localhost falvarez]#
In the above example, you can see that in this case, the default kernel in use is the "/boot/vmlinuz-4.18.0-348.12.2.el8_5.x86_64"
, which is an RHCK flavour of the kernel. You can also check the current kernel using the uname -r
command.
[root@localhost falvarez]# uname -r
4.18.0-348.12.2.el8_5.x86_64
[root@localhost falvarez]#
To check all kernels available in the system we could use the grubby –info
command as shown below.
[root@localhost falvarez]# grubby --info=ALL
index=0
kernel="/boot/vmlinuz-5.4.17-2136.302.7.2.3.el8uek.x86_64"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-5.4.17-2136.302.7.2.3.el8uek.x86_64.img $tuned_initrd"
title="Oracle Linux Server 8 (5.4.17-2136.302.7.2.3.el8uek.x86_64) "
id="c32316cc4b5241b8adb312707ae46458-5.4.17-2136.302.7.2.3.el8uek.x86_64"
index=1
kernel="/boot/vmlinuz-5.4.17-2011.7.4.el8uek.x86_64"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-5.4.17-2011.7.4.el8uek.x86_64.img $tuned_initrd"
title="Oracle Linux Server 8 (5.4.17-2011.7.4.el8uek.x86_64) "
id="c32316cc4b5241b8adb312707ae46458-5.4.17-2011.7.4.el8uek.x86_64"
index=2
kernel="/boot/vmlinuz-4.18.0-348.12.2.el8_5.x86_64"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-4.18.0-348.12.2.el8_5.x86_64.img $tuned_initrd"
title="Oracle Linux Server (4.18.0-348.12.2.el8_5.x86_64) 8.5"
id="c32316cc4b5241b8adb312707ae46458-4.18.0-348.12.2.el8_5.x86_64"
index=3
kernel="/boot/vmlinuz-4.18.0-240.el8.x86_64"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-4.18.0-240.el8.x86_64.img $tuned_initrd"
title="Oracle Linux Server (4.18.0-240.el8.x86_64) 8.3"
id="c32316cc4b5241b8adb312707ae46458-4.18.0-240.el8.x86_64"
index=4
kernel="/boot/vmlinuz-0-rescue-c32316cc4b5241b8adb312707ae46458"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap test"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-0-rescue-c32316cc4b5241b8adb312707ae46458.img"
title="Oracle Linux Server (0-rescue-c32316cc4b5241b8adb312707ae46458) 8.3"
id="c32316cc4b5241b8adb312707ae46458-0-rescue"
[root@localhost falvarez]#
Or by using the rpm -qa kernel*
(Please note that when using the rpm command it would also display all kernel-related packages), and the ls -l /boot/vmlinux*
commands.
[root@localhost falvarez]# rpm -qa kernel*
kernel-uek-5.4.17-2011.7.4.el8uek.x86_64
kernel-tools-libs-4.18.0-348.12.2.el8_5.x86_64
kernel-core-4.18.0-240.el8.x86_64
kernel-modules-4.18.0-240.el8.x86_64
kernel-core-4.18.0-348.12.2.el8_5.x86_64
kernel-uek-5.4.17-2136.302.7.2.3.el8uek.x86_64
kernel-tools-4.18.0-348.12.2.el8_5.x86_64
kernel-4.18.0-240.el8.x86_64
kernel-devel-4.18.0-348.12.2.el8_5.x86_64
kernel-headers-4.18.0-348.12.2.el8_5.x86_64
kernel-4.18.0-348.12.2.el8_5.x86_64
kernel-modules-4.18.0-348.12.2.el8_5.x86_64
[root@localhost falvarez]#
[root@localhost falvarez]# ls -l /boot/vmlinuz*
-rwxr-xr-x. 1 root root 8922664 Feb 10 14:28 /boot/vmlinuz-0-rescue-c32316cc4b5241b8adb312707ae46458
-rwxr-xr-x. 1 root root 9516568 Nov 6 2020 /boot/vmlinuz-4.18.0-240.el8.x86_64
-rwxr-xr-x. 1 root root 10225200 Jan 21 07:39 /boot/vmlinuz-4.18.0-348.12.2.el8_5.x86_64
-rwxr-xr-x. 1 root root 8922664 Oct 3 2020 /boot/vmlinuz-5.4.17-2011.7.4.el8uek.x86_64
-rwxr-xr-x. 1 root root 10368576 Feb 9 05:23 /boot/vmlinuz-5.4.17-2136.302.7.2.3.el8uek.x86_64
[root@localhost falvarez]#
When checking all available kernels, we can quickly identify two versions of UEK kernels available and two versions of RHCK kernels available. For this example, we will use the UEK kernel called “/boot/vmlinuz-5.4.17-2136.302.7.2.3.el8uek.x86_64”
. So now, let’s use the grubby –-set-default
command to make the selected UEK kernel the new default.
[root@localhost falvarez]# grubby --set-default=/boot/vmlinuz-5.4.17-2136.302.7.2.3.el8uek.x86_64
The default is /boot/loader/entries/c32316cc4b5241b8adb312707ae46458-5.4.17-2136.302.7.2.3.el8uek.x86_64.conf with index 0 and kernel /boot/vmlinuz-5.4.17-2136.302.7.2.3.el8uek.x86_64
[root@localhost falvarez]#
And that’s it; now, all we need to do is reboot the system to reflect the kernel change. Then, if you want to switch it back to the previous RHCK flavour of the kernel, all you need to do is run the grubby –-set-default
command again, but this time specifying a name of the RCHK flavour available of your preference.
Unified Extensible Firmware Interface (UEFI)
The Operation System (OS) security requires that every layer below the OS layer be secure. In other words, you cannot run software if it cannot be trusted to execute a code correctly because untrusted software can readily temper your bootloader or, even worse, have your firmware compromised. To solve this, security requires a newer method for booting systems called the Unified Extensible Firmware Interface (UEFI) was implemented in the firmware, becoming the interface between your hardware and the OS, replacing the legacy Basic Input/Output System (BIOS) firmware that was previously the industry default. As a Secure Boot method, it ensures that your system boots by only using software trusted by the hardware manufacturer of your system in use. In addition, it provides a verification mechanism (by verifying each piece of boot software by using cryptographic checksums and signatures) to ensure that the code that is launched is trusted by validating the boot loader before executing it (even before loading the OS). IF AVAILABLE, many UEFI systems can also boot in legacy BIOS mode via a compatibility support module.
To boot in UEFI mode, Oracle Linux requires the UEFI firmware to be present during the system installation as it is detected at installation time. Next, a GUID Partition Table (GPT) is automatically set up, creating an EFI System Partition (ESP) on the /boot/efi
mount, which contains the files needed for the UEFI booting. If doing manual partitioning, the ESP must be explicitly specified.
Now let’s run the df -h command to view the partitions in the system; please notice that the /boot/efi
is mounted on the /dev/sda1
partition in this example.
[root@localhost falvarez]# df -h
Filesystem Size Used Avail Use% Mounted on
devtmpfs 2.2G 0 2.2G 0% /dev
tmpfs 2.2G 0 2.2G 0% /dev/shm
tmpfs 2.2G 9.3M 2.2G 1% /run
tmpfs 2.2G 0 2.2G 0% /sys/fs/cgroup
/dev/mapper/ol-root 17G 5.3G 12G 32% /
/dev/sda2 1014M 341M 674M 34% /boot
/dev/sda1 599M 5.1M 594M 1% /boot/efi
tmpfs 439M 20K 439M 1% /run/user/1000
/dev/sr0 59M 59M 0 100% /run/media/falvarez/VBox_GAs_6.1.32
[root@localhost falvarez]#
If running the command ls -l /boot/efi/EFI/redhat/
this directory contains a first-stage bootloader called shimx64.efi
, the GRUB 2 bootloader called grubx64.efi and the GRU2 configuration file called grub.cfg
. The location of the grub.cfg
file is different when in BIOS mode as it resides in the /boot/grub2
.
[root@localhost falvarez]# ls -l /boot/efi/EFI/redhat
total 4112
-rwx------. 1 root root 134 Aug 27 15:51 BOOTX64.CSV
drwx------. 2 root root 4096 Oct 15 19:59 fonts
-rwx------. 1 root root 6545 Feb 14 20:45 grub.cfg
-rwx------. 1 root root 1024 Feb 14 22:31 grubenv
-rwx------. 1 root root 1024 Feb 14 21:15 grubenvRvxfzJ
-rwx------. 1 root root 2288320 Oct 15 19:59 grubx64.efi
-rwx------. 1 root root 905400 Aug 27 15:51 mmx64.efi
-rwx------. 1 root root 984688 Aug 27 15:51 shimx64.efi
[root@localhost falvarez]#
The file /etc/default/grub
file is responsible for containing the user settings for the grub.cfg
file. Note that this file is also located at the same location when in BIOS mode; furthermore if you make any changes to this file, the grub.cfg
file will require to be rebuilt.
[root@localhost falvarez]# cat /etc/default/grub
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet"
GRUB_DISABLE_RECOVERY="true"
GRUB_ENABLE_BLSCFG=true
[root@localhost falvarez]#
To rebuild the grub.cfg
file, please use the grup2-mkconfig
command specifying the output file, using the -o
option, as /boot/efi/EFI/redhat/grub.cfg
.
[root@localhost falvarez]# grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg
Generating grub configuration file ...
Adding boot menu entry for EFI firmware configuration
done
[root@localhost falvarez]#
The utility used to manage the UEFI boot process is called “efibootmgr
” (it provides a boot menu showing the boot entries). It also allows manipulating boot entries by:
-
- Altering the boot order
- Creating boot entries
- Removing boot entries
- Specifying the boot entry for the next boot
You can view a summary of boot entries by running the efibootmgr
command with no options, or for more details, add the -v
option to it.
[root@localhost falvarez]# efibootmgr
BootCurrent: 0004
Timeout: 0 seconds
BootOrder: 0004,0000,0001,0002,0003
Boot0000* UiApp
Boot0001* UEFI VBOX CD-ROM VB2-01700376
Boot0002* UEFI VBOX HARDDISK VB2d5be0c5-80049c5d
Boot0003* EFI Internal Shell
Boot0004* Oracle Linux
[root@localhost falvarez]# efibootmgr -v
BootCurrent: 0004
Timeout: 0 seconds
BootOrder: 0004,0000,0001,0002,0003
Boot0000* UiApp FvVol(7cb8bdc9-f8eb-4f34-aaea-3ee4af6516a1)/FvFile(462caa21-7614-4503-836e-8ab6f4662331)
Boot0001* UEFI VBOX CD-ROM VB2-01700376 PciRoot(0x0)/Pci(0x1,0x1)/Ata(1,0,0)N.....YM....R,Y.
Boot0002* UEFI VBOX HARDDISK VB2d5be0c5-80049c5d PciRoot(0x0)/Pci(0xd,0x0)/Sata(0,65535,0)N.....YM....R,Y.
Boot0003* EFI Internal Shell FvVol(7cb8bdc9-f8eb-4f34-aaea-3ee4af6516a1)/FvFile(7c04a583-9e3e-4f1c-ad65-e05268d0b4d1)
Boot0004* Oracle Linux HD(1,GPT,dff50c5d-96ed-406c-9823-212649b405bd,0x800,0x12c000)/File(\EFI\redhat\shimx64.efi)
[root@localhost falvarez]#
As per the example above, you can see that boot 0004 (Oracle Linux) is the boot entry used to start the currently running system, called BootCurrent. The BootOrder is the boot order used in the boot manager; consequently, the boot manager will boot the first active entry in the list. If not successful, it will try the next entry and so on. Please use the man command to learn more about the efibootmgr
command.
Playing with Secure Boot
The Secure Boot is an additional or optional feature implemented in UEFI intended to help avoid malware execution during a boot process. You can enable and disable it by accessing your system (hardware) EFI setup program.
The Secure Boot steps are identical to the regular UEFI booting nut. The important exception is that it requires the components to be signed and authenticated to be loaded and executed (private and public key pairs are used for authentication). It consists of two launch Roots of Trust to build the transitive trust chains, they are:
-
- The Verification Root of Trust is responsible for the signature verification, and
- The Measurement Root of Trust is responsible for the measurement collection.
- The Verification RoT is the launch RoT that most refer to when speaking about Secure Boot, and it will lie on Boot Flash as RoT for storage to protect the key database.
- Verify only after DXE (Driver eXecution Environment) phase, not during the SEC (SECurity) phase.
The Secure Boot will establish a chain of trust by:
-
- First, the first-stage bootloader (
shim
) signed by Oracle and Microsoft is authenticated and then loads the GRUB 2 loader. - The GRUB 2 bootloader validated the kernel signature signed by Oracle and authenticated it before loading and executing the kernel.
- The Kernel signed by Oracle is Authenticated and executed. Loads signed/authenticated kernel modules only (as per example: all kernel modules included with the kernel RPM and those used with Oracle Ksplice have the corresponding Oracle signatures and the signed/authenticated running validated, or they would not be loaded).
- First, the first-stage bootloader (
Now that we have covered some basics regarding the topic, let’s learn how to sign kernel modules with Secure Boot. First, before you can sign a module, you will need to install several required packages, including the kernel source for the kernel where the modules are loaded. Furthermore, a signing certificate for a key pair created for this purpose is also required.
Installing all Required Packages
If you are using the Unbreakable Enterprise Kernel (UEK), the kernel source is available in the kernel-uek-devel
package. When using the UEFI Secure Boot functionality, Oracle recommends installing and using UEK.
[root@localhost falvarez]# dnf install kernel-uek-devel
Last metadata expiration check: 0:00:09 ago on Tue 15 Feb 2022 09:32:36 PM EST.
Package kernel-uek-devel-5.4.17-2136.300.7.el8uek.x86_64 is already installed.
Dependencies resolved.
====================================================================================== Package Architecture Version Repository Size
======================================================================================Installing:
kernel-uek-devel x86_64 5.4.17-2136.304.4.1.el8uek ol8_UEKR6 18 M
Transaction Summary
======================================================================================Install 1 Package
Total download size: 18 M
Installed size: 74 M
Is this ok [y/N]: y
Downloading Packages:
kernel-uek-devel-5.4.17-2136.304.4.1.el8uek.x86_64.rpm 374 kB/s | 18 MB 00:49
--------------------------------------------------------------------------------------
Total 374 kB/s | 18 MB 00:49
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : kernel-uek-devel-5.4.17-2136.304.4.1.el8uek.x86_64 1/1
Running scriptlet: kernel-uek-devel-5.4.17-2136.304.4.1.el8uek.x86_64 1/1
Verifying : kernel-uek-devel-5.4.17-2136.304.4.1.el8uek.x86_64 1/1
Installed:
kernel-uek-devel-5.4.17-2136.304.4.1.el8uek.x86_64
Complete!
[root@localhost falvarez]#
As a good practice, it is always recommended to update the system to ensure that you have the most recent kernel and related packages available.
[root@localhost falvarez]# dnf update
Last metadata expiration check: 0:11:18 ago on Tue 15 Feb 2022 09:32:36 PM EST.
Dependencies resolved.
===========================================================================================
Package Arch Version Repository Size
===========================================================================================
Installing:
kernel x86_64 4.18.0-348.12.2.el8_5 ol8_baseos_latest 7.0 M
Upgrading:
accountsservice x86_64 0.6.55-2.el8_5.2 ol8_appstream 139 k
accountsservice-libs x86_64 0.6.55-2.el8_5.2 ol8_appstream 96 k
binutils x86_64 2.30-108.0.2.el8_5.1 ol8_baseos_latest 5.9 M
…
Transaction Summary
===========================================================================================
Install 5 Packages
Upgrade 173 Packages
Total download size: 483 M
Is this ok [y/N]: y
Downloading Packages:
(1/178): grub2-tools-efi-2.02-106.0.2.el8.x86_64.rpm 56 kB/s | 476 kB 00:08
(2/178): kernel-4.18.0-348.12.2.el8_5.x86_64.rpm 138 kB/s | 7.0 MB 00:51
…
(178/178): vim-minimal-8.0.1763-16.0.1.el8_5.4.x86_64.rpm 734 kB/s | 574 kB 00:00
-------------------------------------------------------------------------------------------
Total 307 kB/s | 483 MB 26:53
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Running scriptlet: libgcc-8.5.0-4.0.2.el8_5.x86_64 1/1
Upgrading : libgcc-8.5.0-4.0.2.el8_5.x86_64 1/351
…
Verifying : xfsprogs-5.0.0-9.el8.x86_64 351/351
Upgraded:
accountsservice-0.6.55-2.el8_5.2.x86_64
accountsservice-libs-0.6.55-2.el8_5.2.x86_64
…
xfsprogs-5.4.0-1.0.1.el8.x86_64
Installed:
grub2-tools-efi-1:2.02-106.0.2.el8.x86_64
kernel-4.18.0-348.12.2.el8_5.x86_64
kernel-core-4.18.0-348.12.2.el8_5.x86_64
kernel-modules-4.18.0-348.12.2.el8_5.x86_64
kernel-uek-5.4.17-2136.304.4.1.el8uek.x86_64
Complete!
[root@localhost falvarez]#
As you can see in the example above, our system required the installation of 5 packages and 173 others to be upgraded.
It is time to install the utilities required to perform the module signing operations (openssl
, keyutils
, mokutil
, and pesign
).
[root@localhost falvarez]# dnf install openssl keyutils mokutil pesign
Last metadata expiration check: 1:05:13 ago on Tue 15 Feb 2022 09:32:36 PM EST.
Package openssl-1:1.1.1k-5.el8_5.x86_64 is already installed.
Package keyutils-1.5.10-9.el8.x86_64 is already installed.
Package mokutil-1:0.3.0-11.0.1.el8.x86_64 is already installed.
Dependencies resolved.
======================================================================================
Package Architecture Version Repository Size
======================================================================================
Installing:
pesign x86_64 0.112-25.0.2.el8 ol8_appstream 182 k
Installing dependencies:
nss-tools x86_64 3.67.0-7.el8_5 ol8_appstream 576 k
Transaction Summary
======================================================================================
Install 2 Packages
Total download size: 758 k
Installed size: 3.3 M
Is this ok [y/N]: y
Downloading Packages:
(1/2): pesign-0.112-25.0.2.el8.x86_64.rpm 198 kB/s | 182 kB 00:00
(2/2): nss-tools-3.67.0-7.el8_5.x86_64.rpm 429 kB/s | 576 kB 00:01
--------------------------------------------------------------------------------------
Total 562 kB/s | 758 kB 00:01
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : nss-tools-3.67.0-7.el8_5.x86_64 1/2
Running scriptlet: pesign-0.112-25.0.2.el8.x86_64 2/2
Installing : pesign-0.112-25.0.2.el8.x86_64 2/2
Running scriptlet: pesign-0.112-25.0.2.el8.x86_64 2/2
[/usr/lib/tmpfiles.d/pesign.conf:1] Line references path below legacy directory /var/run/, updating /var/run/pesign → /run/pesign; please update the tmpfiles.d/ drop-in file accordingly.
Verifying : nss-tools-3.67.0-7.el8_5.x86_64 1/2
Verifying : pesign-0.112-25.0.2.el8.x86_64 2/2
Installed:
nss-tools-3.67.0-7.el8_5.x86_64
pesign-0.112-25.0.2.el8.x86_64
Complete!
[root@localhost falvarez]#
If you require to build a module source, you can optionally install the Development Tools
group to ensure that the option to create tools would be available to you.
[root@localhost falvarez]# dnf group install "Development Tools"
Last metadata expiration check: 1:10:58 ago on Tue 15 Feb 2022 09:32:36 PM EST.
Dependencies resolved.
======================================================================================
Package Arch Version Repository Size
======================================================================================
Installing group/module packages:
asciidoc noarch 8.6.10-0.5.20180627gitf7c2274.el8 ol8_appstream 216 k
autoconf noarch 2.69-29.el8 ol8_appstream 710 k
…
zstd x86_64 1.4.4-1.0.1.el8 ol8_appstream 393 k
Enabling module streams:
javapackages-runtime 201801
Installing Groups:
Development Tools
Transaction Summary
======================================================================================
Install 83 Packages
Total download size: 100 M
Installed size: 354 M
Is this ok [y/N]: y
Downloading Packages:
(1/83): elfutils-libelf-devel-0.185-1.el8.x86_64.rpm 115 kB/s | 59 kB 00:00
(2/83): elfutils-devel-0.185-1.el8.x86_64.rpm 153 kB/s | 86 kB 00:00
…
--------------------------------------------------------------------------------------
Total 262 kB/s | 100 MB 06:31
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Running scriptlet: copy-jdk-configs-4.0-2.el8.noarch 1/1
Verifying : zstd-1.4.4-1.0.1.el8.x86_64 83/83
Installed:
asciidoc-8.6.10-0.5.20180627gitf7c2274.el8.noarch
…
zstd-1.4.4-1.0.1.el8.x86_64
Complete!
[root@localhost falvarez]#
Creating the Signing Certificate
Create a configuration file that OpenSSL can use to obtain default values when generating your certificates. You can create this file at any location, but it is useful to keep it with the rest of your OpenSSL configuration in /etc/ssl/x509.conf
. The file should look similar to the following:
[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
prompt = no
string_mask = utf8only
x509_extensions = extensions
[ req_distinguished_name ]
O = Module Signing Example
CN = Module Signing Example Key
emailAddress = first.last@example.com
[ extensions ]
basicConstraints=critical,CA:FALSE
keyUsage=digitalSignature
extendedKeyUsage = codeSigning
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid
You should edit the O
, CN
, and emailAddress
fields to be more appropriate. Note that in the extensions
section of the configuration, the keyUsage
field is set as digitalSignature
. Additionally, the extendedKeyUsage
option is set to codeSigning
for compatibility with key verification tools.
Generate a new key pair using this configuration file:
[root@localhost falvarez]# openssl req -x509 -new -nodes -utf8 -sha512 -days 3650 -batch -config /etc/ssl/x509.conf -outform DER -out /etc/ssl/certs/pubkey.der -keyout /etc/ssl/certs/priv.key
Generating a RSA private key
........++++
.......++++
writing new private key to '/etc/ssl/certs/priv.key'
-----
[root@localhost falvarez]#
This signing certificate is valid for ten years (3,650 days). Ensure that the keys are adequately protected.
Export the certificate in PEM format:
[root@localhost falvarez]# openssl x509 -inform DER -in /etc/ssl/certs/pubkey.der -out /etc/ssl/certs/pubkey.pem
[root@localhost falvarez]#
Signing the Module
The sign-file utility ensures that the module is signed correctly for the kernel. This utility is provided within the kernel source. The instructions below assume that you are signing a module for the currently running kernel. If you intend to sign a module for a different kernel, you must provide the path to the sign-file utility within the correct kernel version source. If you do not use the proper utility, the signature type for your module may not align correctly with the expected signature type.
To sign the module, run the sign-file utility for your currently running kernel and provide it with the path to your private key and the public key that you created for the purpose of signing your modules (for this example I would use a public module called hello) :
[root@localhost extra]# sudo /usr/src/kernels/$(uname -r)/scripts/sign-file sha512 /etc/ssl/certs/priv.key \
> /etc/ssl/certs/pubkey.der /lib/modules/$(uname -r)/extra/hello.ko
[root@localhost extra]#
Note that the module should already be installed into /lib/modules/,
and you need to provide the correct path to the module.
When the module is signed, you can check the signature by running the modinfo
command, for example:
[root@localhost extra]# modinfo /lib/modules/5.4.17-2136.300.7.el8uek.x86_64/extra/hello.ko
filename: /lib/modules/5.4.17-2136.300.7.el8uek.x86_64/extra/hello.ko
version: 0.1
description: A simple Hello world LKM!
author: Akshat Sinha
license: GPL
srcversion: B7B3CF8B5A8284B3911C7AF
depends:
retpoline: Y
name: hello
vermagic: 5.4.17-2136.300.7.el8uek.x86_64 SMP mod_unload modversions
sig_id: PKCS#7
signer: *.domain.test
sig_key: 32:25:16:91:71:14:E7:0A:4D:AA:55:3A:11:92:D7:1A:12:82:B5:B7
sig_hashalgo: sha512
signature: A3:60:4A:AC:73:0C:85:FF:3D:17:55:91:A0:54:98:CE:B5:29:60:7F:
BE:0C:60:69:4E:99:5C:90:6E:FF:1C:69:4E:EC:C4:00:5D:EF:6A:AF:
1B:88:6B:B7:0C:16:10:55:8C:F0:36:D6:37:72:5A:A2:D6:2E:CF:0B:
42:CE:94:0C:A6:82:59:CA:84:78:A0:2C:B1:90:2F:12:FC:1C:23:2E:
E4:EE:3C:60:EE:C4:76:EA:2F:25:7B:61:CD:D0:1A:BF:32:A2:93:E1:
BE:5A:E9:34:4D:11:EF:CC:93:97:8A:39:B4:62:AA:D6:74:A2:CF:59:
9C:A4:E5:BF:1B:4D:80:55:19:D2:F5:5F:45:09:B0:4A:E5:42:A7:0A:
68:8C:98:C4:37:C3:4F:67:A8:51:EC:B4:0B:B8:98:86:0D:91:F9:25:
F9:C0:50:58:B5:79:2D:46:4B:16:83:3F:D0:78:DC:78:45:A5:69:13:
26:B7:B5:BA:37:4F:03:20:CE:BD:B6:F6:40:30:D5:84:76:9D:31:46:
8A:FB:57:40:9F:E0:80:47:59:B4:26:44:60:1B:5D:B5:BD:4C:0F:3F:
9F:D3:B9:40:67:2A:34:CF:90:2D:B1:C5:FE:88:F3:97:67:2B:34:6E:
70:6E:93:11:A8:90:5B:1C:BF:5D:52:C2:64:61:AE:11:0F:B9:75:F0:
3C:86:DE:CB:5C:61:8E:BE:5D:93:73:02:6C:0B:BF:B9:D5:C4:AE:5F:
A5:B7:70:EC:8E:1E:95:79:1B:AC:55:E2:E0:46:FD:99:2F:BD:87:6C:
68:40:69:9B:2A:1B:40:BA:CC:02:71:AE:88:C1:E5:33:CC:AA:97:13:
CE:70:CE:2B:1A:14:CA:87:1D:CE:66:CF:8B:97:BE:4B:07:07:8C:60:
3C:37:9A:E6:34:EB:39:36:3C:B5:7D:B4:4C:E4:AA:AE:3C:97:3A:6B:
71:19:08:BE:0A:72:FB:42:AE:35:7B:A5:F1:F3:DE:63:88:96:A1:E5:
FF:D1:DD:58:44:DB:E6:F2:99:5B:E7:46:F5:B8:21:72:3A:62:05:73:
5B:21:9A:F3:71:51:85:84:39:83:8C:70:F4:D1:C7:8F:B9:7F:BC:D5:
47:9F:3E:5F:1B:AE:69:8A:FB:4A:FA:0C:C1:5B:A9:61:48:00:01:26:
AE:53:28:BE:DB:97:EB:5D:A7:06:45:4E:F7:79:6A:17:02:4D:A9:86:
76:1F:43:2B:41:96:3A:36:10:8C:67:E7:D4:5D:D5:A4:00:3B:F2:DC:
77:8F:09:E6:B7:8F:76:30:9F:CF:BA:1B:D4:5B:2F:4F:44:25:C0:12:
FA:02:B0:EC:23:0B:53:2D:D6:4E:F9:CA
[root@localhost extra]#
Updating the Machine Owner Key (MOK) Database
The Machine Owner Key (MOK) is a key equivalent to a Database (DB) key. You would use the MOK key type to sign boot loaders and other EFI executables, or you can use this key type to store hashes that correspond to individual programs. MOKs are not a standard part of Secure Boot; however, they are used by the Shim and the PreLoader programs to store keys and hashes. The significant capability that the MOK facility provides is the ability to add public keys to the MOK list without requiring the key chain back to another key that is already in the KEK database. The MOK facility is ideal for testing newly generated key pairs and the kernel modules signed with them. A key on the MOK list will automatically propagate to the system key ring on every subsequent boot when UEFI Secure Boot is enabled. To enrol an MOK key, you must manually do so on each target system using the UEFI system console.
Because the key that you created is not included in the UEFI Secure Boot Key Database, you must enrol into the MOK database in the Shim by using the mokutil
command:
mokutil --import /etc/ssl/certs/pubkey.der
The previous command prompts you for a single-use password that you use when the MOK Management service enrols the key after you reboot the system.
Reboot the system
The UEFI Shim should automatically start the Shim UEFI key manager at boot. Be sure to hit a key within 10 seconds to interrupt the boot process to enrol your MOK key.
-
- Press any key to perform MOK Management.
- Select Enroll MOK from the menu.
- Select View key 0 from the menu to display the key details.
- Verify that the values presented to match the key you used to sign the module and that you inserted into the kernel image, then press any key to return to the Enroll MOK menu.
- Select Continue from the menu.
- The Enroll the key(s)? the screen is displayed.
- Select Yes to enrol the key.
- Enter the password you used when you imported the key using the
mokutil
command when prompted for a password. - The key is enrolled within the UEFI Secure Boot key database.
- When the Perform MOK management screen is displayed, select Reboot from the menu.
Validating if a key is trusted
After booting the system, you can validate whether a key is included in the appropriate kernel keyring. Validation depends on the kernel version that you are running. Also, the keyring name that you need to check varies, as the implementation has changed across kernel versions.
If the key generated for signing custom modules is listed within the correct keyring, you can load modules signed with this key while in Secure Boot mode.
For RHCK on Oracle Linux 8 and UEK R6U3 kernels or later, keys within both the builtin_trusted_keys
keyring and the platform keyring
are trusted for both module signing and for the kexec
tools, which means you can follow the standard procedure to sign a module and add it to the MOK database for the key to appear in the platform keyring
and it is automatically trusted.
Because it is possible that a key can be loaded into the builtin_trusted_keys keyring
, you should check both keyrings for the module signing key, for example:
[root@localhost falvarez]# keyctl show %:.builtin_trusted_keys
Keyring
718980051 ---lswrv 0 0 keyring: .builtin_trusted_keys
889527021 ---lswrv 0 0 \_ asymmetric: Oracle CA Server: 23652876a2ec7c7794eb905265a1145e5ad5b873
643918572 ---lswrv 0 0 \_ asymmetric: Oracle IMA signing CA: a2f28976a05984028f7d1a4904ae14e8e468e551
668816900 ---lswrv 0 0 \_ asymmetric: Oracle America, Inc.: Ksplice Kernel Module Signing Key: 09010ebef5545fa7c54b626ef518e077b5b1ee4c
35441076 ---lswrv 0 0 \_ asymmetric: Oracle Linux Kernel Module Signing Key: 2bb352412969a3653f0eb6021763408ebb9bb5ab
[root@localhost falvarez]# keyctl show %:.platform
Keyring
858046056 ---lswrv 0 0 keyring: .platform
886150219 ---lswrv 0 0 \_ asymmetric: Oracle America, Inc.: 430c85cb8b531c3d7b8c44adfafc2e5d49bb89d4
698748825 ---lswrv 0 0 \_ asymmetric: Oracle America Inc.: 2e7c1720d1c5df5254cc93d6decaa75e49620cf8
790695213 ---lswrv 0 0 \_ asymmetric: Oracle America, Inc.: 795c5945e7cb2b6773b7797571413e3695062514
227851788 ---lswrv 0 0 \_ asymmetric: Oracle America, Inc.: f9aec43f7480c408d681db3d6f19f54d6e396ff4
[root@localhost falvarez]#
Trenchboot – Improving boot security and integrity
Trenchboot is a GitHub cross-community and cross-platform framework integration launched from an idea originated in 2014 by Apertus Solutions when dealing with the limitations of using boot to launch Xen for the OpenXT project and other contributors like Oracle (Intel), 3MDEB (AMD), and Citrix (https://github.com/TrenchBoot ) with its primary purpose to expand the mechanism of security and integrity of the boot process by using a standard and unified approach (between Xen, KVM, Linux, BSDs and potentially proprietary kernels).
When using TrenchBoot, one of the main capabilities we are interested in is the secure launch for Linux which is the attempt to enable the Linux kernel to be dynamically launched by AMD and Intel by introducing an intermediate phase to the booth launch (Instead of focusing purely on the traditional first launch scenario known as Bootstrap Phase as previous available open-source dynamic launch like XMHF, OSLO, OpenDTex Secure Boot, tboot, etc.) that use to launch your kernel upgrade through a key exec you could launch than an integrity kernel that could set there, and dynamically inspect the system or as per example, to establish the integrity of the platform before persisting everything to diskless at an embed environment during a shutdown. Note that the newly introduced Intermediate Phase includes an Intermediate Loader called TrenchBoot loader that various bootstrap solutions can launch. The TrenchBoot Loader contains the TrenchBoot Security Engine that implements the integrity processing (Please refer to the image below).
Oracle has added more Trenchboot support into the Oracle Linux kernel to enable a secure boot protocol for the Linux Kernel for multiple use-cases like two-factor authentication (2FA) for travel laptops to crowdsourcing integrity handling; with this, the only winner is you!
The TrenchBoot Loader Components
The TrenchBoot Loader is composed of well-known components like Linux and u-root; let’s take a closer look at the main components within it, they are:
-
- A TrenchBoot-enhanced Linux kernel with a built-in
TrenchBoot u-root initramfs
.
- A TrenchBoot-enhanced Linux kernel with a built-in
-
- The TrenchBoot Security Engine is implemented as an extension to
u-root
.
- The TrenchBoot Security Engine is implemented as an extension to
-
- A resulting image that can be launched by different boot
mechanisms/environments
.
- A resulting image that can be launched by different boot
The benefits of using TrenchBoot
The main benefits of using TrenchBoot, are:
-
- Linux and u-root provide a single source cross-architecture support (like x86, ARM, s390x, PPC, MIPS, etc.)
- It unifies system launch from a secure start-up point of view.
- It provides a rich environment for launch integrity inspection and verification process, including:
- Off-platform attestation, TCG Attestation SNMP MIB.
- Off-platform key retrievals like KMIP and YubiKey.
- Fine-grained attestation.
Removing the RHCK Kernel
In this section, you will learn how to remove the Red Hat Compatible Kernel (RHCK) from an Oracle Linux 8 environment where the Unbreakable Enterprise Kernel (UEK) is already installed and in use, so all package dependencies are met during future system updates. Remember that when installing Oracle Linux, it automatically installs the Oracle flavour of Linux kernel (UEK) as the default kernel and installs the RHCK Linux kernel to make it available to you for compatibility purposes.
Previously to Oracle Linux 8, when removing the RHCK kernel from a system, it required to use of the kernel-transition
package (note that this package does not contain any files itself, it only transfers the package dependencies from the kerne
l package to the kernel-UEK
package) first to prepare the system for the removal of the RHCK kernel without affecting dependent packages, such as bluez
, fuse
, and irqbalance
that may be required for a regular operation of the system. Now, within OEL8, this requirement is obsolete, and all packages are purposely built to avoid any dependencies concerning a particular kernel type. Now, any kernel that is not currently in use can be easily removed without impacting the system.
So, let’s check the steps to remove the RHCK kernel from our system:
-
-
First, let’s check all kernels running within our system by using the
grubby
command as follows:
-
[root@localhost falvarez]# grubby --info=ALL
index=0
kernel="/boot/vmlinuz-5.4.17-2136.304.4.1.el8uek.x86_64"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-5.4.17-2136.304.4.1.el8uek.x86_64.img $tuned_initrd"
title="Oracle Linux Server 8 (5.4.17-2136.304.4.1.el8uek.x86_64) "
id="3a314f4904914e27a578fa67647f00fb-5.4.17-2136.304.4.1.el8uek.x86_64"
index=1
kernel="/boot/vmlinuz-5.4.17-2136.300.7.el8uek.x86_64"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-5.4.17-2136.300.7.el8uek.x86_64.img $tuned_initrd"
title="Oracle Linux Server 8 (5.4.17-2136.300.7.el8uek.x86_64) "
id="3a314f4904914e27a578fa67647f00fb-5.4.17-2136.300.7.el8uek.x86_64"
index=2
kernel="/boot/vmlinuz-4.18.0-348.12.2.el8_5.x86_64"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-4.18.0-348.12.2.el8_5.x86_64.img $tuned_initrd"
title="Oracle Linux Server (4.18.0-348.12.2.el8_5.x86_64) 8.5"
id="3a314f4904914e27a578fa67647f00fb-4.18.0-348.12.2.el8_5.x86_64"
index=3
kernel="/boot/vmlinuz-4.18.0-348.el8.x86_64"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-4.18.0-348.el8.x86_64.img $tuned_initrd"
title="Oracle Linux Server (4.18.0-348.el8.x86_64) 8.5"
id="3a314f4904914e27a578fa67647f00fb-4.18.0-348.el8.x86_64"
index=4
kernel="/boot/vmlinuz-0-rescue-3a314f4904914e27a578fa67647f00fb"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-0-rescue-3a314f4904914e27a578fa67647f00fb.img $tuned_initrd"
title="Oracle Linux Server 8 (0-rescue-3a314f4904914e27a578fa67647f00fb) "
id="3a314f4904914e27a578fa67647f00fb-0-rescue"
[root@localhost falvarez]#
We can see in the above output that the default kernel in use is the /boot/vmlinuz-5.4.17-2136.304.4.1.el8uek.x86_64
, which is a UEK kernel; also, we can see that we have a couple of RHCK kernels installed: /boot/vmlinuz-4.18.0-348.12.2.el8_5.x86_64
and /boot/vmlinuz-4.18.0-348.el8.x86_64
that we can safely remove.
-
- Now that we know that we are using the UEK kernel, we can safely remove the desired RHCK kernel using the yum remove kernel or
dnf
remove kernel commands as recommended in the Oracle Linux manual. It will detect the unused kernels and show the dependencies within them.
- Now that we know that we are using the UEK kernel, we can safely remove the desired RHCK kernel using the yum remove kernel or
[root@localhost falvarez]# dnf remove kernel
Dependencies resolved.
======================================================================================
Package Architecture Version Repository Size
=====================================================================================
Removing:
kernel x86_64 4.18.0-348.el8 @anaconda 0
kernel x86_64 4.18.0-348.12.2.el8_5 @ol8_baseos_latest 0
Removing unused dependencies:
kernel-modules x86_64 4.18.0-348.el8 @anaconda 22 M
kernel-modules x86_64 4.18.0-348.12.2.el8_5 @ol8_baseos_latest 22 M
Transaction Summary
======================================================================================
Remove 4 Packages
Freed space: 45 M
Is this ok [y/N]: y
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Erasing : kernel-4.18.0-348.12.2.el8_5.x86_64 1/4
Running scriptlet: kernel-4.18.0-348.12.2.el8_5.x86_64 1/4
Erasing : kernel-4.18.0-348.el8.x86_64 2/4
Running scriptlet: kernel-4.18.0-348.el8.x86_64 2/4
Erasing : kernel-modules-4.18.0-348.el8.x86_64 3/4
Running scriptlet: kernel-modules-4.18.0-348.el8.x86_64 3/4
Erasing : kernel-modules-4.18.0-348.12.2.el8_5.x86_64 3/4
Running scriptlet: kernel-modules-4.18.0-348.12.2.el8_5.x86_64 4/4
Verifying : kernel-4.18.0-348.el8.x86_64 1/4
Verifying : kernel-4.18.0-348.12.2.el8_5.x86_64 2/4
Verifying : kernel-modules-4.18.0-348.el8.x86_64 3/4
Verifying : kernel-modules-4.18.0-348.12.2.el8_5.x86_64 4/4
Removed:
kernel-4.18.0-348.el8.x86_64 kernel-4.18.0-348.12.2.el8_5.x86_64
kernel-modules-4.18.0-348.el8.x86_64 kernel-modules-4.18.0-348.12.2.el8_5.x86_64
Complete!
[root@localhost falvarez]#
-
- As you can see above, both RHCK kernels installed were detected and technically deleted. Now, let’s run the
grubby
command again to see if the RHCK kernels were removed from our system.
- As you can see above, both RHCK kernels installed were detected and technically deleted. Now, let’s run the
[root@localhost falvarez]# grubby --info=ALL
index=0
kernel="/boot/vmlinuz-5.4.17-2136.304.4.1.el8uek.x86_64"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-5.4.17-2136.304.4.1.el8uek.x86_64.img $tuned_initrd"
title="Oracle Linux Server 8 (5.4.17-2136.304.4.1.el8uek.x86_64) "
id="3a314f4904914e27a578fa67647f00fb-5.4.17-2136.304.4.1.el8uek.x86_64"
index=1
kernel="/boot/vmlinuz-5.4.17-2136.300.7.el8uek.x86_64"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-5.4.17-2136.300.7.el8uek.x86_64.img $tuned_initrd"
title="Oracle Linux Server 8 (5.4.17-2136.300.7.el8uek.x86_64) "
id="3a314f4904914e27a578fa67647f00fb-5.4.17-2136.300.7.el8uek.x86_64"
index=2
kernel="/boot/vmlinuz-4.18.0-348.12.2.el8_5.x86_64"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-4.18.0-348.12.2.el8_5.x86_64.img $tuned_initrd"
title="Oracle Linux Server (4.18.0-348.12.2.el8_5.x86_64) 8.5"
id="3a314f4904914e27a578fa67647f00fb-4.18.0-348.12.2.el8_5.x86_64"
index=3
kernel="/boot/vmlinuz-4.18.0-348.el8.x86_64"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-4.18.0-348.el8.x86_64.img $tuned_initrd"
title="Oracle Linux Server (4.18.0-348.el8.x86_64) 8.5"
id="3a314f4904914e27a578fa67647f00fb-4.18.0-348.el8.x86_64"
index=4
kernel="/boot/vmlinuz-0-rescue-3a314f4904914e27a578fa67647f00fb"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-0-rescue-3a314f4904914e27a578fa67647f00fb.img $tuned_initrd"
title="Oracle Linux Server 8 (0-rescue-3a314f4904914e27a578fa67647f00fb) "
id="3a314f4904914e27a578fa67647f00fb-0-rescue"
[root@localhost falvarez]#
Sadly, both are still there. For example, from Oracle Linux 8, the RHCK kernel package kernel-<version>
is merely a metadata package containing no files. It is intended to ensure all dependent kernel packages are correctly installed. So, in other words, by removing the “kernel-<version>.el8" rpm
, it does not remove any of the kernel-sub packages, which includes the packages that update the /boot
associated files and the boot loader entries.
To solve this situation, we need to remove the corresponding kernel-core-<version> packages containing the /boot/
and all kernel-related files/directories
.
-
- As shown below, we will use the
dnf erase kernel-core
command to remove all related kernel-core packages.
- As shown below, we will use the
[root@localhost falvarez]# dnf erase kernel-core
Dependencies resolved.
======================================================================================
Package Arch Version Repository Size
======================================================================================
Removing:
kernel-core x86_64 4.18.0-348.el8 @anaconda 68 M
kernel-core x86_64 4.18.0-348.12.2.el8_5 @ol8_baseos_latest 68 M
Removing dependent packages:
NetworkManager-wifi x86_64 1:1.32.10-4.0.1.el8 @anaconda 167 k
initial-setup-gui x86_64 0.3.81.7-1.0.1.el8 @AppStream 26 k
…
xmlrpc-c-client x86_64 1.51.0-5.el8 @anaconda 54 k
Transaction Summary
======================================================================================
Remove 61 Packages
Freed space: 189 M
Is this ok [y/N]: y
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1 Running scriptlet: initial-setup-gui-0.3.81.7-1.0.1.el8.x86_64 1/1
Erasing : initial-setup-gui-0.3.81.7-1.0.1.el8.x86_64 1/61
Verifying : xmlrpc-c-client-1.51.0-5.el8.x86_64 61/61
Removed:
NetworkManager-wifi-1:1.32.10-4.0.1.el8.x86_64
anaconda-core-33.16.5.6-1.0.1.el8.x86_64
anaconda-gui-33.16.5.6-1.0.1.el8.x86_64
anaconda-tui-33.16.5.6-1.0.1.el8.x86_64
anaconda-user-help-1:8.3.3-1.0.1.el8.noarch
anaconda-widgets-33.16.5.6-1.0.1.el8.x86_64
blivet-data-1:3.4.0-6.0.1.el8.noarch
crda-3.18_2020.04.29-1.el8.noarch
daxctl-libs-71.1-2.el8.x86_64
initial-setup-0.3.81.7-1.0.1.el8.x86_64
initial-setup-gui-0.3.81.7-1.0.1.el8.x86_64
iw-4.14-5.el8.x86_64
kernel-core-4.18.0-348.el8.x86_64
kernel-core-4.18.0-348.12.2.el8_5.x86_64
keybinder3-0.3.2-4.el8.x86_64
kmod-kvdo-6.2.5.72-81.0.1.el8.x86_64
langtable-0.0.51-4.el8.noarch
libblockdev-btrfs-2.24-7.0.1.el8.x86_64
libblockdev-dm-2.24-7.0.1.el8.x86_64
libblockdev-kbd-2.24-7.0.1.el8.x86_64
…
python3-pyparted-1:3.11.7-4.el8.x86_64
python3-pytz-2017.2-9.el8.noarch
python3-requests-file-1.4.3-5.el8.noarch
python3-requests-ftp-0.3.1-11.el8.noarch
python3-simpleline-1.1.1-2.el8.noarch
satyr-0.26-2.el8.x86_64
tigervnc-license-1.11.0-10.el8_5.noarch
tigervnc-server-minimal-1.11.0-10.el8_5.x86_64
vdo-6.2.5.74-14.el8.x86_64
wpa_supplicant-1:2.9-5.el8.x86_64
xmlrpc-c-1.51.0-5.el8.x86_64
xmlrpc-c-client-1.51.0-5.el8.x86_64
Complete!
[root@localhost falvarez]#
-
- Now, let’s rerun the
grubby
command to see if the RHCK kernels were removed this time from our system.
- Now, let’s rerun the
[root@localhost falvarez]# grubby --info=ALL
index=0
kernel="/boot/vmlinuz-5.4.17-2136.304.4.1.el8uek.x86_64"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-5.4.17-2136.304.4.1.el8uek.x86_64.img $tuned_initrd"
title="Oracle Linux Server 8 (5.4.17-2136.304.4.1.el8uek.x86_64) "
id="3a314f4904914e27a578fa67647f00fb-5.4.17-2136.304.4.1.el8uek.x86_64"
index=1
kernel="/boot/vmlinuz-5.4.17-2136.300.7.el8uek.x86_64"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-5.4.17-2136.300.7.el8uek.x86_64.img $tuned_initrd"
title="Oracle Linux Server 8 (5.4.17-2136.300.7.el8uek.x86_64) "
id="3a314f4904914e27a578fa67647f00fb-5.4.17-2136.300.7.el8uek.x86_64"
index=2
kernel="/boot/vmlinuz-0-rescue-3a314f4904914e27a578fa67647f00fb"
args="ro crashkernel=auto resume=/dev/mapper/ol-swap rd.lvm.lv=ol/root rd.lvm.lv=ol/swap rhgb quiet $tuned_params"
root="/dev/mapper/ol-root"
initrd="/boot/initramfs-0-rescue-3a314f4904914e27a578fa67647f00fb.img $tuned_initrd"
title="Oracle Linux Server 8 (0-rescue-3a314f4904914e27a578fa67647f00fb) "
id="3a314f4904914e27a578fa67647f00fb-0-rescue"
[root@localhost falvarez]#
As you can now see, all RHCK kernels were removed from our system.
Furthermore, if you later decide to restore the deleted RHCK kernels, you can quickly restore them using the dnf install kernel
command.
[root@localhost falvarez]# dnf install kernel
Oracle Linux 8 BaseOS Latest (x86_64) 17 kB/s | 3.6 kB 00:00
Oracle Linux 8 BaseOS Latest (x86_64) 3.0 MB/s | 42 MB 00:14
Oracle Linux 8 Application Stream (x86_64) 18 kB/s | 3.9 kB 00:00
Oracle Linux 8 Application Stream (x86_64) 2.9 MB/s | 32 MB 00:11
Latest Unbreakable Enterprise Kernel Release 6 for Oracle Linux 8 14 kB/s | 3.0 kB
Latest Unbreakable Enterprise Kernel Release 6 for Oracle Linux 8 3.6 MB/s | 35 MB
Last metadata expiration check: 0:00:08 ago on Wed 23 Feb 2022 07:38:55 PM EST.
Dependencies resolved.
======================================================================================
Package Architecture Version Repository Size
======================================================================================
Installing:
kernel x86_64 4.18.0-348.12.2.el8_5 ol8_baseos_latest 7.0 M
Installing dependencies:
kernel-core x86_64 4.18.0-348.12.2.el8_5 ol8_baseos_latest 38 M
kernel-modules x86_64 4.18.0-348.12.2.el8_5 ol8_baseos_latest 30 M
Transaction Summary
======================================================================================
Install 3 Packages
Total download size: 74 M
Installed size: 90 M
Is this ok [y/N]: y
Downloading Packages:
(1/3): kernel-4.18.0-348.12.2.el8_5.x86_64.rpm 1.0 MB/s | 7.0 MB 00:06
(2/3): kernel-modules-4.18.0-348.12.2.el8_5.x86_64.rpm 1.5 MB/s | 30 MB 00:19
(3/3): kernel-core-4.18.0-348.12.2.el8_5.x86_64.rpm 1.6 MB/s | 38 MB 00:23
--------------------------------------------------------------------------------------
Total 3.2 MB/s | 74 MB 00:23
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : kernel-core-4.18.0-348.12.2.el8_5.x86_64 1/3
Running scriptlet: kernel-core-4.18.0-348.12.2.el8_5.x86_64 1/3
Installing : kernel-modules-4.18.0-348.12.2.el8_5.x86_64 2/3
Running scriptlet: kernel-modules-4.18.0-348.12.2.el8_5.x86_64 2/3
Installing : kernel-4.18.0-348.12.2.el8_5.x86_64 3/3
Running scriptlet: kernel-core-4.18.0-348.12.2.el8_5.x86_64 3/3
Running scriptlet: kernel-4.18.0-348.12.2.el8_5.x86_64 3/3
Verifying : kernel-4.18.0-348.12.2.el8_5.x86_64 1/3
Verifying : kernel-core-4.18.0-348.12.2.el8_5.x86_64 2/3
Verifying : kernel-modules-4.18.0-348.12.2.el8_5.x86_64 3/3
Installed:
kernel-4.18.0-348.12.2.el8_5.x86_64 kernel-core-4.18.0-348.12.2.el8_5.x86_64 kernel-modules-4.18.0-348.12.2.el8_5.x86_64
Complete!
[root@localhost falvarez]#
Hope you enjoyed this post as it refreshes some very important topics regarding Linux Kernels and Boot basics. We started with understanding the purpose of boot options all the way to the types of Linux Kernels available within Oracle Linux 8 and how to play with them. Thank you so much for reading it.