Go 博客

模块镜像和校验和数据库已上线

Katie Hockman
2019年8月29日

我们很高兴地宣布,我们的模块 镜像索引校验和数据库 现已正式上线!go 命令将默认使用模块镜像和校验和数据库,适用于 Go 1.13 模块用户。有关这些服务的隐私信息,请参阅 proxy.golang.org/privacy,有关配置详情(包括如何禁用这些服务器的使用或使用其他服务器)请参阅 go 命令文档。如果您依赖非公开模块,请参阅 关于配置非公开模块环境的文档

本文将介绍这些服务及其使用优势,并总结 Gophercon 2019 大会上的 Go 模块代理:查询的生命周期 演讲中的一些要点。如果您对完整演讲感兴趣,请观看 录像

模块镜像

模块 是版本化的 Go 包集合,每个版本的内容都是不可变的。这种不可变性为缓存和身份验证提供了新的机会。当 go get 以模块模式运行时,它必须获取包含请求包的模块,以及该模块引入的任何新依赖项,并在需要时更新您的 go.modgo.sum 文件。从版本控制系统获取模块可能会因为延迟和系统存储而产生高昂的成本:go 命令可能被迫下载包含传递依赖项的存储库的完整提交历史记录,即使该依赖项未被构建,仅仅是为了解析其版本。

解决方案是使用模块代理,它使用更适合 go 命令需求的 API(请参阅 go help goproxy)。当 go get 以模块模式并结合代理运行时,它将通过仅请求其所需的特定模块元数据或源代码来更快地工作,而无需担心其他部分。下面是一个 go 命令在 go get 中使用代理的示例,通过请求版本列表,然后获取最新标记版本的详细信息、mod 文件和 zip 文件。

模块镜像是特殊的模块代理,它将其元数据和源代码缓存在自己的存储系统中,从而允许镜像继续提供已不再可从原始位置获取的源代码。这可以加快下载速度,并保护您免受依赖项消失的影响。有关更多信息,请参阅 2019 年的 Go 模块

Go 团队维护着一个模块镜像,托管在 proxy.golang.org,从 Go 1.13 开始,go 命令将默认使用它来为模块用户服务。如果您使用的是早期版本的 go 命令,您可以通过在本地环境中设置 GOPROXY=https://proxy.golang.org 来使用此服务。

校验和数据库

模块引入了 go.sum 文件,该文件记录了首次下载每个依赖项时其源代码和 go.mod 文件的 SHA-256 校验和列表。go 命令可以使用这些校验和来检测源服务器或代理提供的代码不匹配的情况,即同一版本返回了不同的代码。

go.sum 文件的一个限制是它完全基于您“第一次使用”时的信任。当您将一个以前从未见过的依赖项版本添加到您的模块中时(可能通过升级现有依赖项),go 命令会获取代码并动态地向 go.sum 文件添加行。问题在于,这些 go.sum 行并未与其他任何人的文件进行比对:它们可能与 go 命令刚刚为其他人生成的 go.sum 行不同,这可能是因为代理故意提供了针对您的恶意代码。

Go 的解决方案是提供一个全局的 go.sum 行源,称为 校验和数据库,它确保 go 命令始终向每个人的 go.sum 文件添加相同的行。每当 go 命令接收到新的源代码时,它都可以将其校验和与此全局数据库进行比对,以确保校验和匹配,从而确保每个人都使用给定版本的相同代码。

校验和数据库由 sum.golang.org 提供服务,并基于由 Trillian 支持的校验和 透明日志(或“Merkle 树”)构建。Merkle 树的主要优点是其防篡改性,并具有不允许错误行为未被检测到的特性,这使其比简单数据库更值得信赖。go 命令使用此树在向您的模块的 go.sum 文件添加新的 go.sum 行之前,检查“包含性”证明(证明特定记录存在于日志中)和“一致性”证明(证明树未被篡改)。下面是这样一个树的示例。

校验和数据库支持 go 命令用于请求和验证 go.sum 行的 一组端点。`/lookup` 端点提供一个“签名树头”(STH)和请求的 go.sum 行。`/tile` 端点提供树的块,称为 *tiles*,go 命令可以使用它们来生成证明。下面是 go 命令通过执行模块版本的 `/lookup`,然后请求证明所需的 tiles 来与校验和数据库交互的示例。

这个校验和数据库允许 go 命令安全地使用一个通常不值得信任的代理。因为在其之上有一个可审计的安全层,代理或源服务器无法有意、随意或意外地向您提供错误的代码而不被发现。即使是模块的作者,也无法在一夜之间移动其标签或更改与特定版本相关的代码,而不会被检测到。

如果您使用的是 Go 1.12 或更早版本,您可以使用 gosumcheck 手动将 go.sum 文件与校验和数据库进行比对。

$ go get golang.org/x/mod/gosumcheck
$ gosumcheck /path/to/go.sum

除了 go 命令进行的验证外,第三方审计员可以通过迭代日志查找错误条目来使校验和数据库负责。他们可以合作并交流树的状态,以确保其不被破坏,我们希望 Go 社区能够参与其中。

模块索引

模块索引由 index.golang.org 提供服务,它是一个公共的模块版本新发布信息流,这些信息通过 proxy.golang.org 可用。这对于工具开发者来说尤其有用,他们希望维护自己关于 proxy.golang.org 上可用内容的缓存,或者及时了解人们正在使用的一些最新模块。

反馈或 bug

我们希望这些服务能改善您使用模块的体验,如果您遇到问题或有任何反馈,请 提交 issue

下一篇文章:Go 1.13 发布
上一篇文章:迁移到 Go 模块
博客索引