二进制文件之下

  • BTCStudy
  • 发布于 18小时前
  • 阅读 26

文章深入探讨了 Bitcoin Core 开发体系中“别信任,去验证”的核心哲学。通过详细介绍可复现编译(使用 Guix)、减少第三方依赖、拒绝自动更新以及持续集成的安全性原则,展示了比特币如何从软件构建层面确保其去中心化和透明性,以抵御供应链攻击并保障用户自主权。

作者:Mike Schmidt

来源: https://bitcoinmagazine.com/print/the-core-issue-beneath-the-binary-verifying-trust

大部分人下载 Bitcoin Core 软件的时候, 他们跟这套开发体系(build system)的交互只在几次点击之间。他们会下载软件的可执行的二进制文件(executable binary)、验证一个签名(希望如此!),然后开始运行一个比特币节点。人们会看到软件马上就跑起来。但他们不会看到这套开发体系以及开发软件的广泛流程。这个开发体系,就代表了比特币的去中心化、透明性和可验证性的哲学。

在你下载到的二进制文件背后,藏着专门为回答一个简单的问题而设计的持续多年的工程杰作:“ 为什么每个人都可以信任这个软件呢? ” 而回答是:你不该被迫信任它,应该让你可以验证。

在这个软件供应链攻击可以登上全球新闻头条的时代,在受污染的 npm 安装包、埋后门的工具库、流氓 CI(连续集成)服务端之间,Bitcoin Core 的开发体系保持了低调和自律。相比于 “一推代码就部署” 的无摩擦便利性,Bitcoin Core 的方法似乎缓慢而复杂,但这就是重点。安全性并非便利性。

为了理解 Bitcoin Core 的开发体系,我们要理解:

  • Bitcoin Core 的开发体系哲学
  • 可复现编译(reproducible builds)
  • 尽可能减少依赖
  • 不自动升级
  • 连续集成
  • 逐步采用

Bitcoin Core 的开发体系哲学

说起比特币的去中心化,大部分人看到的是矿工、节点和开发者。但去中心化不是只跟协议的参与者有关。比特币的去中心化延伸到了开发和分发软件的做法中。

比特币世界的原则之一是:“别信任,去验证。” 运行你自己的节点是一种验证活动:根据共识规则来验证每一个区块和每一笔交易。但开发体系自身给了你另一个机会去验证,在软件层面验证。比特币是一种无需受信任中间人的货币,Bitcoin Core 则尝试成为一个不需要信任开发者的软件。这套开发体系花了很多力气来保证,任何地方的任何人,都能独立重新创造出跟 bitcoincore.org 网站上挂载的二进制文件一模一样的文件。

这种哲学可以追溯到 Ken Thompson 在 1984 年出版的散文《对依赖于信任的反思(Reflections on Trusting Trust)》,该文警告说,即使一份源代码是清楚无误的,如果将它编程成软件的编译器被污染了,那么其结果软件也是不可信任的。比特币的开发者们将这一教训铭记在心。用 Bitcoin Core 贡献者 Michael Ford (fanquake) 的话来说:

“可复现编译是极为关键的,因为我们软件的用户将不必被迫信任软件里面的东西就是我们说的这样。软件的内容必须永远可以独立验证。”

这段话,既是一种技术目标,也是比特币精神的一部分。

在安全学的世界里,人们常常会讨论 “攻击界面”。Bitcoin Core 的开发体系,就是把软件开发流程自身当成一种攻击界面,从而尽可能缩小它和保护它的。

可复现编译:全流程的验证

生成 Bitcoin Core 发行版的第一步从 GitHub 网站上的开源代码开始。这份代码的每一次变更都是公开的。每一次代码合并请求都会经过审核。但是,从人类可读的 代码, 变成可运行的二进制 软件,需要经过编译器、第三方库和操作系统,每一个环节自身都是篡改、后门乃至故障的潜在界面。

“受信任的第三方即是安全漏洞” —— 尼克·萨博 (Nick Szabo, 2001)

为了解决这些顾虑,Bitcoin Core 项目架设了一个使用 Guix 的开发流水线。Guix 是一个软件包管理器,专门设计用于创建可复现、确定性的软件环境。

当一个新的 Bitcoin Core 发行版获得标签的时候,多位独立的贡献者会使用 Guix 从头编译出新发行版二进制文件。每一个编译者都在一个隔离的环境中工作,并保证使用完全一致的工具链、编译器版本和系统库。如果所有编译者都产生了完全相同的比特输出,我们就知道编译是确定性的了。

然后,贡献者们为得到的二进制文件生成密码学签名,并将这些签名发布在一个独立的 GitHub 库 “guix.sigs” 中,那里列出了对每一个 Bitcoin Core 发行版的签名。一些编译者同时也是 Bitcoin Core 的开发者,但这不是硬性要求,因为这个见证过程是开放给所有人的。事实上,许多非代码贡献者会定期参与、贡献签名。

这个过程就叫 “可复现编译”,就是 Thompson 的 “依赖于信任” 的解药。它意味着,任何人都可以取得公开的源代码、相同的 Guix 环境,然后独立地确认:正式发布的二进制文件与他们自己编译出来的文件是一样的。不过,虽然可复现编译可能验证一个软件是一份源代码的真实表示,这个软件本身的正确性,还是要由透彻的测试和代码审核流程来保证。

