私有模块

Private modules 私有模块

原文:https://go.dev/ref/mod#private-modules

​ Go模块经常是在版本控制服务器和模块代理上开发和发布的,这些模块在公共互联网上是不可用的。go 命令可以从私有资源中下载和构建模块,不过通常需要一些配置。

​ 下面的环境变量可以用来配置对私有模块的访问。详情请参见Environment variables(环境变量)。有关控制发送到公共服务器的信息的信息,也请参见Privacy(隐私)

  • GOPROXY —— 模块代理URL的列表。go 命令将尝试按顺序从每个服务器下载模块。关键字 direct 指示 go 命令从其开发的版本控制存储库中下载模块,而不是使用代理。
  • GOPRIVATE —— 应该被视为私有的模块路径前缀的 glob 模式列表。作为 GONOPROXYGONOSUMDB 的默认值。
  • GONOPROXY —— 不应从代理下载的模块路径前缀的 glob 模式列表。go 命令将从开发模块的版本控制存储库中下载匹配的模块,而不考虑 GOPROXY
  • GONOSUMDB —— 不应使用公共校验和数据库 sum.golang.org 进行检查的模块路径前缀的 glob 模式列表。
  • GOINSECURE —— 可以通过HTTP和其他不安全协议检索的模块路径前缀的 glob 模式列表。

​ 这些变量可以在开发环境中设置(例如,在 .profile 文件中),也可以用 go env -w 永久设置。

​ 本节的其余部分描述了提供访问私有模块代理和版本控制存储库的常见模式。

Private proxy serving all modules 为所有模块提供服务的私有代理

​ 为所有模块(公共和私有)提供服务的中央私有代理服务器为管理员提供了最大程度的控制,并且对单个开发人员来说需要的配置最少。

​ 要配置go命令以使用这样的服务器,请设置以下环境变量,将https://proxy.corp.example.com替换为您的代理URL,将corp.example.com替换为您的模块前缀。

GOPROXY=https://proxy.corp.example.com
GONOSUMDB=corp.example.com

GOPROXY 设置指示 go 命令仅从 https://proxy.corp.example.com 下载模块;go 命令不会连接到其他代理或版本控制存储库。

GONOSUMDB 设置指示 go 命令不使用公共校验和数据库来验证路径以 corp.example.com 开头的模块。

​ 以这种配置运行的代理可能需要对私有版本控制服务器进行读取访问。它还需要访问公共互联网来下载公共模块的新版本。

​ 有几种现有的GOPROXY服务器实现可以以这种方式使用。最小的实现将从module cache(模块缓存)目录中提供文件,并使用go mod download(带有适当的配置)来检索丢失的模块。

Private proxy serving private modules 为私有模块提供服务的私有代理

​ 私人代理服务器可以为私人模块提供服务,而不需要为公开的模块提供服务。go命令可以被配置为在私人服务器上无法使用的模块时回退到公共源。

​ 要配置go命令以这种方式工作,请设置以下环境变量,将https://proxy.corp.example.com替换为代理URL,将corp.example.com替换为模块前缀:

GOPROXY=https://proxy.corp.example.com,https://proxy.golang.org,direct
GONOSUMDB=corp.example.com

GOPROXY 设置指示 go 命令首先尝试从 https://proxy.corp.example.com 下载模块。如果该服务器的回应是404 (Not Found)或410 (Gone),go命令将回退到https://proxy.golang.org,在之后才是直接连接到存储库。

GONOSUMDB 设置指示 go 命令不使用公共校验和数据库来验证路径以 corp.example.com 开头的模块。

​ 请注意,在这种配置下使用的代理仍然可以控制对公共模块的访问,即使它不为公共模块提供服务。如果代理以404或410以外的错误状态响应请求,go命令将不会回退到GOPROXY列表的后面条目。例如,代理可能会对具有不合适许可证或具有已知安全漏洞的模块响应403 (Forbidden) 。

Direct access to private modules 直接访问私有模块

