UEFI (统一可扩展固件接口) 是系统硬件附带的固件、系统所有硬件组件以及操作系统之间的接口。
UEFI 正在越来越多的 PC 系统上可用,因此正在取代传统的 PC-BIOS。例如,UEFI 恰当地支持 64 位系统,并提供安全启动(需要固件版本 2.3.1c 或更高版本),这是其最重要的功能之一。最后,通过 UEFI,所有 x86 平台都将提供标准的固件。
UEFI 此外还提供以下优势
从大于 2 TiB 的磁盘启动,使用 GUID 分区表 (GPT)。
CPU 独立架构和驱动程序。
具有网络功能的灵活的预操作系统环境。
CSM(兼容性支持模块),用于通过类似 PC-BIOS 的仿真来支持启动传统操作系统。
有关更多信息,请参阅 https://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface。以下章节并非作为 UEFI 的一般概述;这些只是关于某些功能在 openSUSE Leap 中实现方式的提示。
在 UEFI 的世界中,确保引导过程意味着建立信任链。 “平台” 是此信任链的根;在 openSUSE Leap 的上下文中,主板和板载固件可以被认为是“平台”。换句话说,它是硬件供应商,信任链从该硬件供应商流向组件制造商、操作系统供应商等。
信任通过公钥密码学表达。硬件供应商将所谓的平台密钥 (PK) 放入固件中,代表信任的根。与操作系统供应商等的信任关系通过使用平台密钥对他们的密钥进行签名来记录。
最终,通过要求固件仅执行已由这些“受信任”密钥(无论是操作系统引导加载程序、位于某些 PCI Express 卡或磁盘上的闪存中的驱动程序,还是固件本身的更新)签名的代码来建立安全性。
要使用安全启动,需要使用固件信任的密钥对您的操作系统加载程序进行签名,并且需要操作系统加载程序验证其加载的内核是否可信。
可以将密钥交换密钥 (KEK) 添加到 UEFI 密钥数据库。这样,如果它们使用 PK 的私钥签名,您可以使用其他证书。
默认情况下安装了 Microsoft 的密钥交换密钥 (KEK)。
安全启动默认在 UEFI/x86_64 安装上启用。您可以在“引导加载程序设置”对话框的“引导代码选项”选项卡中找到“启用安全启动支持”选项。它支持在固件中激活安全启动时进行引导,同时也可以在固件停用时进行引导。
安全启动功能要求 GUID 分区表 (GPT) 替换旧的分区,使用主引导记录 (MBR)。如果 YaST 在安装过程中检测到 EFI 模式,它将尝试创建一个 GPT 分区。UEFI 期望在 FAT 格式化的 EFI 系统分区 (ESP) 上找到 EFI 程序。
支持 UEFI 安全启动需要具有固件识别为受信任密钥的数字签名的引导加载程序。该密钥默认受固件信任,无需任何手动干预。
有两种方法可以实现这一点。一种是与硬件供应商合作,让他们认可 SUSE 密钥,然后 SUSE 使用该密钥对引导加载程序进行签名。另一种方法是通过 Microsoft 的 Windows Logo 认证计划来认证引导加载程序,并让 Microsoft 认可 SUSE 签名密钥(即使用他们的 KEK 对其进行签名)。到目前为止,SUSE 已通过 UEFI 签名服务(在本例中为 Microsoft)对加载程序进行了签名。
在实现层面上,SUSE 使用默认安装的 shim 加载程序。这是一个巧妙的解决方案,可以避免法律问题,并大大简化认证和签名步骤。 shim 加载程序的工作是加载一个引导加载程序,例如 GRUB 2 并对其进行验证;该引导加载程序反过来将仅加载由 SUSE 密钥签名的内核。
有两种类型的受信任用户
首先,那些持有密钥的人。平台密钥 (PK) 允许几乎所有操作。密钥交换密钥 (KEK) 允许 PK 可以执行的所有操作,但不包括更改 PK。
其次,任何具有对机器的物理访问权限的人。具有物理访问权限的用户可以重新启动机器并配置 UEFI。
UEFI 提供两种类型的变量来满足这些用户的需求
第一种是所谓的“认证变量”,可以从引导过程(所谓的引导服务环境)和正在运行的操作系统中进行更新。只有当变量的新值使用与变量的旧值相同的密钥签名时,才能这样做。并且只能附加到或更改为具有较高序列号的值。
第二种是所谓的“仅引导服务变量”。这些变量可供在引导过程中运行的任何代码访问。在引导过程结束后并在操作系统启动之前,引导加载程序必须调用 ExitBootServices 调用。之后,这些变量将不再可访问,操作系统无法触及它们。
UEFI 密钥列表是第一种类型,因为这允许在线更新、添加和黑名单密钥、驱动程序和固件指纹。正是第二种类型的变量,“仅引导服务变量”,有助于以安全和开源友好的方式实现安全启动,从而与 GPLv3 兼容。
SUSE 从 shim 开始——一个由 SUSE 和 Microsoft 签名的小型简单的 EFI 引导加载程序。
这允许 shim 加载和执行。
shim 然后继续验证它想要加载的引导加载程序是否受信任。在默认情况下,shim 将使用嵌入在其主体中的独立 SUSE 证书。此外,shim 将允许“注册”其他密钥,覆盖默认的 SUSE 密钥。在以下内容中,我们称它们为“机器所有者密钥”或 MOK 简而言之。
接下来,引导加载程序将验证然后引导内核,内核将对模块执行相同的操作。
要替换特定的内核、驱动程序或其他引导过程的一部分,需要使用机器所有者密钥 (MOK)。 mokutil 工具可以帮助您管理 MOK。
可以使用 mokutil 创建 MOK 注册请求。该请求存储在 UEFI 运行时 (RT) 变量中,称为 MokNew。在下一次引导期间,shim 引导加载程序检测到 MokNew 并加载 MokManager,后者会向您呈现几个选项。您可以使用“从磁盘注册密钥”和“从磁盘注册哈希”选项将密钥添加到 MokList。使用“注册 MOK”选项将密钥从 MokNew 变量复制。
从磁盘注册密钥通常是在 shim 无法加载 grub2 并回退到加载 MokManager 时完成的。由于 MokNew 尚不存在,因此您有权在 UEFI 分区上找到该密钥。
以下基于 https://en.opensuse.net.cn/openSUSE:UEFI#Booting_a_custom_kernel。
安全启动不会阻止您使用自编译的内核。您必须使用您自己的证书对其进行签名,并使该证书为固件或 MOK 所知。
创建用于签名的自定义 X.509 密钥和证书
openssl req -new -x509 -newkey rsa:2048 -keyout key.asc \ -out cert.pem -nodes -days 666 -subj "/CN=$USER/"
有关创建证书的更多信息,请参阅 https://en.opensuse.net.cn/openSUSE:UEFI_Image_File_Sign_Tools#Create_Your_Own_Certificate。
将密钥和证书打包为 PKCS#12 结构
> openssl pkcs12 -export -inkey key.asc -in cert.pem \
-name kernel_cert -out cert.p12生成用于 pesign 的 NSS 数据库
> certutil -d . -N将包含在 PKCS#12 中的密钥和证书导入 NSS 数据库
> pk12util -d . -i cert.p12
使用 pesign 使用新签名“祝福”内核
> pesign -n . -c kernel_cert -i arch/x86/boot/bzImage \
-o vmlinuz.signed -s列出内核映像上的签名
> pesign -n . -S -i vmlinuz.signed此时,您可以像往常一样将内核安装在 /boot 中。由于内核现在具有自定义签名,因此用于签名的证书需要导入到 UEFI 固件或 MOK 中。
将证书转换为 DER 格式以导入固件或 MOK
> openssl x509 -in cert.pem -outform der -out cert.der将证书复制到 ESP 以方便访问
>sudocp cert.der /boot/efi/
使用 mokutil 自动启动 MOK 列表。
将证书导入 MOK
> mokutil --root-pw --import cert.der该 --root-pw 选项允许直接使用 root 用户。
检查准备注册的证书列表
> mokutil --list-new重新启动系统;shim 应该启动 MokManager。您需要输入 root 密码以确认将证书导入 MOK 列表。
检查新导入的密钥是否已注册
> mokutil --list-enrolled或者,这是手动启动 MOK 的过程
重新启动
在 GRUB 2 菜单中按 'c' 键。
类型
chainloader $efibootdir/MokManager.efi boot
选择 。
导航到 cert.der 文件并按 Enter。
按照说明注册密钥。通常,这应该按“0”然后按“y”以确认。
或者,固件菜单可能提供添加新密钥到签名数据库的方法。
在启用安全启动的情况下,在安装过程中不支持添加非收录驱动程序(即,不随 openSUSE Leap 一起提供的驱动程序)。用于 SolidDriver/PLDP 的签名密钥默认不受信任。
以两种不同的方式可以在启用安全启动的情况下在安装过程中安装第三方驱动程序。在这两种情况下
在安装之前,通过固件/系统管理工具将所需的密钥添加到固件数据库。此选项取决于您使用的特定硬件。有关更多信息,请咨询您的硬件供应商。
使用来自 https://drivers.suse.com/ 或您的硬件供应商的可引导驱动程序 ISO,在首次启动时将所需的密钥注册到 MOK 列表中。
要使用可引导的驱动程序 ISO 将驱动程序密钥注册到 MOK 列表,请按照以下步骤操作
将上述 ISO 映像刻录到空白的 CD/DVD 介质上。
使用新的 CD/DVD 介质启动安装,同时准备好标准安装介质或网络安装服务器的 URL。
如果进行网络安装,请在启动命令行中使用 install= 选项输入网络安装源的 URL。
如果从光盘进行安装,安装程序将首先从驱动程序包启动,然后提示插入产品的第一个安装盘。
将使用包含更新驱动程序的 initrd 进行安装。
有关更多信息,请参阅 https://drivers.suse.com/doc/Usage/Secure_Boot_Certificate.html。
在安全启动模式下启动时,以下特性适用
安装到 UEFI 默认启动加载程序位置,这是一种保持或恢复 EFI 启动条目的机制。
通过 UEFI 重新启动。
当没有遗留 BIOS 可回退时,Xen 管理程序将使用 UEFI 启动。
UEFI IPv6 PXE 启动支持。
UEFI 视频模式支持,内核可以从 UEFI 获取视频模式以使用相同的参数配置 KMS 模式。
支持从 USB 设备进行 UEFI 启动。
自 openSUSE Leap 15.3 以来,安全启动模式下支持 Kexec 和 Kdump。
在安全启动模式下启动时,以下限制适用
为了确保安全启动不易被绕过,在安全启动下运行时,某些内核特性会被禁用。
启动加载程序、内核和内核模块必须经过签名。
休眠(磁盘挂起)被禁用。
即使是 root 用户,也无法访问 /dev/kmem 和 /dev/mem。
即使是 root 用户,也无法访问 I/O 端口。所有 X11 图形驱动程序必须使用内核驱动程序。
无法通过 sysfs 访问 PCI BAR。
ACPI 中的 custom_method 不可用。
asus-wmi 模块的 debugfs 不可用。
参数 acpi_rsdp 对内核没有任何影响。
https://uefi.org — UEFI 主页,您可以在这里找到当前的 UEFI 规范。
Olaf Kirch 和 Vojtěch Pavlík 的博客文章(以上章节很大程度上基于这些文章)
https://en.opensuse.net.cn/openSUSE:UEFI — openSUSE 中的 UEFI。