SUSE addresses another grub2 UEFI secure boot security exposure

Tuesday, 2 March, 2021

Various security researchers and the grub2 team have published more security issues in grub2 today, which can be used to bypass the UEFI secure boot chain.
These security issues have the same scope as the BootHole issues from 2020. This attack requires root access to the bootloader used in Linux operating systems, GRUB2. It bypasses normal Secure Boot protections to persistently install malicious code which cannot be detected by the operating system.

Given the need for root access to the bootloader, the described attack appears to have limited relevance for most cloud computing, data center and personal device scenarios, unless these systems are already compromised by another known attack. However, it does create an exposure when untrusted users can access a machine, e.g. bad actors in classified computing scenarios or computers in public spaces operating in unattended kiosk mode. These are scenarios which Secure Boot was intended to protect against.

SUSE has released fixed grub2 packages which close the vulnerabilities for all SUSE Linux products, and is releasing corresponding Linux kernel packages, cloud image and installation media updates. Please follow the normal update procedure to install them. Should you be unsure about your company’s procedure, please consult your local system administrator.

To ensure that sophisticated attackers cannot reinstall old versions of grub2, software and hardware vendors are working together. Over time, vendors are going to update cryptographic keys in the BIOS for new computers, as well as to provide so-called DBX Exclusion List updates for existing computers. These can prevent unpatched systems and old installation media from starting. Please make sure you have installed all relevant bootloader and operating system updates for BootHole before installing a BIOS or DBX Exclusion List update to ensure continuity.

References:

If you have any questions or concerns, please reach out to your SUSE contact. Security and reliability continue to be top priorities for SUSE because they are top priorities for our customers and partners. And as always, customers and partners come first.

Secure Boot Network Installation

Wednesday, 27 June, 2018

1. Preboot Execution Environment (PXE)

We have to start with the standard PXE setup that is used for decades for disk-less client bootstrapping. The client requests an IP address and gets it together with the information where to find a boot file that can be loaded via TFTP. In our case the network connection is done via the EFI stack and the file the system is loading is an EFI application.

2. Copy relevant files to the right places

The relevant files that we need can simply be copied from the ISO image. First we need the the bootx64.efi file that is the shim that has an official digital signature from Microsoft. This file gets validated during Secure Boot and allows us to load and validate the grub.efi file that was signed with the “openSUSE Secure Boot CA”. Grub will then load its config file and offers the same menu we know from the ISO image.

The following steps are the same for openSUSE and SUSE Linux Enterprise:

#> mount -o loop openSUSE-Leap-15.0-DVD-x86_64.iso /mnt
#> cp /mnt/EFI/BOOT/{bootx64.efi,grub.efi,grub.cfg} /srv/tftpboot/
#> cp -r /mnt/boot /srv/tftpboot/

To run a full network installation we also need to provide the ISO image content. A simple way to do this is via HTTP. Just create an installation sub-directory with the full content of the ISO image. Best practice is to mount the ISO image inside the web server environment.

The 'Installation' menu-entry inside the grub.cfg file can then be extended with the netsetup= and install= parameters. Simply extend the linuxefi line with the following string:

netsetup=dhcp,all install=http://192.168.7.1/install/opensuse/leap150/

We can also customize the boot menu theme by editing the boot/x86_64/grub2-efi/themes/openSUSE/theme.txt file. In this example we will edit the theme title that is shown during boot.

title-text: "openSUSE Leap 15.0 (UEFI Network Installation)"

3. Showtime

You need to enable UEFI IPv4 Boot and Secure Boot inside the BIOS of your system. Then it should look similar to this KVM Secure Boot screen cast.

Have a lot of fun! 😉

SUSE and Secure Boot: The Details

Thursday, 9 August, 2012

In the previous posts, UEFI Secure Boot and Our Planned Approach to Secure Boot, Olaf Kirch has introduced you into the topic of UEFI Secure Boot and the basics of our approach to implementing it in SUSE. In this post, I’ll lead you through the technical details of our Secure Boot plan. So be prepared for this post to be rather detailed. And technical.

The goal of Secure Boot is to prevent malware from hiding embedded in the boot chain by performing a verification of every executed component starting with a fresh reboot of the whole platform. To achieve its goal, Secure Boot must prevent any modification of the verification process, the keys, or any other variables by untrusted code or untrusted entities. An example of an untrusted entity is a hacker who has penetrated the system through an unpatched security hole in the operating system.

There are two types of trusted users:

First, those who hold the keys. The Platform Key (PK) allows almost everything. The Key Exchange Key (KEK) allows all a PK can except changing the PK.

Second, anyone with physical access to the machine. A user with physical access can reboot the machine, and configure UEFI.

UEFI offers two types of variables to cater to the needs of those users:

The first is the so called “Authenticated Variables,” which can be updated from both within the boot process (the so called Boot Services Environment) and the running OS, but only when the new value of the variable is signed with the same key that the old value of the variable was signed. And they can either only be appended to or changed to a value with a higher serial number.

The second is the so called “Boot Services Only Variables.” These variables are accessible to any code that runs during the boot process. After the boot process ends and before the OS starts, the bootloader must call the ExitBootServices() call. After that, these variables are no longer accessible, the OS can’t touch them.

The various UEFI key lists are of the first type, as this allows on-line updating, adding and blacklisting of keys, drivers and firmware fingerprints. It’s the second type of variable, the “Boot Services Only Variable” that will help us in our quest for an implementation of Secure Boot that is both secure and open source friendly. And compatible with GPLv3.

As Olaf explained in the last post, we start with a shim, based on the Fedora shim, signed by either a certificate signed by the SUSE KEK or a Microsoft-issued certificate, based on what KEKs are available in the UEFI key database on the system.

This allows the shim to load and execute.

The shim then goes on to verify that the GRUB2 bootloader it wants to load is trusted. It will not use the SUSE KEK nor the Microsoft cert for this. In a default situation the shim will use an independent SUSE certificate embedded in its body. In addition, the shim will allow to “Enroll” additional keys, overriding the default SUSE key. Let’s call them “Machine Owner Keys” or MOKs for short.

