menu Web-Worker Todo 归档 留言 朋友 致谢 关于我 隐私权
如何安全启动 Arch Linux
作者 | 浏览量 2725
请注意,本文编写于 99 天前,最后修改于 56 天前,其中某些信息可能已经过时。

前言

安全启动是可以保护你的引导程序不受篡改的一项技术。它的原理是给引导程序签名,让你的计算机信任这个签名,并仅允许启动有可信签名的引导程序。一旦有人恶意往引导程序注入些东西时,由于签名被破坏,计算机就出于安全目的停止启动了。

阅读提醒

  • 安全启动需要您的主板支持 UEFI
  • 安全启动在您启用了全盘加密后才有实际意义。
  • 安全启动适用于 ESP 分区所在的硬盘有被通过物理接触而被篡改的场景。
  • 在 Arch Linux 启用安全启动时,您需要有一颗热爱折腾,不怕困难的心。

实现安全启动的几种方法(理论+原理)

  • 使用你自己的密钥(需主板支持)
  • 使用由微软签名的预引导程序,然后由这个预引导程序来信任你的引导程序/内核,并完成安全启动。

首先,“使用你自己的密钥” 这种方法是将证书写到主板里,就和主板预装的微软证书一样,预装你的证书。缺点是只有新主板支持这个特性。

然后 “使用由微软签名的预引导程序” 这种方法是先安全启动一个由微软签名过的预引导程序再由这个预引导程序引导经过签名验证或哈希校验的引导程序。

目前在 Linux,有两个 “使用由微软签名的预引导程序” 可以使用。一个是 Preload,另一个是 shim。这俩个预引导程序的区别是该如何信任下一环的引导程序。Preload 和 shim 都可以分别通过哈希校验信任不同的引导程序/内核(通过哈希校验实现防篡改),但这样做的坏处是每次更新引导程序/内核时,都需要重新向 efivar 写入哈希校验。

shim 可以信任一个公钥证书(在信任公钥证书时 shim 会向 efivar 写入 MOK),这样所有被这个私钥证书签名过的引导程序/内核也就获得了信任,并可以安全启动它们了。这样做的好处是每次更新引导程序/内核时,你只需要重新签名引导程序/内核即可。无需再向 efivar 写入些什么。你可以通过包管理器的钩子实现在每次更新引导程序/内核时自动签名它们。

我个人推荐使用 shim 实现安全启动,这样在更换设备后可以很方便的再次启用安全启动(只需要导入公钥证书就好)。

我为什么不推荐使用 “使用你自己的密钥” 这种方法呢?
  • 这可能会有兼容性问题,部分主板的安全启动不支持使用你自己的密钥。
  • 通过 “使用你自己的密钥” 来实现安全启动配置较为复杂。详见 Arch Wiki Using_your_own_keys. 本文在此处不做过多介绍。
我为什么不推荐使用 Preload 这种方法呢?
  • Preload 更新引导程序/内核后需要重新向 efivar 写入哈希校验。这可能会损害固件。

在 Arch Linux 上启用安全启动(教程)

  • 确保你的电脑支持 UEFI 安全启动,并已经使用 UEFI 启动系统。
  • 在配置完成之前,请确保你的安全启动是处于关闭状态,以保证可以正常进入系统配置安全启动。

在开始之前,请先确保你使用的是 root 并处于 /etc/efi-keys/ 文件夹中

# 通过 root 密码提权到 root
su
# 通过 sudo 提权到 root
sudo su
# 通过 pkexec 提权到 root
pkexec

# 前往 /etc/efi-keys/ 目录
cd /etc/efi-keys/

创建一对证书,用来签名并信任引导程序/内核。

openssl req -new -x509 -sha256 -newkey rsa:4096 -nodes -days 28565 -subj "/CN=Machine Owner Key/" -keyout /etc/efi-keys/MOK.key  -out /etc/efi-keys/MOK.crt
openssl x509 -outform DER -in /etc/efi-keys/MOK.crt -out /etc/efi-keys/MOK.cer

安装 shim 到你的 esp 分区。

# 温馨提示:开头带有 # 的为注释行,可不复制。复制了也不影响。
# 请把下行的 /boot 改为你实际 esp 分区所挂载的路径。
ESP=/boot
# 由于 shim 只会引导 grubx64.efi,所以在此处把你的引导程序改名为 grubx64.efi。
sudo mv ${ESP}/EFI/BOOT/BOOTX64.EFI ${ESP}/EFI/BOOT/grubx64.efi
# 使用 shim 预引导程序作为你 UEFI 启动项的默认引导程序。
sudo cp /usr/share/shim-signed/shimx64.efi ${ESP}/EFI/BOOT/BOOTx64.EFI
sudo cp /usr/share/shim-signed/mmx64.efi ${ESP}/EFI/BOOT/

