跳过正文

Secure Boot

··
目录

注意:请谨慎操作,设备有变砖的风险

检查安全启动状态
#

在启动操作系统前,可以进入固件设置进行查看,请注意不要随意更改任何设置。您需要导航到正确的位置。您感兴趣的设置可能被简单地标记为安全启动,您可以将其设置为开启或关闭。

在启动操作系统后,可以使用 systemd-boot 检查安全启动状态:

$ bootctl

实现安全启动
#

安全启动的理想设置需要满足一些条件,否则即使实现了安全启动,不满足理想条件的安全启动可能会削弱安全启动的安全模型。

确定 OpROM 签名
#

此小节目前没有自己编写

https://wiki.archlinux.org/title/Unified_Extensible_Firmware_Interface/Secure_Boot#Determine_OpROM_signature

警告:为避免设备软砖,如果您发现显卡带有已签名的 ROM,请确保在注册您自己的密钥后,安全启动数据库保留必要的颁发者。

备份当前变量
#

安装efitools,然后运行以下命令来备份所有四个主要安全启动变量:

$ for var in PK KEK db dbx ; do efi-readvar -v $var -o old_${var}.esl ; done

如果您在新计算机或主板上执行此命令,则提取的变量很可能是 Microsoft 提供的变量。

将固件设置为 setup mode
#

移除平台密钥后,安全启动将处于设置模式。要将固件置于设置模式,请进入固件设置实用程序,并找到删除或清除证书的选项(只用删除 PK 即可)。

使用 sbctl 进行辅助处理
#

注意: sbctl 并非适用于所有硬件。其工作效果取决于硬件制造商。

请安装sbctl

创建和注册密钥
#

将固件设置为 setup mode 后,重新登陆,检查安全启动状态:

$ sbctl status

您应该看到 sbctl 未安装并且安全启动已被禁用。

然后创建您的自定义安全启动密钥:

# sbctl create-keys

将 Microsoft 的密钥和您的密钥注册到 UEFI:

# sbctl enroll-keys -m

警告:启用安全启动后,某些固件会使用 Microsoft 密钥进行签名和验证。不验证设备可能会导致设备崩溃。要注册您的密钥而不注册 Microsoft 密钥,请运行:sbctl enroll-keys。请仅在您了解操作方法的情况下执行此操作。

Note:例如,对于某些 PC(例如搭载 Framework 操作系统的笔记本电脑),如果您希望保留升级固件和运行 OEM 提供的其他启动应用程序的功能,建议同时包含 OEM 固件的内置证书。在这种情况下,请运行以下命令:sbctl enroll-keys -m -f

再次检查安全启动状态:

$ sbctl status

sbctl 现在应该已经安装好了,但是只有在使用您刚刚创建的密钥对启动文件进行签名后,安全启动才会起作用。

签名
#

检查需要签名哪些文件才能使安全启动正常工作:

# sbctl verify

现在对所有未签名的文件进行签名。通常内核和引导加载程序都需要签名。例如:

# sbctl sign -s /boot/vmlinuz-linux 
# sbctl sign -s /boot/EFI/BOOT/BOOTX64.EFI

需要签名的文件取决于您的系统布局、内核和引导加载程序。

提示:尤其是在 Windows 双启动的情况下,可能需要签名的文件数量可能很多。使用 sbctl 签名所有需要的文件的过程可以通过sed完成:

# sbctl verify | sed -E 's|^.* (/.+) is not signed$|sbctl sign -s "\1"|e'

现在您已经完成了!重启系统,并在固件设置中重新启用安全启动。如果引导加载程序和操作系统能够正常加载,安全启动应该就可以正常工作了。检查方法如下:

$ sbctl status

使用 pacman hook 自动签名
#

sbctl 带有一个pacman 钩子,每当 Linux 内核、systemd 或引导加载程序更新时,它都会自动签署所有新文件。

sbctl 其他命令
#

# sbctl reset

重置平台密钥。这将使计算机退出安全启动模式并允许密钥轮换。

# sbctl rotate-keys

轮换安全启动密钥并将其替换为新生成的密钥。将旧密钥保存到 /var/tmp 目录中,并从文件数据库中重新签名所有文件。

# sbctl setup --print-config

打印 sbctl 当前配置。

# sbctl list-files

列出所有已注册的 EFI 二进制文件。

# sbctl remove-file <FILE>

从签名数据库中删除该文件。

# sbctl sign-all

对所有注册的 EFI 二进制文件进行签名。

systemd-boot
#

如果您使用 systemd-boot 和 systemd-boot-update.service,则引导加载程序仅在重启后更新,因此 sbctl pacman 钩子不会对新文件进行签名。作为一种解决方法,可以直接在 /usr/lib/ 中对引导加载程序进行签名,因为 bootctl installbootctl update 会自动识别 .efi.signed 文件并将其复制到ESP分区(如果存在),而不是普通的 .efi 文件。