The enrollment process begins by rebooting the machine and interrupting the boot process  (e.g., pressing a key) when the shim loads. The shim will then go into enrollment mode, allowing the user to replace the default SUSE key with keys from a file on the boot partition. If the user chooses to do so, the shim will then calculate a hash of that file and put the result in a “Boot Services Only” variable. This allows the shim to detect any change of the file made outside of Boot Services and thus avoid the tampering with the list of user approved MOKs.

An important aspect to remember is that all of this happens during boot time, only verified code is executing now. Therefore, only a user present at the console can say, “I want to use my own set of keys.” It can’t be malware or a hacker with remote access to the OS because hackers or malware can only change the file, but not the hash stored in the “Boot Services Only” variable.

GRUB2, once loaded and verified by the shim, will call back to the shim when it wants to verify the kernel – to avoid duplication of the verification code. The shim will use the same list of MOKs for this and tell GRUB2 whether it can load the kernel.

And that’s it.

This is all you need to be able to work on improving the kernel or the bootloader. Install a new set of keys and authorize them by being physically present during the first reboot.

Also, thanks to MOKs being a list and not just a single MOK, you can make the shim trust keys from several different vendors, allowing dual- and multi-boot from the GRUB2 bootloader.

In the end the real implementation may be a little bit more complicated – for example password-protecting the MOK authorization feature to allow secure authenticated updating of the MOK list from within the OS – but this is the gist of it. And since you can freely modify GRUB2 and your kernel as an owner of a machine, you are happy and so is  GPLv3 that the machine didn’t get tivoized.

You may be wondering whether this goes against the UEFI specification or Microsoft Win8 Logo requirements or any of the associated contracts.

I don’t think so – even the UEFI specification allows, but doesn’t mandate, that a UEFI implementation allow a user authorize EFI code with an invalid signature by adding a hash to a special variable.

And the Linux Foundation has asked vendors to make sure to include a way of clearing the PK to allow the user to enroll their own set of keys.

Our approach is just making sure that a feature like this is available everywhere.

To keep the “PC” a free platform.

Our Planned Approach to Secure Boot

Wednesday, 8 August, 2012

In this follow-on blog to UEFI Secure Boot, I will describe our plans towards UEFI Secure Boot. Note that when we say “SUSE”, we really mean two very distinct distributions –  SUSE Linux Enterprise on one hand, and openSUSE on the other hand. The latter, being a  community project, is rather independent in their decisions on how to address the issue –  so the description below should be considered as the current Plan of Record for SUSE Linux Enterprise, but in the context of openSUSE, it can be a proposal for the community’s consideration only.

As explained in the previous installment of this series, UEFI Secure Boot is a useful technology, making it harder for attackers to hide a rootkit in the boot chain.

And at the same time, already the basics of its operation – establishing a single root of trust – conflict with the principles of Open Source development, which must be independent and distributed to work.

On top of that, there are a number of licensing and legal headaches waiting for anyone who wants to make use of Secure Boot in its default form. The GPL v3 anti-tivoization clause being one, another one being the wording of Microsoft’s SysDev contract that precludes the  signing of GPLv3 binaries with a Microsoft-provided certificate.

Currently, the first desktop systems are shipping with Secure Boot support, and we expect it to become pervasive in all newly sold PCs toward the end of this year. And of course we expect all of them to be shipped with Microsoft’s Key Exchange Key (KEK) installed by default.

Some of these new machines will probably have a way to disable secure boot easily; in others it may be possible but cumbersome; and in still others it may be impossible without loss of other functionality.

Supporting UEFI Secure Boot essentially boils down to having a boot loader with a digital signature that the firmware recognizes as a trusted key, and in order to be useful to Enterprise customers, that key should be trusted by the firmware a priori, without requiring any manual intervention.

There are two ways of getting there. One is to work with hardware vendors to have them endorse a SUSE key which we then sign the boot loader with. The other way is to go through Microsoft’s Windows Logo Certification program to have the boot loader certified and have Microsoft recognize our signing key (i.e. have it signed with their KEK). We are currently evaluating both approaches, and may eventually even pursue both in parallel.

At the implementation layer, we intend to use the shim loader originally developed by Fedora – it’s a smart solution which avoids several nasty legal issues, and simplifies the certification/signing step considerably. This shim loader’s job is to load grub2 and verify it; this version of grub2 in turn will load kernels signed by a SUSE key only. We are
currently considering to provide this functionality with SLE11 SP3 on fresh installations with UEFI Secure Boot present.

Now it is probably clear why this approach offers the level of security that UEFI Secure Boot promises – there is an unbroken chain of verification, making sure only trusted and signed code gets executed prior to handing control to the Operating System kernel.

What isn’t clear is how this allows Open Source developers to run their own kernels, or bootloaders for that matter or how this complies with the GPL v3 license. In the next part of this series of blogs, we will explain how we intend to provide this with our version of the shim.

UEFI Secure Boot

Tuesday, 7 August, 2012

In case you don’t know what this blog is talking about: UEFI is the “Unified Extensible Firmware Interface”, and “Secure Boot” is one of its more recent features that is generating a bit of a stir in the Open Source world.

At SUSE, we have been looking at UEFI Secure Boot long and hard.

On one hand, we agree that closing down some of the loopholes in the boot process is a worthwhile goal. For decades, we have accepted that this process has been one of the soft spots that are essentially unfixable without a major change in the BIOS. Now that this change is coming, we are ready to embrace it. And we’re also happy to see a much bigger change happening as part of this, which is the establishment of UEFI as the standard firmware on all x86 platforms.

On the other hand, as a Linux company, we are seeing a number of issues that have been causing us quite some headaches, which we wanted to resolve before we publicly state our plans in this regard.

In order to explain our concerns, let’s take a brief look at what Secure Boot really does, in a nutshell. In the world of UEFI, securing the bootstrapping process means establishing a chain of trust. The “platform” is the root of this chain of trust; I tend to think of it as the motherboard and the on-board firmware ROM. Or, put slightly differently, it’s the hardware vendor, and the chain of trust flows from that hardware vendor to the component manufacturers, the OS vendors, etc.

On the legal side, this trust is established by a lot of contracts and other legal paperwork. On the level of bits and bytes, this trust is expressed via public key cryptography.  The vendor puts a so-called Platform Key into the ROM, representing the root of trust. The trust relationships with operating system vendors and others is documented by signing their keys with the Platform Key.

