Fedora 计划实现 99% 的软件包可复现构建
By Joe Brockmeier March 31, 2025
确保开源软件可复现的努力已经进行了多年,并逐渐获得了主流 Linux 发行版的认可。例如,Debian 已经致力于可复现构建超过十年;现在它可以构建当前稳定版的可复现官方 live CD。Fedora 启动这项工作的时间较晚,但进展迅速,该项目正在考虑针对 Fedora 43 开发周期(预计 10 月发布)的变更提案,目标是使 99% 的 Fedora 软件包构建可复现。到目前为止,对该提案的反应似乎是积极的,主要集中在如何实现该目标(尽量减少打包者的痛苦),而不是是否尝试。
定义可复现构建
Reproducible Builds 项目定义一个构建是可复现的,如果“给定相同的源代码、构建环境和构建指令,任何一方都可以重新创建所有指定 artifacts 的 bit-by-bit 完全相同的副本”。Zbigniew Jędrzejewski-Szmek 在 2023 年黑客马拉松报告中表示,Fedora 过去没有优先考虑可复现构建,因为 Fedora 对其构建过程的控制比 Debian 和其他发行版更多。因为 Debian 允许维护者在本地系统上生成源代码包,并上传一些本地构建的软件包以分发给用户,他说“对源代码包和二进制包内容的信任度都很低”。(Debian 的构建守护进程从源代码构建 大多数 二进制软件包以分发给用户,但也有例外。)另一方面,Fedora 对软件包的控制要严格得多。
在 Fedora 中,分发给用户的所有软件包都在集中式、强控制的基础设施中构建。所有源 RPM 都是从 "dist-git" 构建的:一个 git 仓库,其中包含构建 "recipe" 和软件包源的加密哈希,因此相对容易验证软件包版本之间的更改、哪些 "inputs" 进入了特定的源软件包,以及在什么环境中构建了二进制软件包。
然而,即使 Fedora 对其软件包的控制更加严格,Jędrzejewski-Szmek 表示,可复现构建的好处之一是帮助检测和缓解对 Fedora 构建器的任何类型的供应链攻击,并允许其他人执行独立的验证,以确认软件包源与 Fedora 交付的二进制文件匹配。值得注意的是,Fedora 在 XZ 后门事件引起人们对供应链攻击的更多关注之前,就已经开始了这项工作。
他承认 Debian 在其可复现构建流程方面更先进,并指出 Fedora 正在设置不同的可复现构建定义。此定义排除了签名和一些元数据,并且仅关注给定 RPM 中打包文件的 payload:
如果给定相同的源代码、构建环境和构建指令以及来自构建 artifacts 的元数据,任何一方都可以重新创建 artifacts 的副本,这些副本除了签名和部分元数据外都是相同的,则认为构建是可复现的。
Fedora 追求不同的可复现构建定义的原因是它_无法_实现原始定义中的 "bit-by-bit" 可复现性。这是因为软件包格式的差异以及 Fedora 构建软件包的方式。RPM 在构建时将软件包签名嵌入到 RPM 中,但 Debian 使用分离签名。RPM 还包括诸如构建时间 (BUILDTIME
) 和构建主机 (BUILDHOST
) 之类的信息,这些信息可能会影响可复现性。曾经有关于允许覆盖这些变量的讨论。然而,普遍的观点是 BUILDHOST
提供的信息很有用,并且不希望覆盖它的包含。但是,内容仍然应该是 "bit-by-bit" 完全相同的,即使该短语没有出现在 Fedora 的定义中。
根据 Jan Zerebecki 的说法,openSUSE 项目也使用 RPM 格式分发软件,它将 BUILDHOST
设置为 "reproducible
"据。实际的构建主机打印在构建日志中,感兴趣的用户可以搜索 openSUSE 的构建日志来查找主机。
可复现之路
对于 BUILDTIME
,openSUSE 将构建时间设置为最新变更日志条目的日期。这是由 SOURCE_DATE_EPOCH
环境变量提供给构建的。这是 Fedora 的可复现构建工作开始的地方,在 Fedora 38 开发周期中进行了一项更改,以将打包文件的修改时间 (mtime) "clamp" 到 SOURCE_DATE_EPOCH
。这确保了 mtime 独立于实际构建的时间。如果由于某种原因,新行为会破坏他们的软件包,则打包者可以选择退出此设置。
在 Fedora 41 开发周期中,该项目实施了 RPM 构建流程的另一项更改,以消除常见的不可复现性来源。该更改使用了 Rust 程序 add-determinism
,该程序尝试标准化二进制文件或源文件中的元数据,以确保一致性。它类似于 Debian 的 strip-nondeterminism
,这是一个 Perl 库,是用于构建 Debian 软件包的 debhelper
工具的一部分。使用 strip-nondeterminism
,debhelper
工具从各种文件和存档格式中删除不确定的信息,例如时间戳和文件系统排序。Fedora 项目选择编写自己的工具,因为不希望将 Perl 拉入每个软件包的构建根目录。
根据新的变更提案,迄今为止对 Fedora 构建基础设施的修改使其能够使 90% 的软件包构建可复现。现在的目标是达到 99% 的软件包构建。看来 Fedora 已经从基础设施变更中获得了尽可能多的好处,而无需单个打包者处理可复现性问题。为了达到 99%,该项目将不得不要求打包者将软件包中的可复现性问题视为 bug。
变更负责人 Jędrzejewski-Szmek、Davide Cavalca 和 Jelle van der Waa 将打包 fedora-repro-build
实用程序,以允许开发人员对在 Koji(Fedora 的构建系统)中构建的软件包进行本地重建,以测试其可复现性。它还需要建立 rebuilderd 的公共实例,这是一个用于提供独立验证的系统,以验证二进制软件包是否可以从源代码复制。它可以扫描软件包存储库的元数据以查找新的或更新的软件包,然后将它们排队以进行重建,并提供一个 API 来查询软件包的可复现性状态。Rebuilderd 还可以选择使用 diffoscope 工具来生成差异报告。Arch Linux 可复现状态页面 提供了一个很好的 rebuilderd 使用示例。
如果获得批准,该提案还将要求更新 Fedora 的打包指南,其中指出软件包应该(至少目前不是 "必须")可复现地构建,并且允许在软件包不可复现时针对它们提交 bug。
除了可复现性的安全优势外,该提案还认为它将导致更高质量的软件包。软件包中不可复现的位通常是 "由代码中的错误或粗心造成的"。例如,架构无关 (noarch) 软件包中对硬件架构的依赖性 "几乎总是不需要的和/或 bug",并且可复现性测试可以发现这些 bug。
该提案承认某些软件包的可复现性存在难以修复的问题。例如,Haskell 软件包目前在被多个线程编译时无法复现,尽管正在修复。使用 Go 生产的软件包具有不可复现的调试数据,因为即使给定相同的输入,GNU Debugger 索引文件 (.gdb_index
) 的大小也可能不同。目前还没有解决该问题的方案。另一个已知的问题是 Linux 内核使用临时密钥进行模块签名。LWN 报道了 Thomas Weißschuh 的一个补丁集,该补丁集可能解决该问题。
反馈
在 Fedora 的 Discourse 论坛上的讨论主题中,Fedora 的基础设施负责人 Kevin Fenzi 询问,"这个 [rebuilderd] 实例将位于何处,谁将维护它?🙂" 他还指出,最好有关于设置 rebuilderd 实例的文档。"否则我喜欢这个想法!" Cavalca 表示,可复现性工作目前正在使用 Meta 赞助的 Amazon Web Services (AWS) 帐户,但 "如果大家更喜欢,我们可以考虑迁移到 Fedora 基础设施"。Fenzi 回复 说,最好继续在 Fedora 基础设施之外运行这项工作,以使其更加独立。"当然,我们可以运行一个,然后其他人可以运行其他实例并进行比较"。
Daniel P. Berrangé 询问 是否可以将 rebuilderd 与 Koji 集成,以便维护者不必学习另一个构建工具。"我对处理另一个提供构建后测试的独立 Web 服务并不太热衷。" Jędrzejewski-Szmek 表示,使用 Koji 执行构建是一个有趣的想法,但 "我们还希望我们的重建尽可能独立",因此仍然希望在 Koji 之外的系统中执行它们。在相同的构建环境中第二次重建软件包意味着 "我们没有测试太多"。
Fedora 基础设施团队成员 Miroslav Suchý 想知道 rebuilderd 是否可以将构建提交到 Fedora 的 Copr 构建系统,而不是在 Fedora 中建立另一个构建系统。这引发了关于 Copr 功能以及它是否能与 rebuilderd 很好地集成的讨论。Jędrzejewski-Szmek 指出,rebuilderd 是一个 "完整的项目,以自己的方式做事",并且尝试教它异步地与外部服务通信可能会很复杂。
将 rebuilderd 工具和报告集成到 Fedora 现有基础设施中一直是讨论中反复出现的主题。Simon de Vlieger 表示,他并不一定要在 Koji 中执行构建,但希望该项目 "与 Fedora 预先存在的工具和事物很好地集成,以便人们真正使用它并按照人们期望的方式执行它的机会最高"。
下一步
该提案的下一步是在宣布该提案至少一周后,向 Fedora Engineering Steering Committee (FESCo) 提交 ticket。在这种情况下,最早应在 3 月 26 日提交。如果 FESCo 批准,负责人可以开始处理该提案,目标是在 10 月 Fedora 43 计划发布时完成。
Fedora 的大多数用户可能尚未注意到 Fedora 中迄今为止的可复现性工作,并且在安装 Fedora 43(或 44、45 等)时不会欣赏到任何差异。然而,鉴于不良行为者不断努力寻找和利用开源项目中的供应链弱点,这是一项有价值的工作。