# sbctl sign -s -o /usr/lib/systemd/boot/efi/systemd-bootx64.efi.signed /usr/lib/systemd/boot/efi/systemd-bootx64.efi

之后重新安装 systemd-boot 以签名:

# bootctl remove
# bootctl cleanup
# bootctl install

然后重新配置 systemd-boot。

fwupd
#

使用 fwupd 更新固件后,安装固件会失败,根据错误信息使用以下类似命令签名:

# sbctl sign -s -o /usr/lib/fwupd/efi/fwupdx64.efi.signed /usr/lib/fwupd/efi/fwupdx64.efi

另外,必须在 /etc/fwupd/fwupd.conf 设置 DisableShimForSecureBoot ,然后重新启动。

/etc/fwupd/fwupd.conf
...

[uefi_capsule]
DisableShimForSecureBoot=true

Fwupd#Using_your_own_keys

保护安全启动
#

  • 使用密码保护固件设置
  • 考虑启用内核锁定模式:添加 lockdown=integrity 内核参数

注意

  1. 内核锁定会禁用休眠
  2. 启用内核锁定后,某些依赖于底层硬件或内核访问权限的应用程序可能无法正常工作

使用自定义密钥对官方 ISO 文件进行签名
#

可以使用 libisoburnmtools 解压和重新打包官方安装镜像。这样,您就可以创建一个支持安全启动的镜像。

再此之前,安装 libisoburnmtools 包。

下载 ISO 文件和对应的 ISO PGP 签名,并验证:

$ pacman-key -v archlinux-version-x86_64.iso.sig

要为官方 ISO 添加使用自定义密钥的安全启动支持,只需提取引导加载程序( BOOTx64.EFI 和 BOOTIA32.EFI )、内核、UEFI shell,对它们进行签名,然后使用签名后的文件重新打包 ISO 即可。请按照以下步骤操作:

首先提取相关文件和 El Torito 启动镜像:

$ osirrox -indev archlinux-YYYY.MM.DD-x86_64.iso \
	-extract_boot_images ./ \
	-cpx /arch/boot/x86_64/vmlinuz-linux \
	/EFI/BOOT/BOOTx64.EFI \
	/EFI/BOOT/BOOTIA32.EFI \
	/shellx64.efi \
	/shellia32.efi ./

iso 文件名需要替换

mkarchiso 使用的 xorrisofs-rational-rock 选项会将 ISO 9660 格式的文件设置为只读,并且在解压后仍然保持只读状态。请将文件设置为可写,以便可以对其进行修改:

$ chmod +w BOOTx64.EFI BOOTIA32.EFI shellx64.efi shellia32.efi vmlinuz-linux

签名这些文件,我们使用 sbctl 进行签名:

# sbctl sign BOOTx64.EFI
# sbctl sign BOOTIA32.EFI
# sbctl sign shellx64.efi
# sbctl sign shellia32.efi
# sbctl sign vmlinuz-linux

将已签名的 EFI 二进制文件复制到指定位置 eltorito_img2_uefi.img。它将用作 EFI 系统分区,并被列为 El Torito UEFI 启动映像。该分区的大小是固定的,但 mkarchiso 添加了 8 MiB 的可用空间(用于舍入/对齐、预留扇区等),因此签名带来的空间增加应该不会造成问题:

$ mcopy -D oO -i eltorito_img2_uefi.img vmlinuz-linux ::/arch/boot/x86_64/vmlinuz-linux
$ mcopy -D oO -i eltorito_img2_uefi.img BOOTx64.EFI BOOTIA32.EFI ::/EFI/BOOT/
$ mcopy -D oO -i eltorito_img2_uefi.img shellx64.efi shellia32.efi ::/

使用修改后的 El Torito UEFI 启动映像重新打包 ISO,并将已签名的 EFI 二进制文件添加到 ISO 9660 中:

$ xorriso -indev archlinux-YYYY.MM.DD-x86_64.iso \
	-outdev archlinux-YYYY.MM.DD-x86_64-Secure_Boot.iso \
	-map vmlinuz-linux /arch/boot/x86_64/vmlinuz-linux \
	-map_l ./ /EFI/BOOT/ BOOTx64.EFI BOOTIA32.EFI -- \
	-map_l ./ / shellx64.efi shellia32.efi -- \
	-boot_image any replay \
	-append_partition 2 0xef eltorito_img2_uefi.img

iso 文件名需要替换

启动生成的 archlinux-YYYY.MM.DD-x86_64-Secure_Boot.iso

作者
南风
夕阳…真美…