Finally, security is established by requiring that no code will be executed by the firmware unless it has been signed by one of these “trusted” keys – be it an OS boot loader, some driver located in the ROM of some PCI Express card, or be it an update of the firmware itself.

Of course, one could make this a very long chain of trust, by requiring that everything that ever gets run on that machine be signed: the OS itself, the modules it loads, the binaries and shared libraries it loads, all the scripts executed by any random interpreter, and even
the commands you type into a shell session.

So obviously, that has to stop somewhere; and in the UEFI specification, that point is reached when the firmware hands control to the operating system. Essentially, if you want to use Secure Boot, you need to have your OS loader signed with a key trusted by the firmware, and you need the OS loader to verify that the kernel it loads can be trusted.

Admittedly, this is glossing over quite some details – but that is of no real importance for this discussion.

The crux of the matter is that this conflicts with the way the Open Source community has been developing code for several decades now.  The Open Source movement began as an act of emancipation from the operating system vendors of that time. Open Source was and is about Freedom, not in a dogmatic, but really in some very practical sense. The Linux community is where it is today because people could just start their own distribution, build their own boot loader and kernel, and grow a community. It is thriving the way it is thriving today because there are thousands of people around the globe who rebuild their kernel ten times a day to fix bugs, to add enhancements, or to run their test harness on the latest set of changes.  And it will only continue to thrive in this way if we keep it that way.

From this point of view, Secure Boot is very much at odds with the Linux development model.

Just for the record, I do not think this is a conspiracy, or a sinister attempt to kill Linux. That’s not going to happen. But while Secure Boot can be a significant improvement for many, it definitely creates obstacles for the Linux community.

Granted, the Windows 8 Logo certification requires that BIOS vendors should allow users to turn off Secure Boot on x86 platforms, and we have hope that all BIOS vendors will actually implement this in a way that works well for Linux developers. But ideally, Linux  developers should not be required to switch off a security feature in order to run their operating system.

Thus, over the past months, our guiding questions when dealing with Secure Boot have been, how can we make it work for our customers, and how can we reconcile the requirements of Secure Boot with the needs of the Linux community.

We plan to continue this series of blog postings soon with an overview of how we intend to support Secure Boot in SUSE Linux Enterprise, and what solutions we propose to the  openSUSE community.

Hybrid Boot and SEV-SNP support in AWS EC2

Wednesday, 3 May, 2023

A while back AWS introduced UEFI support for specific instance types. Then in March of 2023 AWS enabled hybrid-boot for AMIs and in addition to the memory encryption that has already been supported in EC2, AWS announced the support of attestation, also known as SEV-SNP recently. Throughout this process AWS and SUSE have been working closely together to ensure the support of these features in SUSE Linux Enterprise.

SUSE Linux Enterprise and openSUSE images have been ready for UEFI boot from day 1 and anyone was able to create an image that uses UEFI secure boot. However SLE and openSUSE images published by SUSE reamained set to boot with BIOS, until a few days ago. Any SLE image published with a date stamp of 20230428 or later is set to use the relatively new “uefi-preferred” boot mode setting when an image gets registered. openSUSE images with a datestamp of 20230504 and later have the same setting. This setting indicates that the image is capable of hybrid-boot, more on hybrid-boot below.

With this the logical question is why there has not been a UEFI bootable image published by SUSE until now?

The answer is fairly simply, duplication of images. Until March 6, 2023 an image for x86_64 was either set up for BIOS or UEFI booting. A hybrid boot setup was not recognized by the platform. With the enablement of hybrid boot in EC2 SLE  images with date stamps of 20230428 or later will now boot with UEFI secure boot or BIOS depending on the instance type. For openSUSE images this applies for images with a datestamp of 20230504 or later.

What does hybrid-boot mean?

In general it means that a system can boot either with EFI (Extendable Firmware Interface) of BIOS (Basic Inout/Output System) as fimware. In EC2 the “uefi-preferred” setting means that an x86_64 image will boot using UEFI Secure Boot for instance types that support UEFI and will boot using BIOS for instance types that do not supporte UEFI. Both firmware implementations are supported with the same image.

Support for attestation, i.e. SEV-SNP

Attestation requires that you use SLE 15 SP4 or later Service Packs or openSUSE Leap 15.4 or later images for your instances. Before you can follow the validation process that is part of the AWS documentation some extra steps are required.

  1. Install necessary development packages
    1. zypper in git make gcc libopenssl-1_1-devel kernel-source linux-glibc-devel libuuid-devel automake autoconf gcc-c++
  2. Update the headers only needed in instances launched with images with a date stamp less than v20230719
    1. cd /usr/src/linux-$VERSION
    2. make headers_install ARCH=x86_64 INSTALL_HDR_PATH=/usr/

After this you can follow the instructions in the AWS Documentation.

We are working on providing the sev-guest tools as a package and the steps above will eventually boil down to a simple zypper install command.

 

SUSE open-sources Secure VM Service Module for Confidential Computing

Wednesday, 15 March, 2023

Today SUSE open-sources its implementation of a Secure Virtual Machine Service Module (SVSM), which will enhance the security of confidential virtual machines (CVMs). The COCONUT-SVSM will allow CVMs to securely store data in a trusted environment and emulate TPM devices on AMD EPYC Generation 3 and later. Written in the Rust programming language it features special isolation capabilities. It is dual-licensed under the Apache-2.0 and MIT licenses. With open-sourcing the project we invite the community to participate in its future development.

What is Confidential Computing

The very short answer is: Confidential Computing encrypts data during processing. In recent years CPU vendors have started to integrate features which allow to setup isolated and trusted execution environments that are inaccessible to the rest of the system. The SVSM builds on AMD Secure Virtual Machine with Secure Nested Paging (AMD SEV-SNP). With this extension the virtual machine runs with encrypted memory and register state, so that its content is not visible outside of the CVMs context.

Why a Secure VM Service Module

Confidential Computing is especially important in environments where the hypervisor is controlled by someone else and thus not fully trusted. Since all peripheral devices of a CVM are controlled by the hypervisor, these devices are not fully trusted too. For most devices like disks and network cards the CVM can protect itself from malformed or malicious input. But there are also devices, like the TPM, which contain security sensitive state that must not be visible to the hypervisor.