go命令可以被配置为绕过公共代理,并直接从版本控制服务器下载私有模块。当无法运行私有代理服务器时,这非常有用。

​ 要配置 go 命令以这种方式工作,请设置 GOPRIVATE,将私有模块前缀替换为 corp.example.com

GOPRIVATE=corp.example.com

​ 在这种情况下,不需要更改GOPROXY变量。它的默认值是https://proxy.golang.org,direct,它指示go 命令首先尝试从https://proxy.golang.org,然后在代理响应404 (Not Found)或410 (Gone)时回退到直接连接。

GOPRIVATE设置指示go 命令不要连接到代理或以corp.example.com开头的模块的校验和数据库。

​ 可能仍需要内部HTTP服务器来将模块路径解析为存储库URL。例如,当 go 命令下载模块 corp.example.com/mod 时,它将向 https://corp.example.com/mod?go-get=1发送一个 GET 请求,并在响应中查找存储库的 URL。要避免这种需求,请确保每个私有模块路径都有一个VCS后缀(如.git)来标记存储库根的前缀。例如,当 go 命令下载模块 corp.example.com/repo.git/mod 时,它将在 https://corp.example.com/repo.gitssh://corp.example.com/repo.git中克隆 Git 存储库,而不需要发出额外的请求。

​ 开发人员将需要对包含私有模块的存储库具有读取权限。这可以在全局VCS配置文件中配置,如.gitconfig。好将VCS工具配置为不需要交互式身份验证提示。默认情况下,在调用Git时,go 命令通过设置GIT_TERMINAL_PROMPT=0来禁用交互式提示,但它会遵守显式设置。

Passing credentials to private proxies 将凭据传递给私有代理

go 命令在与代理服务器通信时支持 HTTPbasic authentication(基本身份验证)

​ 凭证可以在.netrc 文件中指定。例如,包含以下几行的.netrc文件将配置go 命令用给定的用户名和密码连接到proxy.corp.example.com机器上。

machine proxy.corp.example.com
login jrgopher
password hunter2

​ 文件的位置可以通过NETRC环境变量来设置。如果没有设置NETRCgo 命令将读取$HOME/.netrc(在类UNIX平台上),或读取%USERPROFILE%\_netrc(在Windows上)。

.netrc中的字段用空格、制表符和换行符分隔。遗憾的是,这些字符不能用于用户名或密码。还要注意的是,计算机名不能是一个完整的URL,因此不能为同一台机器上的不同路径指定不同的用户名和密码。

​ 另外,凭证可以直接在GOPROXY的URL中指定。例如:

GOPROXY=https://jrgopher:hunter2@proxy.corp.example.com

​ 采取这种方法时要小心:环境变量可能会出现在shell历史记录和日志中。

Passing credentials to private repositories 将凭证传递给私有存储库

go 命令可以直接从版本控制储存库中下载模块。如果没有使用私有代理,这对私有模块是必要的。参见Direct access to private modules(直接访问私有模块)的配置。

go 命令在直接下载模块时运行git等版本控制工具。这些工具执行它们自己的身份验证,所以您可能需要在工具特定的配置文件(如.gitconfig)中配置凭证。

​ 为了确保这项工作顺利进行,请确保go 命令使用正确的存储库URL,并且版本控制工具不需要交互式输入密码。go 命令优先使用 https:// URL,而不是ssh://等其他方案,除非在查找存储库 URL 时指定了方案。特别是对于 GitHub 存储库,go 命令假定为 https://

​ 对于大多数服务器,您可以将客户端配置为通过HTTP进行身份验证。例如,GitHub 支持使用 OAuth 个人访问令牌作为 HTTP 密码。您可以将HTTP密码存储在.netrc文件中,就像将凭证传递给私有代理时一样。

​ 另外,您也可以将https:// URL重写成另一种方案。例如,在.gitconfig中:

[url "git@github.com:"]
    insteadOf = https://github.com/

​ 更多信息,请参见为什么 “go get “在克隆存储库时使用HTTPS?

