安全启动:initramfs 验证

安全启动:initramfs 验证

根据https://wiki.ubuntu.com/UEFI/SecureBoot Initrd 映像未经验证。这些信息是最新的吗?这将使整个安全启动完全无用,因为攻击者可以很容易地用记录 LUKS 密码并将其发送给他的 initramfs 替换它……这反过来会使所有模块签名变得麻烦,并且在安全启动时禁用休眠模式太荒谬了。

如果确实如此,是否存在任何启动板错误/功能请求,我们可以对其进行投票,以使安全启动真正安全?

另一方面,如果这个说法已经过时,那么验证工作如何进行?在安装新内核期间生成 initrd 文件时,用于对其进行签名的密钥对在哪里?哪个组件稍后会验证签名?(shim、MOK、GRUB、内核本身?)……或者也许以某种方式使用 PCR 和 TPM?
……内核命令行怎么样?这个也必须经过签名/验证才能确保启动安全……

答案1

根据我目前对 Ubuntu 20.04 的理解:

  • shim 由 Microsoft 的密钥签名,并包含一个 Canonical 密钥。Microsoft 的密钥在 EFI 中预装,用于验证 shim
  • grub 由 Canonical 的密钥签名,并由 shim 检查
  • 内核由 Canonical 的密钥签名,并由 grub 检查

有两种基本情况:

  1. 有人值守启动
  • 你可以加密你的/boot分区(仅限 LUKS1,Ubuntu 20.04 不支持 LUKS2。较新的 Grub 将支持 LUKS2,但有一些限制(https://git.savannah.gnu.org/cgit/grub.git/tree/docs/grub.texi#n4554/))或有一个带有和的单个系统分区/boot(LUKS1)
  • Grub 将要求输入密码来解锁并读取内核,initrd然后
    • 注意:众所周知,grub2 解密 /boot 的速度很慢(10-20 秒):我找不到 grub 团队对此问题的官方确认,但关于此事有很多讨论,并提供解决方法:根本不使用加密启动或在 luks 标头的第一个插槽中使用迭代次数较低的密钥(即:https://bbs.archlinux.org/viewtopic.php?id=228865
  • /boot这样,整个系统的完整性就可以通过磁盘加密得到隐式保护/
  1. 无人值守启动
  • /boot在这种情况下你无法加密,所以你有两个选择
  • 符号initrd和内核并强制检查它们:
    • 您可以创建一个 EFI 二进制文件,其中包含所有内容(内核,,initrdgrub.cfg,使用自定义密钥进行签名,然后将此密钥添加到 EFI 密钥存储区
    • 或者做同样的事情,但不是把所有东西都放进 Grub EFI 二进制文件中,而是只在那里添加一个 GPG 公钥,这是你用来签署grub.cfg、内核和initrd( 的密钥。https://ruderich.org/simon/notes/secure-boot-with-grub-and-signed-linux-and-initrd
    • initrd无论哪种情况,每次更新时你都必须生成签名甚至 EFI 二进制文件(最好通过initramfs-tools钩子自动生成)
  • 如果你不想弄乱签名并且有 TPM
    • 您可以保留initrd原样/boot并让任何攻击者对其进行修改,但您将根 fs 绑定到适当的 TPM 寄存器,从而有效地阻止访问(rootfs如果有人更改了内核参数、任何使用的文件(内核二进制文件、、initrdgrub.cfg...
    • 唯一的缺点是,在initrd/kernel 更改后,您必须重新启动,手动解锁磁盘并将 LUKS 上的 TPM 绑定密钥槽重新绑定到新的 PCR 寄存器值,并确保在此重新启动期间没有人更改任何内容/boot。理想的解决方案是,如果可以计算未来的 TPM 值,这样就不必保持 luks TPM 绑定。解决此问题的项目: https://github.com/grawity/tpm_futurepcr

还有一些其他参考资料:

更新:2022-11-07:添加了有关 grub2 限制的一些来源和详细信息

答案2

你甚至不需要签署/验证初始化内存文件系统,因为你不需要保持它可访问(本地磁盘上未加密)。

Ubuntu20.04完全能够处理 initrd 文件包含在加密容器内的安装布局(目前适用于卢克斯1在 AMD64 和 ARM64 上,卢克斯2以及未来版本中的更多平台)。除了降级到具有相同内核的最早版本外,除了您自己之外,没有人可以修改用您的密码封装的 initrd。

当前自动化中真正缺少的部分是生成签名的 grub 二进制文件来验证其自身配置。它也可以开箱即用 - grub验证 gpg 样式的签名 - 但内核安装脚本由典范不要以通常的全自动方式进行设置/更新。

如果您想在当前的 Ubuntu 版本中配置一个完全验证的启动链,您可以尝试将您自己的脚本(它gpg --sign是您的配置,然后使用它将其集成到 grub 二进制文件中,grub-mkstandalone然后sbsign在将其放入之前先将该二进制文件/boot/efi)放入,/etc/kernel/postinst.d/以便在您安装/删除内核(版本)时自动调用它。

请注意,几乎没有消费类 PC 实际上用于注册安全启动的自定义密钥(莫克),因此您可能会遇到一些固件错误。您也不会发现太多有关此主题的错误报告,因为很少有人想要/做如此复杂且容易出错的事情。

这只是 Ubuntu 的一面。你可能会赢没有什么在安全方面(但你欢迎投稿)。

答案3

您可能需要首先定义一个威胁模型:您要防范什么?

安全启动甚至应能防止 root 用户破坏以内核级权限运行的代码的完整性。这在启动时最为明显:即使是 root 也不应该能够安装不可信的内核或引导加载程序,我们使用签名来确定可信度。但是,它还扩展到正在运行的内核:Ubuntu 内核将在启动初期检测安全启动并进入锁定完整性模式。完整性模式尝试在运行时维护 root 和内核之间的安全边界。(这会阻止您执行kexec从受信任内核到不受信任内核之类的操作。)

安全启动任务中从未包含的一项任务是防止 root 替换非内核二进制文件。这是一个相当困难的问题,而脚本语言则使它变得更加困难。在 FOSS 世界中,这个问题更加棘手,因为人们对于他们认为限制软件自由的任何事情都会感到非常愤怒,即使可以禁用。(例如,看看 Apple 对几乎所有东西的签名!)

确实有方法可以限制 root 安装恶意二进制文件。您可以使用 grub 的分离签名支持来要求对 initrd 进行签名。但这样一来,所有内容,甚至grub.cfg,都必须签名,管理起来会非常烦人。您可以使用类似 的东西dm-verity。IMA 可以帮助您(但对脚本则不然)。但您很快就会失去通用系统!

相关内容