openSUSE:UEFI

跳转到:导航搜索

关于 UEFI

标准介绍

UEFI(统一可扩展固件接口)是一个行业标准,它规定了系统在预启动环境中必须提供的各种接口。UEFI 将控制系统从上电到操作系统完全加载。此外,UEFI 负责在系统提供的资源和操作系统之间提供接口。

换句话说,UEFI 旨在取代并扩展旧的 BIOS 固件。

UEFI 并不是什么新鲜事物。Intel 自 20 世纪 90 年代中期以来一直在 EFI/UEFI 上工作,HP 或 Apple 等供应商很早以前就提供了 EFI 机器。但当微软宣布 Windows 8 时,UEFI 成为新认证机器所需的启动方式。

UEFI 规范(http://www.uefi.org/specs/)是一份庞大的文档,其中包含固件制造商必须提供的所有接口、变量和结构,以及操作系统可以访问这些接口、变量和结构。好消息是,Linux 自 2000 年以来一直可以使用 GRUB 或 elilo 在启动时使用 EFI。事实上,openSUSE 12.2 支持 UEFI,并且从 openSUSE 12.3 开始,对 Secure Boot 扩展提供了实验性支持。

安全启动是 UEFI 的扩展。UEFI 的关键点之一是它可以被扩展。UEFI 具有一个内部虚拟机,该虚拟机独立于其使用的体系结构。该标准接受为该虚拟机编译的特殊二进制文件(EFI 二进制文件),这些文件可以在环境中执行。这些二进制文件可以是设备驱动程序、应用程序或对 UEFI 标准的扩展。从某种意义上说,UEFI 就像一个小操作系统,它在机器上电时运行,其主要任务是找到并加载另一个操作系统。

如何确定您是否拥有 UEFI 机器?通常,在开机过程中按F1(或ESC(取决于机器)检查固件配置。通过浏览菜单,可以发现机器可以在传统模式(旧 BIOS 模式)、EFI 模式和混合模式下运行,其中将根据加载的操作系统选择实际模式。

如果您的机器没有 UEFI 支持,并且您想使用 openSUSE 测试这项新技术,可以使用 QEMU 和 Intel 的 UEFI 参考实现:UEFI 和 Secure Boot 与 QEMU


GPU 支持 - UEFI GOP

图形输出协议 (GOP) 由 UEFI 驱动程序启用,以支持预操作系统阶段的图形控制台输出。如果没有 GOP 支持,可以使用 UEFI CSM(兼容性支持模式),它模拟旧版 BIOS 行为。


GOP 的最终目标是取代旧版 VGA BIOS 并消除 VGA HW 功能。UEFI 的一个影响是取代了依赖于 16 位 x86 兼容性的旧版 BIOS 中断调用,并使用协议。BIOS 用于定义显示适配器支持的模式的传统 VESA 模式依赖于软件中断,因此必须进行替换。结果是 UEFI 图形输出协议 (GOP),它取代了复杂的模式集,并使用简单的视频缓冲区。GOP 只是定义了特定分辨率和颜色深度的缓冲区。这使得支持新分辨率或使显示缩放到不同分辨率变得更容易。在实际使用中也有一些常见的分辨率(例如,Microsoft Windows 需要 1024x768 和 800x600 的 GOP,Intel EPOG 支持 800x600 的 GOP)。这种实现上的简单性使得 BIOS 和预启动应用程序的 GUI 开发更加容易,例如 AMI Provisioning 环境。

UEFI GOP 的硬件支持

使用 https://www.techpowerup.com/vgabios/ 站点检查硬件支持。您可能需要升级视频 BIOS 以获得 UEFI GOP 支持。

AMD UEFI GOP

AMD 自 Evergreen 以来就支持 UEFI GOP,但一些供应商将其延迟到 Radeon 300 系列

Nvidia UEFI GOP

Nvidia 自 Kepler 架构的 700 系列以来就支持 UEFI GOP。对于 Kepler 600 系列,您需要升级视频 BIOS。

Intel UEFI GOP

Intel Arc 独立显卡比较新,支持 UEFI GOP。但是,它们不支持传统 BIOS 启动。

手动添加 UEFI GOP 支持

使用此 手册 升级您的视频 BIOS。注意:请勿中断升级过程。错误的视频 BIOS 可能会导致设备损坏。


GPT

UEFI 改变了固件、系统调用和接口等更多内容。它还提出了一种新的硬盘分区方式。GUID 分区表 (GPT) 旨在取代旧的 Master Boot Record (MBR) 解决方案。

MBR 有一些重要的限制,例如主分区和逻辑分区的数量以及这些分区的大小。GPT 解决了这些问题,现在可以拥有任意数量的分区(以 128 个为一组)和可寻址磁盘空间为 2^64 字节(即,以艾字节为单位)。因此,如果您拥有大型磁盘,这就是您想要的分区表类型。另一个关键区别是 GPT 使用唯一的 UUID 编号引用每个分区,从而避免了分区标识符之间的冲突。

如果 YaST 检测到机器处于 EFI 模式,它将尝试在全新安装期间创建一个 GPT 分区。创建 GPT 分区后,不能再使用旧的 fdisk 工具来创建、删除或编辑分区。用于执行此操作的新工具是 gdisk,它包含在 gptfdisk 包中。该接口与我们熟悉的 fdisk 工具相同。

有时,如果我们计划进行一些测试并试验不同的模式,我们将希望从硬盘中删除 GPT 格式。我们可以使用 YaST2 执行此操作。为此,转到“专家分区程序”选项,选择正确的硬盘,然后在“专家...”按钮中选择“创建新的分区表”

Icon-warning.png
警告: 创建新的分区表将销毁所有现有分区及其中的数据。在执行此过程之前,您应该备份数据!

这将根据正在运行的系统替换分区表。


EFI 系统分区

EFI 系统分区 (ESP) 是 UEFI 期望找到可用于启动安装在设备上的所有操作系统的 EFI 程序的分区。此外,EFI 还会在此处找到在启动时使用的某些设备驱动程序以及需要在操作系统启动之前运行的其他工具。

此分区使用 FAT 文件系统,可以通过 YaST2 在全新安装期间创建,或在双引导机器中重用。这意味着,如果系统上之前安装了以前版本的 Windows,YaST2 将检测 EFI 分区,将用于加载 openSUSE 的新的 EFI 引导加载程序,并将分区挂载到 /boot/efi 挂载点。

默认情况下,固件将在 /EFI/BOOT/bootx64.efi 中搜索扩展名以加载并执行以加载操作系统。在 Windows 机器上,正确的扩展名位于 /EFI/Microsoft/Boot/BCD.efi 中,对于 openSUSE 位于 /EFI/opensuse/grubx64.efi(或如果启用了安全启动,则为 /EFI/opensuse/shim.efi

 # find /boot/efi /boot/efi /boot/efi/EFI /boot/efi/EFI/boot /boot/efi/EFI/boot/bootx64.efi /boot/efi/EFI/boot/fallback.efi /boot/efi/EFI/opensuse /boot/efi/EFI/opensuse/MokManager.efi /boot/efi/EFI/opensuse/grub.efi /boot/efi/EFI/opensuse/shim.efi /boot/efi/EFI/opensuse/boot.csv /boot/efi/EFI/opensuse/grub.cfg /boot/efi/EFI/opensuse/grubx64.efi 

ESP 和旧版 UEFI 固件

虽然 UEFI 标准要求固定驱动器使用 32 位 FAT,但旧版 UEFI 固件(“第一波”)只能使用 16 位 FAT。使用操作系统安装程序调整 ESP 参数。

最小 ESP 卷

对于 FAT32,512 字节扇区的最小卷为 32 MB。Windows 需要至少 100 MB 的 ESP。为了与 4K 驱动器兼容,操作系统安装程序默认使用 260 MB FAT32。您可以根据需要调整 ESP 参数。

启动管理器

为了选择正确的扩展来加载操作系统,EFI 为用户提供了一个内部启动管理器。操作系统负责为自身创建一个新的条目。我们可以在开机过程中启动启动管理器,并列出所有启动条目,通常按 F9 或 F12。但我们可以使用 efibootmgr 工具来查询和编辑这些条目。例如,要列出当前条目,我们可以运行 efibootmgr -v

 # efibootmgr -v BootCurrent: 0006 Timeout: 0 seconds BootOrder: 0006,0005,0000,0001,0002,0003,0004 Boot0000* EFI DVD/CDROM ACPI(a0341d0,0)PCI(1,1)ATAPI(1,0,0) Boot0001* EFI Floppy ACPI(a0341d0,0)PCI(1,0)ACPI(60441d0,0) Boot0002* EFI Floppy 1 ACPI(a0341d0,0)PCI(1,0)ACPI(60441d0,0) Boot0003* EFI Hard Drive ACPI(a0341d0,0)PCI(1,1)ATAPI(0,0,0) Boot0004* EFI Internal Shell MM(b,3fa9e00,3ffbdfff) Boot0005* opensuse HD(1,800,4e000,f43c4206-073e-4e81-8940-fec01a69e79b)File(\EFI\opensuse\grubx64.efi) Boot0006* opensuse-secureboot HD(1,800,4e000,f43c4206-073e-4e81-8940-fec01a69e79b)File(\EFI\opensuse\shim.efi) 

我们可以看到 openSUSE 创建了两个不同的条目来启动。一个在安全模式下使用,另一个在非安全模式下使用。

如果由于某种原因我们丢失了其中一个条目,我们可以使用 efibootmgr 重新创建它。例如,要重新创建 'opensuse' 条目,我们可以执行

 # efibootmgr -c -L "openSUSE-alt" -l '\EFI\opensuse\grubx64.efi'


EFI 变量

UEFI 标准定义了一组存储在固件的非易失性部分中的变量。这些变量用于存储信息和控制 UEFI 系统的行为。当我们创建启动管理器的新的条目,或者启用或禁用安全启动选项时,我们就是在访问和更改其中一个变量的值。

我们可以通过 Sysfs 直接查询和访问这些变量,通过 openSUSE。Sysfs 是内核提供的一个虚拟文件系统,用于将一些内部信息导出到用户空间。我们可以在 '/sys/firmware/efi/vars/' 中找到这些变量。因此,例如,可以查询上一次启动加载程序条目:

$ hexdump -C /sys/firmware/efi/vars/Boot0007-*/data


安全启动

背景

UEFI 安全启动是一种限制可以执行哪些二进制文件来启动系统的方法。固件仅执行带有知名实体加密签名的启动加载程序。在安全启动的上下文中,X.509 证书用于标识实体。

如今,大多数带有默认启用安全启动的消费级 PC 硬件都预装了 Microsoft Windows 10。因此,固件只了解 Microsoft 作为启动加载程序签名的知名实体。为了能够在不重新配置已知签名颁发者列表或关闭安全启动的情况下启动 openSUSE,openSUSE 的启动加载程序必须带有 Microsoft 的签名。

openSUSE 中的实现

openSUSE 在 UEFI 系统上使用的默认启动加载程序是 grub2。在安全启动模式下,还使用了另一个启动加载程序,称为 'shim'。在这种模式下,不直接调用 grub2,而是固件首先加载 'shim'。'shim' 带有 Microsoft 的签名,以便被固件识别。'shim' 反过来又了解用于签名 grub2 的 openSUSE 证书。grub2 随后能够加载也由 openSUSE 证书签名的 Linux 内核。加载 Linux 内核后,安全启动的作用范围结束。openSUSE 中使用的 Linux 内核不会施加额外的限制。

为了允许使用自定义启动加载程序以及自定义内核,shim 提供了一种导入自定义签名的方法。程序 'MokManager' 用于此目的。当 'shim' 被指示加载未由知名实体签名的二进制文件时,它会调用 MokManager,允许将证书导入到已知签名颁发者数据库中。

同意信任内置的 openSUSE 证书

首次加载 openSUSE 'shim' 时,它会询问用户是否信任内置在 'shim' 中的 openSUSE 证书来验证 grub2 和 Linux 内核。

如果用户选择“是”,'shim' 会将答案存储在固件中的非易失性 UEFI 变量中,并且以后不会再打扰用户。用户可以使用以下命令确定是否信任 openSUSE 证书:

# od -An -t u1 /sys/firmware/efi/vars/use_openSUSE_cert-605dab50-e046-4300-abb6-3dd810dd8b23/data

对于正常的 openSUSE 系统,该命令输出 `1`。

如果用户想撤销 openSUSE 证书,以下命令将启动撤销过程:

# mokutil --revoke-cert

系统会要求用户输入密码,作为撤销过程的身份验证。在下一次启动过程中,将启动 MokManager 以完成撤销过程。

在撤销过程结束时,'MokManager' 会要求用户输入 'mokutil' 设置的密码,以完成 openSUSE 证书的撤销。


如何启用或禁用安全启动支持

x86_64

安装程序 YaST 可以自动检测是否启用了安全启动。在安装过程中,它提供了一个手动启用/禁用安全启动支持的选项。打开该选项对于安装 shim 是必需的。要在已安装的系统上启用或禁用安全启动支持,可以使用 YaST 启动加载程序模块。

AArch64

仅适用于 Tumbleweed 和 Leap 15.2+,没有 shim。


在 AArch64 上,没有 shim,因此您需要手动将 openSUSE 密钥安装到您的 UEFI 数据库 (DB) 中。请参阅 openSUSE:UEFI#Other_options 了解如何操作。

对于 x86_64,安装程序 YaST 可以自动检测是否启用了安全启动。在安装过程中,它提供了一个手动启用/禁用安全启动支持的选项。要在已安装的系统上启用或禁用安全启动支持,可以使用 YaST 启动加载程序模块。

如何确定系统是否已启用安全启动

要确定机器是否在固件中启用了安全启动,请在 Linux shell 中以 root 用户身份输入以下命令:

# od -An -t u1 /sys/firmware/efi/vars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c/data

如果命令输出 '1',则表示已启用安全启动。已知某些固件版本存在缺陷,即使启用了安全启动,也会显示 '0'。

启动自定义内核

安全启动不会阻止您使用自己编译的内核。您只需要使用自己的证书对其进行签名,并使该证书被固件或 MOK 识别即可。

  1. 创建用于签名的自定义 X.509 密钥和证书
    $ openssl req -new -x509 -newkey rsa:2048 -sha256 -keyout key.asc -out cert.pem -nodes -days 666 -addext extendedKeyUsage=1.3.6.1.5.5.7.3.3 -subj "/CN=$USER/"
  2. 将密钥和证书打包为 PKCS#12 结构
    $ openssl pkcs12 -export -inkey key.asc -in cert.pem -name kernel_cert -out cert.p12
  3. 生成 pesign 使用的 NSS 数据库
    $ certutil -d . -N
  4. 将 PKCS#12 中包含的密钥和证书导入到 NSS 数据库中
    $ pk12util -d . -i cert.p12
  5. 使用新的签名祝福内核
    $ pesign -n . -c kernel_cert -i arch/x86/boot/bzImage -o vmlinuz.signed -s
  6. 列出内核镜像上的签名
    $ pesign -S -i vmlinuz.signed

此时,您可以将内核安装到/boot通常情况下。由于内核现在具有自定义签名,因此需要将用于签名的证书导入到固件或 MOK 中。

在将证书注册到 UEFI 固件或 MOK 之前,您应该将其转换为 DER 格式

$ openssl x509 -in cert.pem -outform der -out cert.der

有两种方法可以注册 MOK 证书 - 使用 mokutil 或手动导入。前者建议使用,因为它使 MOK 证书管理更容易。

使用 mokutil 注册 MOK 证书 (x86* only)
  1. 导入上述步骤中生成并转换为 DER 格式的密钥
    # mokutil --import cert.der
  2. 检查并确认将要注册的新导入的密钥
    # mokutil --list-new
  3. 重新启动系统,它将在启动加载程序处自动进入 MokManager。
  4. 有四个选项:“Continue boot”“Enroll MOK”“Enroll key from disk”“Enroll hash from disk”。选择 “Enroll MOK,选择证书并确认。
  5. 重启。
  6. 确认注册的证书
    # mokutil --list-enrolled
从 MOKManager 手动注册 MOK 证书 (x86* only)
  1. 将证书复制到 ESP 以便更轻松地访问
    $ sudo cp cert.der /boot/efi/
  2. reboot
  3. 在 grub 菜单中按 'c'
  4. 输入(假设 ESP 是 'hd0' 上的 'gpt1')
    grub> chainloader (hd0,gpt1)/EFI/opensuse/MokManager.efi
    grub> boot
  5. 选择 “Enroll key from disk”
  6. 导航到 cert.der 文件并按 enter
  7. 按照说明注册密钥。通常这应该按 '0' 然后按 'y' 进行确认
其他选项

或者,固件菜单可能提供添加新密钥到 'db' 的方法。

对于此操作,您需要将 /usr/share/efi/aarch64/grub.der 文件添加到可从您的 UEFI 访问的 FAT 分区(USB 存储设备或 openSUSE 安装的 EFI 分区)。
然后,对于基于 EDK2 的 UEFI,您需要转到 Device Manager > Secure Boot Configuration > Secure Boot Mode。如果尚未启用,请启用 Secure Boot 并选择 Custom Mode。转到 Custom Secure Boot Option > DB Options > Enroll Signature > Enroll Signature using File,选择正确的设备(USB 存储设备或 HDD),然后转到 File Explorer 中的文件并按 enter 键进行验证。您可以输入 Signature GUID(可选)。最后,Commit Changes And Exit。返回主菜单,多次按 escape,然后选择 Continue 以继续使用新密钥启动过程。

从 Kernel:stable 仓库启动内核

Kernel:stable 仓库启动内核类似于启动自定义内核。区别在于,您不是创建自己的密钥和证书,而是使用仓库中的证书。

  • 通过单击“GPG Key / SSL Certificate GPG Key / SSL Certificate”和“SSL Cert.” 从仓库下载 .crt 证书。
  • 将证书转换为 DER 格式,以便导入到 UEFI 固件或 MOK 中
    openssl x509 -in Kernel\ builds\ for\ branch\ stable_ssl.cert -outform der -out cert.der
  • 将证书复制到 ESP 以便更轻松地访问
    sudo cp cert.der /boot/efi/
  • 启动到 MokManager 或固件界面,并按照自定义内核说明注册密钥。

启动仅提供供应商提供的密钥的机器

如果固件菜单提供重置安全启动所用密钥的选项,您可以导入新的 PK、KEK 和 db,而无需 Microsoft 密钥。导入/usr/lib64/efi/shim-opensuse.der到 db 以在这种情况下启动 openSUSE 内核。默认 shim 同时由 Microsoft 和 openSUSE 签名。某些固件版本不支持双重签名,因此在这种情况下安装/usr/lib64/efi/shim-opensuse.efi它只有 openSUSE 签名作为/boot/efi/EFI/opensuse/shim.efi

启动仅支持带有供应商提供的密钥的单个签名的机器

某些固件可能无法解析 EFI 镜像中的多个签名,并且默认 shim 在这种情况下将失败。如果固件菜单不提供安装新密钥的选项,则必须手动剥离 openSUSE 签名才能解决此问题。

  1. 安装 mozilla-nss-tools 和 pesign
    zypper install mozilla-nss-tools pesign
  2. 创建一个临时 nss 数据库
    mkdir certdb
    certutil -N -d certdb
    (按“Enter”忽略密码请求)
  3. 剥离 openSUSE 签名
    pesign -n certdb/ -r -i /usr/lib64/efi/shim.efi -o shim.efi -u 1
  4. 将默认 shim.efi 替换为新生成的 shim.efi
    mv shim.efi /boot/efi/EFI/opensuse/shim.efi
  5. 删除临时 nss 数据库
    rm -rf certdb

每次更新 shim 时都必须执行这些步骤。这种类型的固件应该越来越少,因为多签名支持已经包含在 edk2 上游中一年多,但它仍然可能发生在旧机器上。

创建 RPM 脚本来自动在软件包更新时剥离签名

RPM 脚本是一系列可以在 RPM 安装或安装后对系统施加必要或所需更改的指令。以下说明建议使用您自己的 RPM 构建一个简单的脚本,该脚本将执行上述相同的操作以剥离 openSUSE 签名。

  1. 安装 rpm-build 包
    zypper install rpm-build
  2. 创建新 RPM 的目录结构
    mkdir name_of_rpm
    cd name_of_rpm
    mkdir -p BUILD RPMS SOURCES SPECS SRPMS
  3. 使用以下内容创建文件 SPECS/name_of_rpm.spec(vim 将从模板生成它以方便您)
    Name: name_of_rpm
    Version: 1.0
    Release: 0
    Summary: shim secure boot signing script
    License: GPL
    BuildRequires: pesign

    %description

    %post
    %postun
    %triggerin -- shim,grub2-x86_64-efi
    # password prompt is optional, so we avoid it
    # this directory is suggested to avoid certutil "bad database" error
    certutil -N -d /root/.pki/nssdb/ --empty-password
    pesign -n /root/.pki/nssdb/ -r -i /usr/lib64/efi/shim.efi -o /root/shim.efi -u 1
    mv /root/shim.efi /boot/efi/EFI/opensuse/shim.efi
    rm /root/.pki/nssdb/*

    %files
  4. 构建 rpm(-bb 表示仅构建二进制文件,不带源代码)
    rpmbuild -v -bb SPECS/name_of_rpm.spec
  5. 安装新的 rpm(需要 root 权限)
    rpm -i ~/rpmbuild/RPMS/x86_64/name_of_rpm-1.0-0.x86_64.rpm

该脚本将在安装 RPM 后立即应用。下次升级 shim 或 grub2-x86_64-efi 包时,该脚本let 将被触发以剥离签名。如果您知道在升级时更新 shim 的任何其他包,可以在 %triggerin 行的末尾用逗号分隔它们。现在可以删除 rpmbuild 目录,它是新 RPM 构建的默认位置。

此脚本let 有两个小问题

  • 如果在 %triggerin 行中指定了多个包,则在 openSUSE 升级期间会重复剥离签名,这是多余的。
  • grub2-x86_64-efi 似乎有一个安装后脚本let,该脚本let 在安装后更新 shim。但是,%triggerin 指令不考虑此类脚本let,并且仅在目标包正在安装时调用,换句话说,shim 之后将被更新。

启用 shim 中的验证过程

在加载 shim 时,您可能会收到“以不安全模式启动”警告。您可以使用以下命令删除它:

# mokutil --enable-validation

这将为操作系统启用安全启动验证。请记住,这将阻止加载未签名的内核模块。如果您想禁用它,请运行

# mokutil --disable-validation


签名内核模块进行验证

当 openSUSE 内核使用 UEFI 安全启动启动时,内核模块验证将被自动启用。因此,您的自建内核模块必须签名,否则无法通过内核模块验证。

创建用于签名的密钥对

要使用 openssl req 命令创建签名密钥和证书,请键入以下内容:

 export USER="你的名字" export privkey="signing_key.pem" export pubkey="signing_key.x509" openssl req -new -x509 -newkey rsa:2048 \ -keyout $privkey \ -outform DER -out $pubkey -days 36500 \ -subj "/CN=$USER/" \ -addext "extendedKeyUsage=codeSigning" \ -nodes 

为了使 openSUSE Leap/Tumbleweed 最新内核版本能够接受用于内核模块签名验证的证书,需要设置 EKU codeSigning。-addext 选项需要 OpenSSL 1.1.1 或更高版本。对于较早版本的 OpenSSL,请参阅文档以了解如何设置 EKU。

请按照 使用 mokutil 注册 MOK 证书 部分,将 signing_key.x509 注册到 MOK。重启后,内核将加载 MOK 到内核密钥环并使用它来验证内核模块。

签名内核模块

有两种工具可用于签名内核模块。

第一个工具是 pesign-obs-integration 包中的 kernel-sign-file。以下是使用 kernel-sign-file 工具签名 .ko 文件的示例命令

 /usr/lib/rpm/pesign/kernel-sign-file -i pkcs7 sha256 ./signing_key.pem ./signing_key.x509 your_module.ko 

另一个工具是 Linux 内核源代码中的 scripts/sign-file.c。在使用它之前需要编译它。

 ./scripts/sign-file sha256 ./signing_key.pem ./signing_key.x509 ./your_module.ko 

您可以使用 hexdump 命令来检查签名是否附加到 your_module.ko 文件的末尾。例如

 hexdump -C your_module.ko 
 [..snip] 00015250 2d f6 15 a8 8d 60 00 fb 38 5a 3c 45 e3 52 9d db |-....`..8Z<E.R..| 00015260 80 88 af a8 c5 82 42 82 18 c9 c9 a5 aa e6 87 a9 |......B.........| 00015270 cf b9 18 96 c5 36 e9 8c 78 5b 86 84 e8 8b 99 95 |.....6..x[......| 00015280 24 8a 57 b9 1b e8 c8 0f 9a ae f6 dc 16 e2 60 56 |$.W...........`V| 00015290 4c 6a df a4 ef 72 d7 41 6e b4 63 6c 79 fe 9a ce |Lj...r.An.cly...| 000152a0 ca 08 90 ba 94 41 4b 36 7f d5 79 fd 27 74 59 5d |.....AK6..y.'tY]| 000152b0 40 64 7a 70 96 b8 09 c0 16 a2 63 df 14 66 66 00 |@dzp......c..ff.| 000152c0 00 02 00 00 00 00 00 00 00 01 8f 7e 4d 6f 64 75 |...........~Modu| 000152d0 6c 65 20 73 69 67 6e 61 74 75 72 65 20 61 70 70 |le signature app| 000152e0 65 6e 64 65 64 7e 0a |ended~.| 000152e7 

您应该在 .ko 文件的末尾找到一个魔术字符串“~Module signature appended~”。这意味着已附加了一个签名块。

然后您可以使用 modprobe 或 insmod 命令来探测您的内核模块。内核将使用内核密钥环中的 MOK 来验证内核模块。

本地构建和签名 NVIDIA 驱动程序

由于许可情况,NVIDIA 只能在您的本地机器上构建。这意味着 NVIDIA .ko 文件必须在本地签名。openSUSE 的 NVIDIA kmp 在 RPM 脚本中完成了这项工作。当启用安全启动时,NVIDIA kmp 可以自动构建 ko 文件并使用一次性密钥对自动签名它们。它还会调用 mokutil 将一次性公钥注册到 MOK。请查看 SDB:NVIDIA_drivers#Secureboot 以获取更多详细信息。

重置 SBAT 字符串以引导到旧 Leap 镜像中的旧 shim

我们从 Leap 15.5 开始引入了新的 15.7 shim。15.7 shim 是完全支持 SBAT 机制的第一个版本。SBAT 机制通常用于阻止具有安全问题的旧 shim。有关 SBAT 的详细信息,您可以查看 此文档

情况

您已安装 Leap 15.5,这意味着 shim 15.7 现在是您的默认第一阶段引导加载程序。然后您想在 Leap 15.4 iso 镜像中引导旧 shim 15.4。但是 shim 15.4 被 SBAT 自我阻止机制阻止。您会在屏幕上看到以下消息

 Verifying shim SBAT data failed: Security Policy Violation Something has gone serously wrong: SBAT self-check failed: Security Policy Violation 

注意
上述违反消息是由 shim 15.4 的 SBAT 自我阻止机制暴露的。这种机制是 Leap 15.4 iso 镜像中的旧 shim 15.4 支持的唯一 SBAT 功能。

逐步重置 SBAT

本节是重置 SBAT efi 变量(也称为 SbatLevelRT)的逐步指南。在将 SBAT 重置为原始模式之前,请注意您需要承担安全风险,因为旧 shim 存在安全问题。这就是我们使用 SBAT 机制来阻止旧 shim 的原因。

1. 重启到固件 UI 以禁用安全启动

2. 引导到 Leap 15.5,在终端中运行 mokutil 命令

检查安全启动状态:

 localhost:~ # mokutil --sb SecureBoot disabled 

检查 SbatLevelRT 变量中的当前 SBAT 字符串。默认模式为“latest”,如下所示:

 localhost:~ # mokutil --list-sbat-revocations sbat,1,2022111500 shim,2 grub,3 

运行 mokutil 将 SBAT 策略设置为“delete”

 localhost:~ # mokutil --set-sbat-policy delete 

您可以 hexdump SbatPolicy efi 变量以进行确认,命令 3 将被写入 SbatPolicy 变量

 localhost:~ # hexdump /sys/firmware/efi/efivars/SbatPolicy-605dab50-e046-4300-abb6-3dd810dd8b23 0000000 0007 0000 0003 0000005 

3. 重启到 Leap 15.5

这意味着引导到 shim 15.7。shim 15.7 将执行删除任务并将 SbatLevelRT 变量重置为“original”模式。

注意
请不要引导到 Leap 15.4(这意味着您引导到 shim 15.4)。旧 shim 15.4 不支持用于重置 SbatLevelRT 的“--set-sbat-policy”命令。shim 15.4 将忽略 mokutil 删除命令。

4. 确认 SBAT 已设置为“original”模式

现在您仍然引导到 Leap 15.5,在终端中运行 mokutil 命令以确认 SBAT 字符串已更改为“original”模式(也称为 delete)

 localhost:~ # mokutil --list-sbat-revocations sbat,1,2021030218 

如上所示,原始字符串仅包含一个 SBAT 版本,没有 shim 或 grub2 SBAT 条目。这意味着 shim SBAT 不会阻止任何内容。

5. 现在您可以重启到固件 UI 以启用安全启动。

6. 然后引导到 Leap 15.4 镜像中的旧 shim 15.4。SBAT 自我阻止机制现在不会阻止 shim 15.4 本身。

术语表

PK
“平台密钥”通常是指硬件供应商安装在机器上的证书。为了能够修改 KEK,需要有效的 PK 签名。
KEK
需要有效的“密钥交换密钥”签名才能更新签名数据库。
db
签名数据库包含已知的证书、签名或二进制文件的哈希值。固件只能使用该数据库验证的二进制文件才能执行。需要有效的 KEK 签名才能更新签名数据库。
dbx
Forbidden Signatures Database 是 'db' 的相反,基本上是证书、签名和哈希值的黑名单。如果二进制文件与任何条目匹配,则无法执行它。需要有效的 KEK 签名才能更新 Forbidden Signature Database。
MOK
机器所有者密钥。MokManager 使用的额外证书或哈希数据库。MokManager 可以在启动期间由用户交互式地用于更新 MOK。