绝大部分人永远不会执行一次完整的编译,也不会检查 Guix 配置文件和对比编译哈希值。他们也不需要这样做。这套基础设施的存在,以及维护这套基础设施的人,给了每一个用户产生信心的基础。

放在 bitcoincore.org 上的正式二进制文件,并不仅仅是 “由 Bitcoin Core 维护者们制作” 的。它们是数十个独立编译者的输出的交集。你最终下载到的,也就是其他所有人都编译出来并验证了真实性的。

这就是全流程的验证。

尽可能减少依赖:少信任一些东西

可复现性是等式的一边,另一边是尽可能减少要复现的东西。Bitcoin Core 库中的代码,并不是运行 Bitcoin Core 软件时唯一运行的代码。为了加快开发和生产力,Bitcoin Core 也依赖于外部的、第三方生产的代码和库。

过去十年中,Bitcoin Core 开发者们已经稳步地剥离了那些不必要的、有时候会产生问题的第三方依赖,比如 OpenSSL 和 MiniUPnp 。无论是外部的代码库还是开发工具,对它们的依赖总是会增加复杂性,或是引入隐藏的假设。Boost 和 Libevent 这样的项目,一度是 Bitcoin Core 代码的核心,也被逐步淘汰,或替换成了更简单、更自立(self-contained)的其它方案。

为什么呢》因为你继承的每一个依赖项,都是一个潜在的供应链攻击风险点。那就是并非你编写、未经你审核、你也无法完全控制的代码。减少依赖项,让开发体系更轻快、更安全也更容易验证。

最近,Brink 一篇 题为《减少依赖》的博客 中强调了这种努力( 中文译本),并且指出,这不仅仅跟简洁性有关,也是在保护这个项目的安全性和自主性。每移除一个依赖项,就是少一个本项目必须信任的外部参与者,也少一些出现后门的概率。

最终的目标是产生完全静态的二进制文件:包含了所有需要运行的东西,而没有动态的、运行时依赖。这种自立性以为主不依赖于外部库 —— 这些外部库在不通操作系统上可能表现不通。

在绝大部分软件都变得更重、更依赖于中心化的软件包生态系统时, Bitcoin Core 逆向而行:朝向极简和独立。

不自动更新

在当代开发的绝大部分软件中,用户都无权确定使用哪个版本的软件、是否升级软件。你安装一个 app 之后,它会悄悄地、自动地在后台更新自己到最新版本。虽然这很方便,它跟 Bitcoin Core 的哲学是相反的。

Bitcoin Core 从未包含自动升级机制,开发者们也说永远不会。自动升级机制会让权力集中,创造出一个可以推送(可能恶意的)代码到整个网络每一个节点的团体。这无疑就是一种中心化控制权,是比特币最初要规避的东西。通过要求用户手动下载、验证和安装新版本,Bitcoin Core 强化了个人责任意识和可验证的同意机制。

这套开发体系,以及不设自动更新,是同一个原则的两面:只有节点运营者自己能决定自己运行什么软件,并且他们可以验证自己所运行的软件是经过认证的。

连续集成:稳步前进,补足短板

在硅谷,“连续集成” 和 “连续开发”(CI/CD)是 “敏捷软件开发(agile software development)” 的标志。快速发布、抢先迭代,让自动化做完剩下的事。

Bitcoin Core 采用了相反的方法。它的 CI 系统不是为了而加速开发而存在的,而是为了保护完整性。自动化编译会测试跨平台的一致性。Bitcoin Core 的开发体系被设计成尽可能不挑硬件和操作系统。这个项目可以为 Linux、macOS 和 Windows 操作系统编译二进制文件,并且支持多种计算架构,包括 x86_64、aarch64(ARM),甚至 riscv64 。这个连续集成系统通过为每一项变更执行数百个测试来保证兼容性以及软件完整性。

结果是,在这种文化中,“连续集成” 意味着连续测试、验证和安全性,而不是连续创新。

稳步前进,补足短板。

持续适应:我们做到了吗?

这个开发体系也不是一成不变的。开发者们在持续改进它:减少依赖项、优化跨架构编译,并探索完全没有运行时依赖的完全静态编译。

虽然 Bitcoin Core 的开发体系追求确定性,它也无法一成不变。因为它生活于其中的世界在不断改变。操作系统、编译器、库、硬件架构,都在不断改变。每多一种 macOS 或 glibc 版本,每当一种编译器标签被放弃,或者,CPU 的架构每演化一次,都会带来微妙的不兼容性,必须解决。一个开发体系如果原地踏步,假以时日,就会完全失去开发能力。

可复现编译的悖论在于,它需要不断演化以保持可复现性。开发者们必须不断调整,有时候要坚守、要打补丁,有时候要完全替换掉工具链,才能在不断变化的背景中保持确定性。在稳定性和适应性之间保持平衡,也是比特币长期以来的韧性的一部分。

(完)

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
BTCStudy
BTCStudy
https://www.btcstudy.org/