没有 crates.io 的 Rust
Rust 对集中式 crates.io registry 的依赖被质疑为单点故障和软件供应链中的薄弱环节,这也引发了与依赖 Linux 发行版包管理器(如 Debian)的 C/C++ 生态的比较。评论者权衡了发行版维护的包(更慢、更受控、与操作系统绑定)与语言原生管理器如 Cargo(更快、跨平台、依赖更多)之间的取舍,并围绕安全性、可复现性和开发者体验展开讨论。文中还提到了私有镜像、vendoring、Nix/Guix 风格环境以及基于能力的安全模型等替代方案,但对于用发行版打包来取代 crates.io 是否会带来整体改进,几乎没有共识。
韧性与单点故障
- 许多人认同 crates.io 是一个中心化依赖和理论上的单点故障,但也指出已有缓解措施:
cargo vendor可将所有依赖供应到仓库中。- 本地或内网代理/镜像(Artifactory、Nexus、Azure Artifacts、panamax)在企业中被广泛使用。
- 有人说镜像整个 registry(约 1 TB)很容易,并能让你不依赖 crates.io;也有人指出真正这样做的人并不多。
- 支持 Git URL、替代 registry 和离线构建,但这些方式被认为比主 registry 更慢或更笨重。
- 有人提到 Go 的 GOPROXY 模型很不错:中心化代理,但没有硬性的中心依赖。
锁文件与更新行为
- 锁文件会显著减慢“新版本 → 生产”的路径,而且它们本来就已经是事实上的中间环节。
- 说明:
- 对仓库中的普通
cargo build/run,会遵守Cargo.lock。 - 从 crates.io 执行
cargo install时会忽略锁文件,除非使用--locked。
- 对仓库中的普通
--locked、--frozen和--offline等标志可用于更严格的控制。- 有人强调,在添加新依赖或在未仔细审查的情况下运行
cargo update时,仍然存在残余风险。
Debian/系统打包 vs crates.io
- 提议:依赖 Debian(以及其他发行版)来打包 Rust 库,将它们视为 C/C++ 共享库。
- 支持者认为:发行版维护者和安全团队会提供额外审查,更慢的更新速度充当安全缓冲,共享库能将补丁集中化。
- 批评者:
- 横跨数十个发行版 + macOS/Windows 的碎片化不可扩展,会给库作者带来负担。
- 发行版包常常过时、缺失,或者使用不兼容的选项构建;这推动了 Docker、Nix 和 vendoring 的使用。
- Debian 的审查范围有限,也没能阻止 log4j 之类的事件;安全收益更像是“感觉上有效”,而不是经验证明。
开发者体验:Rust vs C/C++
- 许多人将 C/C++ 的依赖管理和跨发行版构建描述为“噩梦”;Rust + Cargo 在各种操作系统上“开箱即用”,甚至多年后仍然如此。
- 也有人表示与发行版和共享库打交道的体验尚可,尤其是在只面向单个平台并使用现代构建系统(Meson、pkg-config)时。
- 关于许多小 crate 与少数大型库的争论:
- 支持小 crate:更好的复用、组合性,以及工具能够让依赖深度更易管理。
- 支持大库:更容易审计、治理和管理 SBOM;减少“微型依赖”蔓延。
供应链安全思路
- 工具:带漏洞防火墙的私有代理、Packj 之类的扫描器(静态/动态/元数据分析)以及 CI 检查经常被提及,但也被承认为只能尽力而为。
- 根本限制:图灵完备、未沙箱化的代码意味着扫描器无法保证安全。
- 对基于能力或沙箱化模型有很大兴趣(受 WASM/WASI、操作系统降权启发),在这种模型中,库除了显式授予的能力之外,不能接触文件系统/网络。
- 普遍共识是:单靠 crates.io 或发行版都无法“解决”供应链风险;真正的缓解需要更好的工具、审查,以及可能的新语言/运行时模型。