Go 博客
模块镜像和校验和数据库已启动
我们很高兴地宣布,我们的模块镜像,索引和校验和数据库现已可用于生产环境!对于Go 1.13 模块用户,go
命令将默认使用模块镜像和校验和数据库。请参阅proxy.golang.org/privacy了解这些服务的隐私信息,并查阅go 命令文档以获取配置详细信息,包括如何禁用这些服务器或使用其他服务器。如果您依赖非公共模块,请查阅配置环境的文档。
本文将介绍这些服务及其优势,并总结了 Gophercon 2019 上Go 模块代理:查询的生命周期演讲中的一些要点。如果您对完整演讲感兴趣,请参阅录像。
模块镜像
模块是 Go 软件包的集合,它们一起进行版本控制,每个版本的内容都是不可变的。这种不可变性为缓存和认证提供了新的机会。当 go get
在模块模式下运行时,它必须获取包含所需软件包的模块,以及该模块引入的任何新依赖项,并根据需要更新您的go.mod和go.sum文件。从版本控制系统中获取模块可能会耗费系统延迟和存储空间:go
命令可能被迫拉取包含传递性依赖项的仓库的完整提交历史,即使是未被构建的依赖项,仅仅是为了解析其版本。
解决方案是使用模块代理,它提供的 API 更适合 go
命令的需求(请参阅 go help goproxy
)。当 go get
在模块模式下使用代理运行时,它只需请求所需的特定模块元数据或源代码,而不必担心其他内容,从而工作更快。下面是 go
命令如何使用代理与 go get
结合的示例,它会先请求版本列表,然后请求最新标签版本的 info、mod 和 zip 文件。

模块镜像是模块代理的一种特殊类型,它将元数据和源代码缓存到自己的存储系统中,使得即使原始位置不再提供源代码,镜像仍然可以继续提供服务。这可以加快下载速度,并保护您免受依赖项消失的影响。更多信息请参阅Go Modules in 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支持的哈希值的透明日志(或称“Merkle 树”)构建。Merkle 树的主要优势在于它是防篡改的,其特性使得任何不良行为都无法不被察觉,这使其比简单的数据库更值得信赖。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提供服务,是一个公共 feed,提供通过proxy.golang.org可用的新模块版本信息。这对于希望保留自己的 proxy.golang.org 中可用模块缓存的工具开发者,或者希望及时了解人们正在使用的一些最新模块的开发者特别有用。
反馈或 Bug
我们希望这些服务能改善您使用模块的体验,并鼓励您在遇到问题或有反馈时提交问题!
下一篇文章:Go 1.13 发布
上一篇文章:迁移到 Go 模块
博客索引