Privacy 隐私

go 命令可以从模块代理服务器和版本控制系统下载模块和元数据。环境变量GOPROXY控制使用哪些服务器。环境变量GOPRIVATEGONOPROXY控制从代理服务器获取哪些模块。

GOPROXY的默认值是:

https://proxy.golang.org,direct

​ 在此设置下,当go 命令下载模块或模块元数据时,它将首先向proxy.golang.org发送请求,这是一个由谷歌(privacy policy(隐私策略))运营的公共模块代理。有关在每个请求中发送哪些信息的详细信息,请参见GOPROXY 协议go 命令不会传输个人身份信息,但它会传输所请求的完整模块路径。如果代理以404 (Not Found)或410 (Gone) 状态响应,go 命令将尝试直接连接到提供该模块的版本控制系统。详见Version control systems(版本控制系统)

GOPRIVATEGONOPROXY 环境变量可以被设置为与模块前缀匹配的 glob 模式列表,这些模块前缀是私有的,不应该从任何代理请求。例如:

GOPRIVATE=*.corp.example.com,*.research.example.com

GOPRIVATE只是作为GONOPROXYGONOSUMDB的默认值,因此没有必要设置GONOPROXY,除非GONOSUMDB应该有一个不同的值。当模块路径与GONOPROXY匹配时,go 命令将忽略该模块的GOPROXY,并直接从其版本控制存储库中获取它。当没有代理为私有模块提供服务时,这很有用。参见Direct access to private modules(直接访问私有模块)

​ 如果有一个受信任的代理为所有模块提供服务,那么GONOPROXY就不应该被设置。例如,如果 GOPROXY 被设置为一个源,那么go 命令将不会从其他源下载模块。在这种情况下仍应设置GONOSUMDB

GOPROXY=https://proxy.corp.example.com
GONOSUMDB=*.corp.example.com,*.research.example.com

​ 如果有一个受信任的代理仅为私有模块提供服务,那么不应该设置GONOPROXY,但必须注意确保该代理以正确的状态码进行响应。例如,请考虑以下配置:

GOPROXY=https://proxy.corp.example.com,https://proxy.golang.org
GONOSUMDB=*.corp.example.com,*.research.example.com

​ 假设由于输入错误,开发人员试图下载一个不存在的模块。

go mod download corp.example.com/secret-product/typo@latest

go 命令首先从proxy.corp.example.com请求此模块。如果该代理响应404 (Not Found)或410 (Gone),那么go 命令将回退到proxy.golang.org,在请求URL中传输secret-product路径。如果私人代理响应任何其他错误码,那么go 命令将打印错误,并且不会回退到其他源。

​ 除了代理之外,go 命令还可以连接到校验和数据库,以验证go.sum中没有列出的模块的加密散列。GOSUMDB环境变量设置校验和数据库的名称、URL和公钥。GOSUMDB 的默认值是 sum.golang.org,它是由 Google (privacy policy(隐私策略))运营的公共校验和数据库。关于每次请求所传送的内容,请参见Checksum database(校验和数据库)。与代理一样,go 命令不会传输个人身份信息,但它会传输所请求的完整模块路径,而且校验和数据库无法计算非公共模块的校验和。

​ 可以将GONOSUMDB环境变量设置为指示哪些模块是私有的并且不应从校验和数据库请求的模式。 GOPRIVATE作为GONOSUMDBGONOPROXY的默认值,因此没有必要设置GONOSUMDB,除非GONOPROXY应该有不同的值。

​ 代理可以mirror the checksum database(镜像校验和数据库)。如果GOPROXY中的代理执行此操作,go 命令将不会直接连接到校验和数据库。

GOSUMDB可以被设置为off,以完全禁止使用校验和数据库。使用此设置时,go 命令将不会对下载的模块进行身份验证,除非它们已经在go.sum中。请参阅Authenticating modules(验证模块)

最后修改 October 10, 2024: 更新 (a4b8f85)