The SVSM allows to move the emulated TPM device from the hypervisor into the trusted CVM context. The TPM state is secure and the CVM can use it for attestation and storing encryption keys.

Getting and Installing the Code

The code for the COCONUT-SVSM is available on GitHub and split into several repositories:

Design Highlights

The SVSM code base has a rich set of features to build on. It contains around 8000 lines of Rust code and puts a strong emphasis on isolation. PerCPU page-tables isolate the mappings of data structures between the cores of a running system. The memory allocator uses buddy and slab algorithms and presents itself to the Rust runtime via the GlobalAlloc trait. With a global allocator the SVSM can use parts of the Rust library which rely on memory allocations, like vec and strings. But also other data structures and smart pointers like Box, Rc and Arc are available to use.

For robustness it includes a locking library with a spin-lock and read-write lock implementation. With fixups the SVSM can recover from exceptions that happen during request processing and return an error code to the operating system.

Last but not least there are also debugging features included, like the ability to collect and print the call-stack. The panic!() macro currently uses them to print a back-trace, but they can also help to debug locking issues.

Future of the COCONUT-SVSM

The released code base is far from being complete. It can boot a Linux image in a CVM with multiple vCPUs assigned. It does not include a TPM emulation yet, but we will add this as one of the very next steps. To implement this, the SVSM will get the ability to run separate modules at ring 3 within the SVSM context. This will isolate the modules from the core SVSM kernel and makes it easy to extend.

With a persistency layer modules like the TPM will be able to securely save and restore their state across reboots and shutdowns. Live migration support is also planned. The SVSM will be able to transfer the running guest operating system to another SVSM running on a remote machine. This requires a secure channel between the source and destination SVSM as well as help from the hypervisor for tracking dirty pages.

Ultimately we want to move more device emulation parts from the hypervisor into the CVM context to enable running almost unenlightened operating systems with AMD SEV-SNP protection.

Acknowledgments

The COCONUT-SVSM project would not have been possible without the close relationship to AMD. AMD provided the Linux kernel and OVMF modifications to complete the SVSM host and guest stack. Many thanks for the work and our continuous cooperation!

Improve Boot Times in SUSE Linux Enterprise Desktop 15 SP3 with These Tweaks

Wednesday, 15 December, 2021

So, you have a nice fresh install of SUSE Linux Enterprise Desktop but wonder about slow startup issues. Some may be transient, such as purging kernels, updating man pages, or the rpm database. Some may be BIOS related and some may just be your hardware, but in any case, still noticed at every boot.

I’m a command-line junkie, but I will also delve into the awesome tool YaST to perform some tasks; however, there will be command-line actions needed!

In this blog, I hope to show you how to check your hardware setup, investigate systemd startup times, and network configuration tweaks for ipv4. Lastly, help you decide if these tweaks can be used for your end-use case.

Analyzing the Initial Boot

Start by opening a terminal session; either use activities and search for gnome-terminal or press alt+F2 and run gnome-terminal from there.

Run the command systemd-analyze in the terminal to get a summary of the system boot time:

systemd-analyze

Startup finished in 4.732s (firmware) + 8.048s (loader) + 3.584s (kernel) + 3.170s (initrd) + 31.312s (userspace) = 50.847sgraphical.target reached after 31.293s in userspace

This system took 50 odd seconds from cold boot to the userspace (in my case, graphical target – GNOME on Wayland). I normally reboot to ensure anything transient is resolved (kernel purge, man DB update, etc) and re-run the systemd-analyze command.

systemd-analyze

Startup finished in 4.477s (firmware) + 7.963s (loader) + 3.554s (kernel) + 3.258s (initrd) + 31.249s (userspace) = 50.504s graphical.target reached after 31.232s in userspace

As seen in both outputs, the boot times from systemd-analyze are consistent, so let’s have a closer look.

We should look at an additional summary of blame and critical-chain options for reference going forward.

I only check the top 10 to start with; if you want to see the full list, just skip the piping through | head -n 10 part.

systemd-analyze blame | head -n 10

21.112s plymouth-quit-wait.service
 4.706s NetworkManager-wait-online.service
 2.592s lvm2-monitor.service
 1.753s dracut-initqueue.service
 1.418s postfix.service
 1.305s kdump-early.service
 1.130s firewalld.service
  955ms kdump.service
  939ms sshd.service
  933ms apparmor.service

systemd-analyze critical-chain

The time when unit became active or started is printed after the "@" character.
The time the unit took to start is printed after the "+" character.

graphical.target @31.293s
└─multi-user.target @31.293s
  └─getty.target @31.292s
    └─getty@tty1.service @31.291s
      └─plymouth-quit-wait.service @10.174s +21.112s
        └─systemd-user-sessions.service @10.158s +9ms
          └─remote-fs.target @10.156s
            └─iscsi.service @10.124s +31ms
              └─network-online.target @10.122s
                └─NetworkManager-wait-online.service @5.414s +4.706s
                  └─NetworkManager.service @5.357s +53ms
                    └─network-pre.target @5.354s
                      └─firewalld.service @4.222s +1.130s
                        └─polkit.service @4.030s +186ms
                          └─basic.target @4.004s
                            └─sockets.target @4.004s
                              └─pcscd.socket @4.004s
                                └─sysinit.target @4.001s
                                  └─apparmor.service @3.068s +933ms
                                    └─var.mount @3.048s +18ms
                                      └─local-fs-pre.target @3.026s
                                        └─lvm2-monitor.service @432ms +2.592s
                                          └─dm-event.socket @419ms
                                            └─-.mount
                                              └─system.slice
                                                └─-.slice

Breaking Down the Boot Times

In the initial output on my system, there are times for firmwareloaderkernelinitrd, and userspace. Let’s look at these:

Firmware

My experience has shown that changing some of the BIOS boot settings can make a difference. All I can suggest is inspecting your system BIOS and disabling items not being used. To give an example, for this blog, I have Secure Boot disabled, TPM disabled, and network boot. I have removed the DVD drive that came with the system, and have an empty HDD caddy installed, so the BIOS option to boot from CDROM is disabled. Likewise, I disabled any POST Hotkey delay.

Since I installed it from USB and don’t need this option anymore, let’s reboot the system and disable the USB boot option in the BIOS to see if it’s made a difference.

