11 UEFI(统一可扩展固件接口) #
UEFI(统一可扩展固件接口)是用于系统硬件自带的固件、系统所有的硬件组件以及操作系统之间的接口。
UEFI 在 PC 系统上的应用范围越来越广,因此正在逐渐替代传统的 PC-BIOS。例如,UEFI 能够很好地支持 64 位系统,提供安全的引导(“安全引导”,要求固件为 2.3.1c 或以上版本)。安全引导是其最为重要的特性之一。最后,借助 UEFI,标准固件将能够用于所有 x86 平台。
除此之外,UEFI 还具有以下优点:
从带有 GUID 分区表 (GPT) 的大磁盘(超过 2 TiB)引导。
独立于 CPU 的架构和驱动程序。
带有网络功能的灵活的预操作系统环境。
通过 PC-BIOS 式仿真支持引导老式操作系统的 CSM(兼容支持模块)。
有关详细信息,请参见 http://en.wikipedia.org/wiki/Unified_Extensible_Firmware_Interface。以下小节仅针对部分功能如何在 SUSE Linux Enterprise Server 中实现而列举一些提示,并不代表 UEFI 的整体概述。
11.1 安全引导 #
在 UEFI 领域中,要想保障引导程序的安全,需要建立一个信任链。“平台”是此信任链的根;在 SUSE Linux Enterprise Server 环境中,可将主板和板载固件视为“平台”。换句话说,它就是硬件供应商,信任链从硬件供应商流向组件制造商、OS 供应商等。
系统通过公共密钥加密法表示信任。硬件供应商将所谓的“平台密钥 (PK)”放入固件中,代表可信根。操作系统供应商与其他方将其密钥与“平台密钥”签署在一起,以此记录他们之间的信任关系。
最后,除非这些“可信的”密钥之一(即 OS 引导加载程序、位于一些 PCI Express 卡的闪存上或磁盘上的一些驱动程序,或者更新的固件本身)签署了代码,否则要求固件不得执行该代码,从而建立安全保障。
要使用安全引导,您需要用固件信任的密钥对您的 OS 加载程序签名,并且需要 OS 加载程序校验其加载的内核是否可信。
可以将密钥交换密钥 (KEK) 添加到 UEFI 密钥数据库中。这样,其他证书只要签署了 PK 的私用部分,即可由您使用。
11.1.1 在 SUSE Linux Enterprise Server 上实施 #
默认情况下安装微软的密钥交换密钥 (KEK)。
UEFI/x86_64 安装中默认会启用安全引导功能。您可在
对话框的 选项卡中找到 选项。该选项支持在固件中的安全引导已激活时引导,同时也支持在安全引导已停用时引导。“安全引导”特性要求 GUID 分区表 (GPT) 使用主引导记录 (MBR) 替代旧的分区。如果安装期间 YaST 检测到 EFI 模式,则会设法创建 GPT 分区。UEFI 预期会在 FAT 格式的 EFI 系统分区(ESP) 上查找到 EFI 程序。
支持 UEFI 安全引导基本上要求具有固件认可作为可信密钥的数字签名的引导加载程序。该密钥需要先天为固件所信任(无需任何手动干预)。
有两种办法可以实现。一种是与硬件供应商合作,让其签署 SUSE 密钥,然后 SUSE 会使用该 SUSE 密钥签署引导加载程序;另一种是通过微软的 Windows 徽标认证计划使引导加载程序获得认证,并使微软认可 SUSE 签名密钥(也就是让加载程序使用他们的 KEK 签名)。至此,SUSE 使引导加载程序获得了 UEFI 签名服务(在此情况下为 Microsoft)的签名。
SUSE 在实施层使用默认将会安装的 shim
加载程序。这是一种可以避免法律纠纷的智能解决方案,能够大幅简化认证和签名步骤。shim
加载程序的任务是装载 GRUB 2 等引导加载程序并对其进行校验,之后,此引导加载程序将装载仅由一个 SUSE 密钥签名的内核。SUSE 从全新安装的 SLE11 SP3 开始提供此功能,并要求启用 UEFI 安全引导。
可信用户分为以下两类:
首先是持有密钥的用户。平台密钥 (PK) 几乎允许所有操作。密钥交换密钥 (KEK) 的许可范围与 PK 一致,但不能更改 PK。
其次是能够以物理方式访问机器的任何用户。具有物理访问权限的用户可以重引导机器并对 UEFI 进行配置。
UEFI 提供下列两类变量以满足这些用户的需求:
第一类变量即所谓的“已验证的变量”,它们可从引导过程(所谓的“引导服务环境”)和正在运行的操作系统中更新。仅当对变量新值签名的密钥是用于对变量旧值签名的相同密钥时,才能进行更新。而且,您只能向这类变量追加或将其更改为序列号更高的数值。
第二类变量即所谓的“仅供引导服务使用的变量”。引导进程中运行的任何代码都可以获取这些变量。在结束引导进程并准备启动 OS 的时间间隔内,引导加载程序必须调用
ExitBootServices
呼叫。此后将无法获取这些变量,OS 也无法接触到这些变量。
各类 UEFI 密钥列表属于第一类,因为该类变量除了允许联机更新外,还允许添加密钥、驱动程序、固件指纹以及将其列入黑名单。第二类变量即“仅供引导服务使用的变量”。该类变量有助于以安全且支持开源的方式实施安全引导,因此符合 GPLv3 要求。
SUSE 首先启动 shim
,它是一个小而简单的 EFI 引导加载程序,由 SUSE 和 Microsoft 签名。
这样一来,shim
即可加载并执行。
shim
随后继续验证其想要加载的引导加载程序是否可信。默认情况下,shim
会使用其主体中所嵌入的独立的 SUSE 证书。此外,shim
还允许“登记”其他密钥,用于覆盖默认的 SUSE 密钥。下文将这些密钥称为“机器拥有者密钥”或缩写为 MOK。
接下来,引导加载程序会验证内核,然后加以引导。该内核将在模块上执行同样的操作。
11.1.2 MOK(机器拥有者密钥) #
如果用户(“机器拥有者”)想要更换引导进程的任何组件,则会用到“机器拥有者密钥 (MOK)”。他们可以借助 mokutils
工具对组件签名及管理 MOK。
当加载 shim
时,登记进程便会开始重引导计算机并中断引导进程(例如按下某个键)。shim
随后转入登记模式,允许用户使用引导分区上的文件的密钥替换默认的 SUSE 密钥。如果用户选择这样做,则 shim
将计算该文件的哈希,并将计算结果置入“仅供引导服务”的变量中。这样,shim
可以检测到文件除引导服务之外出现的任何更改,从而避免篡改用户核准的 MOK 列表。
上述各步都在引导时发生,此时仅执行已经校验的代码。因此,只有控制台上所示的一位用户可以使用机器拥有者的一组密钥。它不可能是远程访问 OS 的恶意程序或骇客,因为骇客或恶意程序只能更改文件,但无法更改存储在“仅供引导服务使用”的变量中的哈希。
引导加载程序经 shim
装载并校验后,如果需要校验内核以免校验代码重复,则会回调 shim
。为此,Shim
将使用同一份 MOK 列表并通知引导加载程序能否加载内核。
这样,您就可以安装自己的内核或引导加载程序。您只需要安装一组新的密钥,并在首次重引导期间以物理方式呈现,从而予以授权。由于 MOK 是个列表而不是单个 MOK,因此您可以让 shim
信任来自多个供应商的密钥,以允许从引导加载程序进行双重或多重引导。
11.1.3 引导自定义内核 #
以下内容基于 http://en.opensuse.org/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/"
有关创建证书的详细信息,请参见 http://en.opensuse.org/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 以简化访问:
sudo cp 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
”予以确认。除此之外,固件菜单也可能提供了多种向“签名数据库”中添加新密钥的方式。
11.1.4 使用非内置驱动程序 #
在启用安全引导的情况下,不支持在安装过程中添加非内置驱动程序(即,不是 SUSE Linux Enterprise Server 自带的驱动程序)。用于 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。
11.1.5 功能和限制 #
以安全引导模式引导时,可以使用以下功能:
安装到 UEFI 默认的引导加载程序位置,这是为了保留或恢复 EFI 引导项而采用的机制。
通过 UEFI 重引导。
如果没有其他可回退到的旧版 BIOS,Xen 超级管理程序将使用 UEFI 引导。
支持 UEFI IPv6 PXE 引导。
支持 UEFI 视频模式,内核可以从 UEFI 检索视频模式,以使用相同的参数配置 KMS 模式。
UEFI 支持从 USB 设备引导。
以安全引导模式引导时,存在以下限制:
为确保他人无法轻易绕过安全引导,系统在安全引导下运行时会禁用部分内核特性。
引导加载程序、内核以及内核模块必须经过签名。
Kexec 和 Kdump 处于禁用状态。
休眠(挂起到磁盘)处于禁用状态。
无法访问
/dev/kmem
和/dev/mem
,连 root 用户也不例外。无法访问 I/O 端口,连 root 用户也不例外。所有 X11 图形驱动程序必须使用内核驱动程序。
无法通过 sysfs 访问 PCI BAR。
无法使用 ACPI 中的
custom_method
。无法使用 asus-wmi 模块的 debugfs。
acpi_rsdp
参数对内核没有任何影响。
11.2 更多信息 #
http://www.uefi.org — UEFI 主页,其中列出了最新的 UEFI 规范。
由 Olaf Kirch 与 Vojtěch Pavlík 撰写的博文(上述章节内容主要取材于这些博文):
http://en.opensuse.org/openSUSE:UEFI — UEFI 与 openSUSE。