签名你的引导程序以及内核

# 温馨提示:请在你证书所在目录执行此命令,否则可能会找不到证书。
# 温馨提示2:请检查你是否使用 linux 内核,如果你用的是其他内核请更改下行命令的 vmlinuz-linux
# 修改示例:使用 linux-zen 内核,将下文的两处 /boot/vmlinuz-linux 修改为 /boot/vmlinuz-linux-zen
sudo sbsign --key /etc/efi-keys/MOK.key --cert /etc/efi-keys/MOK.crt --output /boot/vmlinuz-linux /boot/vmlinuz-linux
sudo sbsign --key /etc/efi-keys/MOK.key --cert /etc/efi-keys/MOK.crt --output ${ESP}/EFI/BOOT/grubx64.efi ${ESP}/EFI/BOOT/grubx64.efi

将公钥证书临时放到 ESP 分区里面。

因为一会要去 shim 导入公钥证书,所以就临时放 ESP 分区了。

sudo cp /etc/efi-keys/MOK.cer ${ESP}/

重启并启用安全启动

# 可以通过下行命令快速重启到固件设置。
systemctl reboot --firmware

导入并信任证书

此时,你在启动后就可以选择导入证书了,在导入完成并重启后,此时你就可以安全启动你的 Arch Linux了。

使用 pacman hook 实现更新引导程序或内核时自动重新签名

在更新引导程序时自动重新签名

# 此配置文件仅供 system-boot 参考,其他引导程序请谨慎操作!
sudo mkdir /etc/pacman.d/hooks/
sudoedit /etc/pacman.d/hooks/90-systemd-boot.hook
[Trigger]
Type = Package
Operation = Upgrade
Target = systemd

[Action]
Description = Updating systemd-boot
When = PostTransaction
Exec = /usr/bin/sh -c '/usr/bin/bootctl update; /usr/bin/cp /boot/EFI/systemd/systemd-bootx64.efi /boot/EFI/BOOT/grubx64.efi; /usr/bin/sbsign --key /etc/efi-keys/MOK.key --cert /etc/efi-keys/MOK.crt --output /boot/EFI/BOOT/grubx64.efi /boot/EFI/BOOT/grubx64.efi; /usr/bin/sbsign --key /etc/efi-keys/MOK.key --cert /etc/efi-keys/MOK.crt --output /boot/EFI/systemd/systemd-bootx64.efi /boot/EFI/systemd/systemd-bootx64.efi;'

在更新内核时自动重新签名

# 如果你在上面那步创建了文件夹则不用执行下面注释掉的这行代码,
# 如果你是跳着看的,你可能需要创建这个文件夹。
# sudo mkdir /etc/pacman.d/hooks/
sudoedit /etc/pacman.d/hooks/99-secureboot.hook

如果你的内核没有被下列 Target 列出来的话,那么您需要手动把您内核的包名按照此格式手动修正补全一下。

[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = linux
Target = linux-lts
Target = linux-hardened
Target = linux-zen

[Action]
Description = Signing Kernel for SecureBoot
When = PostTransaction
Exec = /usr/bin/find /boot/ -maxdepth 1 -name 'vmlinuz-*' -exec /usr/bin/sh -c 'if ! /usr/bin/sbverify --list {} 2>/dev/null | /usr/bin/grep -q "signature certificates"; then /usr/bin/sbsign --key /etc/efi-keys/MOK.key --cert /etc/efi-keys/MOK.crt --output {} {}; fi' ;
Depends = sbsigntools
Depends = findutils
Depends = grep

参考资料:
Unified Extensible Firmware Interface/Secure Boot

版权所属Web-Worker
本文作者
本文链接https://web-worker.cn/Tutorial/how-to-secure-boot-arch.html
版权声明CC BY-NC-SA 4.0
添加新评论
您没有输入昵称,昵称不能是空哦~
您的邮箱地址格式不正确哦~
您没有输入网址,网址不能是空哦~
您没有输入评论,评论不能是空哦~
已有 2 条评论
    正在热修复.jpg

    失踪了大半年总算想起来更博了

    access_time 2021-10-17 22:29
      正在热修复.jpg

      失踪人口回归计划.jpg

      access_time 2021-10-17 22:33