I have also set the login to the desktop as auto for this setup configuration. It will be rebooting, and the login screen adds additional time depending on your login method.

I rebooted after tweaking the BIOS settings and had an initial time of 4.732s and 4.477s, respectively. After disabling the USB Boot option, it was 4.819s, so no real improvement for me… .

Loader (AKA Grub)

For the GRUB Boot Screen, we can improve by reducing the delay, which is set at eight seconds by default.

So we see an initial time of 8.048s and 7.963s, respectively, so let’s fire up YaST Bootloader and make some changes. Now by default, the overall YaST GUI is not visible, so what I do is copy the desktop file to my user directory via:

cp /usr/share/applications/org.opensuse.YaST.desktop ~/.local/share/applications/

You can now search for YaST (and add to Favorites if needed), start YaST, highlight System and select Boot Loader in the right-hand panel:

page4image31721712

Now select the ‘Boolader Options’ tab. If the system is a single boot, uncheck the ‘Probe Foreign OS’ and reduce the Timeout seconds to 1.

Press ‘OK’ and reboot the system to see the effect by running the systemd-analyze command:

Startup finished in 4.603s (firmware) + 1.651s (loader) + 3.581s (kernel) + 3.206s (initrd) + 31.275s (userspace) = 44.318sgraphical.target reached after 31.259s in userspace

The loader time is now down to 1.651s, an approximate 6-second improvement. You can still select a boot option by pressing any key to stop the Grub counter if you wish to select an option.

You can also switch to just the text GRUB via unchecking the option from the Kernel Parameters tab Graphical Console.

page5image31777104

Startup finished in 4.453s (firmware) + 1.427s (loader) + 3.538s (kernel) + 3.188s (initrd) + 31.334s (userspace) = 43.941s graphical.target reached after 31.314s in userspace

Kernel and Initrd

This part is very subjective depending on your needs; in my case, I cut out numerous modules that are not needed for my use case, but I think you will find that a number is not needed.

The first step is to open a terminal, switch to root user, and check mkinitrd output…

su -
Password:

mkinitrd

We are interested in this part of the output at the beginning:

dracut: dracut module 'dmraid' will not be installed, because command 'dmraid' could not be found!
dracut: dracut module 'nvmf' will not be installed, because command 'nvme' could not be found!
dracut: dracut module 'biosdevname' will not be installed, because command 'biosdevname' could not be found!
dracut: dracut module 'dmraid' will not be installed, because command 'dmraid' could not be found!
dracut: dracut module 'nvmf' will not be installed, because command 'nvme' could not be found!

We will use a dracut configuration file to modify these options, so fire up your favorite editor as your user and create a file called 01-yourhostname.conf – my hostname is ernie so I called mine 01-ernie.conf.

In this file we want the following:

hostonly="yes"
compress="cat"

omit_dracutmodules+=" dmraid nvmf biosdevname cdrom pollcdrom wacom selinux "

omit_drivers+=" wacom parport pcmcia cdrom serial pcspkr "

I have also omitted some others since I don’t have hardware present on this laptop, serial wacom etc, likewise no selinux. Save the file and let’s switch to the root user terminal session and copy to the required location:

cp /home/username/01-ernie.conf /etc/dracut.conf.d/

ls /etc/dracut.conf.d/
01-ernie.conf

Now, still as root users we need to rebuild initrd with the mkinitrd command:

mkinitrd

Creating initrd: /boot/initrd-5.3.18-59.27-default
dracut: Executing: /usr/bin/dracut --logfile /var/log/YaST2/mkinitrd.log --force /boot/initrd-5.3.18-59.27-default 5.3.18-59.27-default
dracut: dracut module 'dmraid' will not be installed, because it's in the list to be omitted!
dracut: dracut module 'nvmf' will not be installed, because it's in the list to be omitted!
dracut: dracut module 'biosdevname' will not be installed, because it's in the list to be omitted!
dracut: dracut module 'pollcdrom' will not be installed, because it's in the list to be omitted!
dracut: dracut module 'selinux' will not be installed, because it's in the list to be omitted!
Creating initrd: /boot/initrd-5.3.18-59.27-default
.....
dracut: *** Creating initramfs image file '/boot/initrd-5.3.18-59.27-default' done ***
ernie:~ #  exit

Reboot your system and again check the systemd-analyze output:

systemd-analyze
Startup finished in 4.598s (firmware) + 1.592s (loader) + 1.717s (kernel) + 3.141s (initrd) + 30.196s (userspace) = 41.245s
graphical.target reached after 30.180s in userspace

Another second or so saved, 1.717s (kernel) + 3.141s (initrd).

Now there are a couple more things I do. I remove plymouth and I don’t use ipv6, so I also disable this. There is one thing you do need to do concerning the postfix configuration if only using ipv4.

This is so we can edit our 01-hostname.conf file and add plymouth and ipv6 to the list of modules to omit (omit_dracutmodules).

Open a terminal and again switch to root user and copy the updated file over (tip once root user can use the up key to repeat the cp command):

su -
Password:
cp /home/username/01-ernie.conf /etc/dracut.conf.d/

Now, pause a moment as we will be running some additional commands for postfix and removal of plymouth (I use vi for this):

vi /etc/postfix/main.cf

{hit the / to search in vi and type in inet_protocol and press i to insert} replace all with ipv4 press shift :wq to write and quit vi.

Fire up YaST -> System -> Network Settings and under the Global Options tab and under IPv6 Protocol Settings, uncheck the Enable IPv6 box, press ok, and say ok to the warning about a reboot required.

page8image31838272

This setting is in /etc/sysctl.d/70-yast.conf and changes net.ipv6.conf.all.disable_ipv6 = 0 to 1.

Remove plymouth (plymouth and libply files):

zypper rm libply* ply*
Reading installed packages...
Resolving package dependencies...

The following 11 packages are going to be REMOVED:
  libply-boot-client5 libply-splash-core5 libply-splash-graphics5 libply5 plymouth plymouth-branding-SLE plymouth-dracut plymouth-plugin-label plymouth-plugin-label-ft plymouth-plugin-script
  plymouth-scripts

11 packages to remove.
After the operation, 827.0 KiB will be freed.
Continue? [y/n/v/...? shows all options] (y):y
.....

