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 get 的示例,该示例演示了 go 命令如何使用代理请求版本列表,然后请求最新标记版本的 info、mod 和 zip 文件。

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

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 支持。默克尔树的主要优势在于它是防篡改的,并且具有不允许未被检测到的错误行为的特性,这使其比简单数据库更值得信赖。go 命令使用此树来检查“包含”证明(特定记录是否存在于日志中)和“一致性”证明(树是否被篡改)之后,才会将新的 go.sum 行添加到模块的 go.sum 文件中。以下是这种树的示例。

校验和数据库支持 一组由 go 命令使用的端点 来请求和验证 go.sum 行。/lookup 端点提供“已签名树头”(STH)和请求的 go.sum 行。/tile 端点提供称为切片的树块,go 命令可以使用这些块来进行证明。以下是如何使用 go 命令与校验和数据库进行交互的示例,该示例演示了如何对模块版本进行 /lookup,然后请求证明所需的切片。

此校验和数据库使 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 中的内容或了解人们正在使用的最新模块的工具开发人员尤其有用。

反馈或错误

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

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