根据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 检查
有两种基本情况:
- 有人值守启动
- 你可以加密你的
/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
这样,整个系统的完整性就可以通过磁盘加密得到隐式保护/
- 无人值守启动
/boot
在这种情况下你无法加密,所以你有两个选择- 符号
initrd
和内核并强制检查它们:- 您可以创建一个 EFI 二进制文件,其中包含所有内容(内核,,
initrd
)grub.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
钩子自动生成)
- 您可以创建一个 EFI 二进制文件,其中包含所有内容(内核,,
- 如果你不想弄乱签名并且有 TPM
- 您可以保留
initrd
原样/boot
并让任何攻击者对其进行修改,但您将根 fs 绑定到适当的 TPM 寄存器,从而有效地阻止访问(rootfs
如果有人更改了内核参数、任何使用的文件(内核二进制文件、、initrd
)grub.cfg
... - 唯一的缺点是,在
initrd
/kernel 更改后,您必须重新启动,手动解锁磁盘并将 LUKS 上的 TPM 绑定密钥槽重新绑定到新的 PCR 寄存器值,并确保在此重新启动期间没有人更改任何内容/boot
。理想的解决方案是,如果可以计算未来的 TPM 值,这样就不必保持 luks TPM 绑定。解决此问题的项目: https://github.com/grawity/tpm_futurepcr
- 您可以保留
还有一些其他参考资料:
- https://www.scitepress.org/Papers/2021/103139/103139.pdf
- https://bugzilla.redhat.com/show_bug.cgi?id=1854177
- https://wiki.ubuntu.com/UEFI/SecureBoot
- https://help.ubuntu.com/community/Full_Disk_Encryption_Howto_2019
- https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/security_hardening/configuring-automated-unlocking-of-encrypted-volumes-using-policy-based-decryption_security-hardening
- https://jumpcloud.com/blog/how-to-enable-full-disk-encryption-on-an-ubuntu-20-04-desktop
更新: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 可以帮助您(但对脚本则不然)。但您很快就会失去通用系统!