Add locks so they don’t get reinstalled:

zypper al libply* ply*

Specified locks have been successfully added.

zypper ll

# | Name    | Type    | Repository | Comment
--+---------+---------+------------+--------
1 | libply* | package | (any)      |
2 | ply*    | package | (any)      |

Now let’s rebuild initrd and reboot to see the check the changes:

Startup finished in 4.439s (firmware) + 1.440s (loader) + 1.648s (kernel) + 2.900s (initrd) + 10.317s (userspace) = 20.746s 
graphical.target reached after 10.304s in userspace

A .5-second speed up with the initrd, but notice the userspace time, a ten-second improvement!

Let’s quickly review the current blame output:

systemd-analyze blame | head -n 10

4.671s NetworkManager-wait-online.service
1.649s dracut-initqueue.service
1.613s apparmor.service
1.430s postfix.service
1.291s kdump-early.service
1.152s firewalld.service
1.106s sshd.service
1.095s lvm2-monitor.service
 936ms kdump.service
 863ms display-manager.service

The original 21.112s plymouth-quit-wait.service has gone.

One more thing is the NetworkManager waits for online service, so let’s tweak that as well open a terminal session and switch to root user:

su -
Password:
vi /etc/sysconfig/network/config

We want to change the following entries:

1. WAIT_FOR_INTERFACES=”1″ from 30

2. NM_ONLINE_TIMEOUT=”0″

systemd-analyze 
Startup finished in 4.422s (firmware) + 1.443s (loader) + 1.619s (kernel) + 2.940s (initrd) + 7.709s (userspace) = 18.136s 
graphical.target reached after 7.691s in userspace
systemd-analyze blame | head -n 10
2.531s display-manager.service
2.081s postfix.service
1.926s systemd-localed.service
1.921s sshd.service
1.797s kdump.service
1.742s apparmor.service
1.714s dracut-initqueue.service
1.223s kdump-early.service
1.173s lvm2-monitor.service
1.073s firewalld.service

The wait dropped to 13ms! 13ms NetworkManager-wait-online.service has now reduced the time to 18 odd seconds from the original 50.

Userspace

In another subjective section, we can analyze the critical-chain output:

systemd-analyze critical-chain 
The time when unit became active or started is printed after the "@" character.
The time the unit took to start is printed after the "+" character.

graphical.target @6.666s
└─display-manager.service @5.067s +1.598s
  └─time-sync.target @5.062s
    └─chronyd.service @4.832s +229ms
      └─network.target @4.826s
        └─NetworkManager.service @4.763s +62ms
          └─network-pre.target @4.761s
            └─firewalld.service @3.619s +1.141s
              └─polkit.service @3.463s +151ms
                └─basic.target @3.445s
                  └─sockets.target @3.445s
                    └─pcscd.socket @3.445s
                      └─sysinit.target @3.443s
                        └─apparmor.service @2.123s +1.319s
                          └─var.mount @2.075s +46ms
                            └─local-fs-pre.target @2.046s
                              └─lvm2-monitor.service @435ms +1.610s
                                └─dm-event.socket @421ms
                                  └─system.slice
                                    └─-.slice

I see the likes of pcscd, lvm2, and dm-event. I use neither a card reader nor lvm on my system, so I’m going to either remove the relevant packages or disable and mask the service. From the root user terminal session run:

zypper se -i pcsc
Loading repository data...
Reading installed packages...

S | Name         | Summary                   | Type
--+--------------+---------------------------+--------
i | libpcsclite1 | PC/SC Smart Card Library  | package
i | pcsc-lite    | PC/SC Smart Cards Library | package

Can we remove it?

zypper rm pcsc-lite libpcsclite1

The following 23 packages are going to be REMOVED:
NetworkManager-openconnect NetworkManager-openconnect-gnome NetworkManager-openconnect-lang apache-commons-logging flute java-11-openjdk java-11-openjdk-headless libbase libfonts libformula
liblayout libloader libpcsclite1 libreoffice-base librepository libserializer openconnect openconnect-lang pcsc-lite pentaho-libxml pentaho-reporting-flow-engine sac xml-commons-apis

Let’s not, we can just disable and mask the service as follows:

systemctl status pcscd.socket pcscd.service
● pcscd.socket - PC/SC Smart Card Daemon Activation Socket
     Loaded: loaded (/usr/lib/systemd/system/pcscd.socket; enabled; vendor preset: enabled)
     Active: active (listening) since Thu 2021-11-04 07:27:44 CDT; 1h 1min ago
   Triggers: ● pcscd.service
     Listen: /run/pcscd/pcscd.comm (Stream)
     CGroup: /system.slice/pcscd.socket

Nov 04 07:27:44 ernie systemd[1]: Listening on PC/SC Smart Card Daemon Activation Socket.

● pcscd.service - PC/SC Smart Card Daemon
     Loaded: loaded (/usr/lib/systemd/system/pcscd.service; indirect; vendor preset: disabled)
     Active: inactive (dead)
TriggeredBy: ● pcscd.socket
       Docs: man:pcscd(8)

       Docs: man:pcscd(8)

systemctl stop pcscd.socket pcscd.service

systemctl disable pcscd.socket pcscd.service
Removed /etc/systemd/system/sockets.target.wants/pcscd.socket.

systemctl mask pcscd.socket pcscd.service
Created symlink /etc/systemd/system/pcscd.socket → /dev/null.
Created symlink /etc/systemd/system/pcscd.service → /dev/null.

Yet another reboot and inspect the critical-chain output:

systemd-analyze critical-chain

graphical.target @6.378s
└─display-manager.service @4.680s +1.697s
  └─time-sync.target @4.674s
    └─chronyd.service @4.564s +110ms
      └─network.target @4.557s
        └─NetworkManager.service @4.496s +59ms
          └─network-pre.target @4.494s
            └─firewalld.service @3.423s +1.070s
              └─polkit.service @3.259s +160ms
                └─basic.target @3.241s
                  └─sockets.target @3.241s
                    └─iscsid.socket @3.241s
                      └─sysinit.target @3.239s
                        └─apparmor.service @1.698s +1.541s
                          └─var.mount @1.618s +77ms
                            └─local-fs-pre.target @1.598s
                              └─lvm2-monitor.service @419ms +1.178s
                                └─dm-event.socket @407ms
                                  └─system.slice
                                    └─-.slice

