Lanzaboote – NixOS 安全启动
摘要
本文介绍了 Lanzaboote,这是一个用 Rust 编写的 UEFI UKI 存根,可为 NixOS 提供安全启动支持。它将签名检查推迟到 UEFI 阶段执行,同时保持内核和 initrd 与 UKI 二进制文件分离,从而解决了 NixOS 特有的启动挑战。
暂无内容
查看缓存全文
缓存时间: 2026/05/13 00:24
# Lanzaboote:为 NixOS 实现安全启动
来源: https://x86.lol/generic/2022/11/26/lanzaboote.html
安全启动(Secure Boot,https://en.wikipedia.org/wiki/UEFI#Secure_Boot)可以保护系统免受攻击者破坏启动流程的影响。例如,如果没有安全启动,替换读取磁盘加密密码的代码并将其存储在攻击者稍后可窃取的位置是轻而易举的事。因此,理想情况下应启用安全启动,以限制在系统上运行的代码仅为预期运行的代码。
不幸的是,NixOS(https://nixos.org/)——我日常使用的 Linux 发行版——并不支持安全启动。必须得做点什么。在一个小岛上。🌴
在参加 Ocean Sprint(https://oceansprint.org/)——一个专注于 Nix 的黑客松时,我选择与 nikstur(https://github.com/nikstur)和 raitobezarius(https://github.com/RaitoBezarius)组队,为 NixOS 实现安全启动功能!
这次黑客松是一个与经验丰富的 Nix 老兵交流联系的绝佳机会,而且总体上也非常有趣。非常感谢 zupo 和 Domen 组织的这次活动!
## 基于 systemd-boot 的安全启动
也许先介绍一些背景知识。与其他发行版一样,NixOS 在 UEFI 系统上通过 systemd-boot(https://www.freedesktop.org/wiki/Software/systemd/systemd-boot/)进行引导。为了使安全启动生效,systemd-boot 需要 UKI(https://wiki.archlinux.org/title/Unified_kernel_image)。UKI 是一种旨在将 Linux 内核、命令行参数以及 initrd 封装到 EFI 应用程序中的格式。该 EFI 应用程序随后会被签名。
对于 UKI,启动流程如下所示:
1. UEFI 验证并加载 systemd-boot。
2. systemd-boot 查找 UKI,用户可以选择其中一个进行引导。
3. systemd-boot 加载并启动 UKI。
4. UKI 引导其内部嵌入的 Linux 内核和 initrd。
安全启动的信任链由 UEFI 维护。所有组件都使用 `LoadImage`(https://uefi.org/specs/UEFI/2.10/07_Services_Boot_Services.html#efi-boot-services-loadimage)来加载文件,`LoadImage` 会验证嵌入的签名。
这是一种优雅的设计,避免了在引导加载程序中重复实现加密逻辑,将所有工作都委托给 UEFI。
## NixOS 特有的问题与解决方案
NixOS 用户倾向于保留许多系统世代(https://nixos.wiki/wiki/Overview_of_the_NixOS_Linux_distribution#Generations)。每个世代都需要有一个引导加载程序条目。在上述“传统”的 UKI 流程中,这意味着每个世代都需要一个庞大的 UKI 二进制文件,其中包括内核和 initrd,即使它们可能根本没有变化。你的 ESP(https://en.wikipedia.org/wiki/EFI_system_partition)会迅速被填满。
对于 NixOS,我们希望保留将 Linux 内核和 initrd 与 UKI 分开存储的能力。这意味着我们需要开发自己的桩代码(stub)。
## Lanzaboote:面向 NixOS 的 EFI UKI 桩代码
为了解决上述问题,我们开发了一个小型 UEFI 应用程序(lanzaboote),它符合 UKI 规范,但*不*将内核和 initrd 嵌入 UKI 本身。相反,我们仅嵌入路径名称,并将签名检查推迟给 UEFI 通过 `LoadImage` 处理。
Lanzaboote 使用 Rust 开发。由于 `x86_64-unknown-uefi` 目标现在已成为 Tier 2(https://www.phoronix.com/news/Rust-UEFI-Promoted-Tier-2),开发环境变得非常友好。不再需要 `build-std`(https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std)。我还想特别提及 rust-osdev/uefi-rs(https://github.com/rust-osdev/uefi-rs)项目。它极大地简化了处理 UEFI 的繁琐工作。
## 集成到 Nixpkgs 中
最大的一块工作是将其全部集成到 NixOS 和 nixpkgs 中。在这方面由 nikstur(https://github.com/nikstur)和 raitobezarius(https://github.com/RaitoBezarius)领导。
我们现在拥有 lanzatool,用于组装 UKI、对二进制文件进行签名以及填充 ESP。我们还有 NixOS 模块,以便在运行 `nixos-rebuild switch` 期间安装所有内容。
当然,我们还有集成测试。👍
## 信任根
到目前为止,我们还没有一种方法能够从笔记本电脑默认信任的(微软)密钥建立信任链。这意味着用户必须生成自己的密钥,这是一个有点令人望而生畏的过程(https://wiki.archlinux.org/title/Unified_Extensible_Firmware_Interface/Secure_Boot#Creating_keys)。这些密钥随后还必须注册到固件中。
我们计划尽可能简化这一过程,但到目前为止尚未实现。
## 参与进来
目前仍处于早期阶段,在将 NixOS 的安全启动功能合并到上游之前,还有很多工作需要完成。当前状态可以通过阅读 lanzaboote README(https://github.com/blitz/lanzaboote)找到。如果你想帮忙,请加入 #nixos-secure-boot:ukvly.org(https://matrix.to/#/#nixos-secure-boot:ukvly.org)。
最后,分享一张 GNOME 设备安全性选项卡的截图:
如果有人知道这个问号是什么意思,请在这个问题(https://github.com/fwupd/fwupd/issues/5284)下评论。
相似文章
在Sailfish X(适用于Sony Xperia的Sailfish OS)上使用Nix
一份关于在适用于Sony Xperia设备的Sailfish OS上安装Nix包管理器的技术指南,涵盖文件系统布局、LVM分区以及F2FS相关注意事项。
securix: 基于 NixOS 的安全操作系统。提供具有强隔离性、可重现性和策略驱动配置的强化环境
Sécurix 是一个基于 NixOS 的安全操作系统,由法国数字部门 (DINUM) 开发,用于强化环境,具有强隔离性、可重现性和策略驱动配置,目前处于 alpha 阶段。
Guix Nix 的怪异融合:在 Nix 中利用 Guix 派生
一项技术探索,展示了 Nix 如何构建 Guix 派生项,强调了共享底层“输入输出机”架构以及跨生态系统互操作的可能性。
安全启动和CA证书轮换——给发行版的提醒
本文提醒Linux发行版注意微软用于安全启动的UEFI CA证书即将到期,介绍了新证书以及在缺少旧证书的较新硬件上可能出现的启动问题。
NixOS 与密钥管理
教程介绍 NixOS 的密钥管理选项,比较 sops-nix、agenix 和 ragenix 工具,并提供使用 sops-nix 进行加密密钥管理的实际示例。