Let’s now look at removing lvm2:

zypper se -i lvm2

  | liblvm2cmd2_03     | LVM2 command line library    | package
  | lvm2               | Logical Volume Manager Tools | package

zypper rm lvm2  liblvm2cmd2_03

The following 2 packages are going to be REMOVED:
  liblvm2cmd2_03 lvm2

2 packages to remove.
After the operation, 5.7 MiB will be freed.
Continue? [y/n/v/...? shows all options] (y): 
(1/2) Removing lvm2-2.03.05-8.36.1.x86_64 ......................................................................................................................................................[done]
Additional rpm output:
Removed /etc/systemd/system/sysinit.target.wants/lvm2-monitor.service.
Removed /etc/systemd/system/sysinit.target.wants/lvm2-lvmpolld.socket.
rm: cannot remove '/var/lib/systemd/migrated/lvm2-lvmpolld': No such file or directory
rm: cannot remove '/var/lib/systemd/migrated/lvm2-lvmpolld': No such file or directory
rm: cannot remove '/var/lib/systemd/migrated/blk-availability': No such file or directory
rm: cannot remove '/var/lib/systemd/migrated/lvm2-monitor': No such file or directory


(2/2) Removing liblvm2cmd2_03-2.03.05-8.36.1.x86_64 ............................................................................................................................................[done]

zypper al liblvm2cmd2_03 lvm2

Specified locks have been successfully added.

All looking good, so reboot and check:

systemd-analyze critical-chain 

graphical.target @6.234s
└─multi-user.target @6.234s
  └─cron.service @6.233s
    └─postfix.service @4.523s +1.708s
      └─time-sync.target @4.513s
        └─chronyd.service @4.279s +233ms
          └─network.target @4.273s
            └─NetworkManager.service @4.210s +62ms
              └─network-pre.target @4.208s
                └─firewalld.service @3.084s +1.122s
                  └─polkit.service @2.879s +200ms
                    └─basic.target @2.854s
                      └─sockets.target @2.854s
                        └─iscsid.socket @2.854s
                          └─sysinit.target @2.851s
                            └─systemd-backlight@backlight:amdgpu_bl0.service @3.282s +30ms
                              └─system-systemd\x2dbacklight.slice @3.280s
                                └─system.slice
                                  └─-.slice

I see there is an iscsi entry now; again I don’t use this, so we can remove it:

zypper se -i iscsi
Loading repository data...
Reading installed packages...

S | Name                 | Summary                                   | Type
--+----------------------+-------------------------------------------+--------
i | iscsiuio             | Linux Broadcom NetXtremem II iscsi server | package
i | libopeniscsiusr0_2_0 | The iSCSI User-level Library              | package
i | open-iscsi           | Linux iSCSI Software Initiator            | package
i | yast2-iscsi-client   | YaST2 - iSCSI Client Configuration        | package


zypper rm iscsiuio libopeniscsiusr0_2_0  open-iscsi  yast2-iscsi-client

The following 4 packages are going to be REMOVED:
  iscsiuio libopeniscsiusr0_2_0 open-iscsi yast2-iscsi-client

4 packages to remove.
After the operation, 2.5 MiB will be freed.
Continue? [y/n/v/...? shows all options] (y): 

zypper al iscsiuio libopeniscsiusr0_2_0  open-iscsi  yast2-iscsi-client

I also added iscsi lvm mdraid dm dmraid to omit modules and iscsi_if iscsi_tcp to omit_drivers in my 01-ernie.conf dracut conf file at this point as well.

Now, during boot, I also saw a warning appear with acpi backlight, but this system uses systemd- backlight@backlight:amdgpu_bl0.service so can also look at disabling, note two services since have two GPUs….

journalctl -b | grep backlight

Nov 04 08:36:33 ernie systemd[1]: Created slice Slice /system/systemd-backlight.
Nov 04 08:36:33 ernie systemd[1]: Starting Load/Save Screen Backlight Brightness of backlight:amdgpu_bl0...
Nov 04 08:36:33 ernie systemd[1]: Starting Load/Save Screen Backlight Brightness of backlight:acpi_video0...
Nov 04 08:36:33 ernie systemd[1]: Starting Load/Save Screen Backlight Brightness of backlight:acpi_video1...
Nov 04 08:36:33 ernie systemd-backlight[1389]: Failed to get backlight or LED device 'backlight:acpi_video1': No such device
Nov 04 08:36:33 ernie systemd[1]: systemd-backlight@backlight:acpi_video1.service: Main process exited, code=exited, status=1/FAILURE
Nov 04 08:36:33 ernie systemd[1]: systemd-backlight@backlight:acpi_video1.service: Failed with result 'exit-code'.
Nov 04 08:36:33 ernie systemd[1]: Failed to start Load/Save Screen Backlight Brightness of backlight:acpi_video1.
Nov 04 08:36:33 ernie systemd-backlight[1384]: Failed to get backlight or LED device 'backlight:acpi_video0': No such device
Nov 04 08:36:33 ernie systemd[1]: Finished Load/Save Screen Backlight Brightness of backlight:amdgpu_bl0.
Nov 04 08:36:33 ernie systemd[1]: systemd-backlight@backlight:acpi_video0.service: Main process exited, code=exited, status=1/FAILURE
Nov 04 08:36:33 ernie systemd[1]: systemd-backlight@backlight:acpi_video0.service: Failed with result 'exit-code'.
Nov 04 08:36:33 ernie systemd[1]: Failed to start Load/Save Screen Backlight Brightness of backlight:acpi_video0.

We can use systemctl to check, disable and mask:

systemctl status systemd-backlight@backlight:acpi_video0.service
● systemd-backlight@backlight:acpi_video0.service - Load/Save Screen Backlight Brightness of backlight:acpi_video0
     Loaded: loaded (/usr/lib/systemd/system/systemd-backlight@.service; static)
     Active: failed (Result: exit-code) since Thu 2021-11-04 08:36:33 CDT; 15min ago
       Docs: man:systemd-backlight@.service(8)
   Main PID: 1384 (code=exited, status=1/FAILURE)

systemctl status systemd-backlight@backlight:acpi_video1.service
● systemd-backlight@backlight:acpi_video1.service - Load/Save Screen Backlight Brightness of backlight:acpi_video1
     Loaded: loaded (/usr/lib/systemd/system/systemd-backlight@.service; static)
     Active: failed (Result: exit-code) since Thu 2021-11-04 08:53:36 CDT; 38s ago
       Docs: man:systemd-backlight@.service(8)
    Process: 1355 ExecStart=/usr/lib/systemd/systemd-backlight load backlight:acpi_video1 (code=exited, status=1/FAILURE)
   Main PID: 1355 (code=exited, status=1/FAILURE)

Nov 04 08:53:36 ernie systemd[1]: Starting Load/Save Screen Backlight Brightness of backlight:acpi_video1...
Nov 04 08:53:36 ernie systemd-backlight[1355]: Failed to get backlight or LED device 'backlight:acpi_video1': No such device
Nov 04 08:53:36 ernie systemd[1]: systemd-backlight@backlight:acpi_video1.service: Main process exited, code=exited, status=1/FAILURE
Nov 04 08:53:36 ernie systemd[1]: systemd-backlight@backlight:acpi_video1.service: Failed with result 'exit-code'.
Nov 04 08:53:36 ernie systemd[1]: Failed to start Load/Save Screen Backlight Brightness of backlight:acpi_video1.
Nov 04 08:36:33 ernie systemd[1]: Starting Load/Save Screen Backlight Brightness of backlight:acpi_video0...
Nov 04 08:36:33 ernie systemd-backlight[1384]: Failed to get backlight or LED device 'backlight:acpi_video0': No such device
Nov 04 08:36:33 ernie systemd[1]: systemd-backlight@backlight:acpi_video0.service: Main process exited, code=exited, status=1/FAILURE
Nov 04 08:36:33 ernie systemd[1]: systemd-backlight@backlight:acpi_video0.service: Failed with result 'exit-code'.
Nov 04 08:36:33 ernie systemd[1]: Failed to start Load/Save Screen Backlight Brightness of backlight:acpi_video0.

systemctl stop systemd-backlight@backlight:acpi_video0.service

systemctl disable systemd-backlight@backlight:acpi_video0.service

systemctl mask systemd-backlight@backlight:acpi_video0.service
Created symlink /etc/systemd/system/systemd-backlight@backlight:acpi_video0.service → /dev/null.

systemctl stop systemd-backlight@backlight:acpi_video1.service

systemctl disable systemd-backlight@backlight:acpi_video1.service

systemctl mask systemd-backlight@backlight:acpi_video1.service
Created symlink /etc/systemd/system/systemd-backlight@backlight:acpi_video1.service → /dev/null.

After a reboot, the warnings have gone, from boot to the desktop in around 15 seconds.

Summary

In closing, I hope you have successfully tweaked your system and have improved the boot speed.

I started with:

Startup finished in 4.477s (firmware) + 7.963s (loader) + 3.554s (kernel) + 3.258s (initrd) + 31.249s (userspace) = 50.504s

I finished with:

Startup finished in 2.390s (firmware) + 1.437s (loader) + 1.635s (kernel) + 3.044s (initrd) + 6.045s (userspace) = 14.553s

This was approximately a 36-second improvement, with around 25 of those seconds in userspace.

You may also be interested in YaST -> System -> Services Manager to peruse all the systemd services running and status as there may be others you wish to disable and/or mask.

page17image31722752

Only for advanced users: As a test, you can consider setting the option to zero and hide grub, but I would suggest the 1-second delay until you’re sure after a few update cycles (especially kernel updates) that nothing unfavorable may occur. This reduced the loader time from 1.4 seconds to 370ms, and the overall warm boot time of 13.390s.

My cold boot time after all the tweaks is:

Startup finished in 3.048s (firmware) + 382ms (loader) + 1.632s (kernel) + 2.990s (initrd) + 6.048s (userspace) = 14.103s

If I also time the boot by pressing the power button on, it’s around 20 seconds. Enjoy and remember to have fun!

Laptop Hardware Summary

HP Pavilion Notebook 15-aw057nr born 03/29/2017, BIOS F32A 04/25/2019

Boot: UEFI (Secure boot and TPM disabled)

CPU: AMD A10-9600P RADEON R5, 10 COMPUTE CORES 4C+6G

GPU 1: [AMD/ATI] Wani [Radeon R5/R6/R7 Graphics]

GPU 2: [AMD/ATI] Topaz XT [Radeon R7 M260/M265/M340/M360/M440/M445/530/535/620/625 Mobile]

RAM: 12GB Samsung M471A1K43CB1-CRC @ 1866MT/s 

HDD: WDC WDS250G2B0A-00SM50 SATA 3.3, 6.0 Gb/s SSD

Want to make sure you don’t miss any of the action? Join the SUSE & Rancher Community to get updates on new content coming your way!

SUSE addresses BootHole security exposure

Monday, 27 July, 2020

Security researchers from Eclypsium have published an attack called BootHole today. This attack requires root access to the bootloader used in Linux operating systems, GRUB2. It bypasses normal Secure Boot protections to persistently install malicious code which cannot be detected by the operating system.

Given the need for root access to the bootloader, the described attack appears to have limited relevance for most cloud computing, data center and personal device scenarios, unless these systems are already compromised by another known attack. However, it does create an exposure when untrusted users can access a machine, e.g. bad actors in classified computing scenarios or computers in public spaces operating in unattended kiosk mode. These are scenarios which Secure Boot was intended to protect against.

SUSE has released fixed grub2 packages which close the BootHole vulnerability for all SUSE Linux products, and is releasing corresponding Linux kernel packages, cloud image and installation media updates. Please follow the normal update procedure to install them. Should you be unsure about your company’s procedure, please consult your local system administrator.

To ensure that sophisticated attackers cannot reinstall old versions of grub2, software and hardware vendors are working together. Over time, vendors are going to update cryptographic keys in the BIOS for new computers, as well as to provide so-called DBX Exclusion List updates for existing computers. These can prevent unpatched systems and old installation media from starting. Please make sure you have installed all relevant bootloader and operating system updates for BootHole before installing a BIOS or DBX Exclusion List update to ensure continuity.

References: