GOSUMDB 默认拦截私有模块拉取,因其强制校验模块签名是否来自官方透明日志(如 sum.golang.org),而私有仓库不在该日志中,导致 go get 报 404;可通过 GONOSUMDB 白名单跳过指定域名校验,或在可信环境下设 GOSUMDB=off,自建服务则面临运维高成本与证书等限制。

为什么 GOSUMDB 默认值会拦住私有模块拉取
Go 1.13+ 默认启用 GOSUMDB,它强制校验所有模块的 go.sum 签名是否来自官方透明日志(如 sum.golang.org)。私有仓库、内网模块、或未公开到公共索引的模块,根本不在这个日志里,go get 就会直接报错:verifying github.com/your/internal@v0.1.0: github.com/your/internal@v0.1.0: reading https://sum.golang.org/lookup/github.com/your/internal@v0.1.0: 404 Not Found。
这不是网络问题,也不是权限问题,是 Go 模块验证机制的默认行为——它只信任公开可查的日志源。
- 若你用的是公司内网 Git、GitLab 私有组、或未推送到 GitHub 的模块,
GOSUMDB必须调整 - 改
GOSUMDB=off最快,但会彻底关闭校验,不推荐用于生产构建环境 - 更稳妥的做法是让 Go 接受你自己的校验服务,或跳过特定域名
如何跳过指定域名的 GOSUMDB 校验
Go 支持用 GOSUMDB=off 或 GOSUMDB=gosum.io+<private-key></private-key>,但更常用、也更安全的是用 GONOSUMDB 环境变量白名单跳过校验。
比如你的私有模块全在 git.internal.company.com 下,就设:
立即学习“go语言免费学习笔记(深入)”;
GONOSUMDB=git.internal.company.com
多个域名用逗号分隔,不加空格:
GONOSUMDB=git.internal.company.com,github.com/my-private-org
-
GONOSUMDB只影响模块路径前缀匹配,不是正则,所以git.internal.company.com/foo会被跳过,但my.git.internal.company.com不会 - 它和
GOSUMDB共存时优先级更高:即使GOSUMDB=sum.golang.org,匹配上的模块也不会去查 - CI/CD 中建议写进构建脚本开头,而不是全局设在 shell profile 里,避免污染其他项目
GOSUMDB=off 在什么场景下真能用
关掉校验不是“不安全”,而是把责任移交给其他环节。如果你已经通过以下方式确保模块来源可信,GOSUMDB=off 是合理选择:
- 所有依赖都走内部 Nexus/Artifactory 代理,并启用了 checksum 验证和签名拦截
- CI 构建使用固定 commit hash +
go mod download -x日志人工审计过依赖树 - 项目完全离线开发,所有
.zip和go.sum文件随代码一起提交,且禁止go get动态拉取
注意:GOSUMDB=off 不影响 go.sum 文件生成和比对,只是跳过远程签名查询。本地 go.sum 仍会记录哈希,下次 go build 仍会校验本地缓存一致性。
自建 GOSUMDB 服务的关键限制
官方没提供开箱即用的私有 GOSUMDB 实现,社区方案(如 sumdb-proxy)本质是反向代理 + 缓存,但要注意几个硬约束:
- 它必须能访问
sum.golang.org(或你指定的上游),否则无法为公共模块签发有效响应 - 私有模块仍需手动注入签名,Go 官方工具链不支持往自定义 sumdb 写入;你得自己实现
/lookup和/tlog接口并维护透明日志 -
GOSUMDB=https://your-sumdb.example.com要求服务端 HTTPS 证书有效,Go 不接受自签名证书,哪怕加了-insecure也不行
绝大多数团队卡在这一步就退回用 GONOSUMDB ——不是技术做不到,是运维成本远超收益。真正需要自建的,通常是超大型组织已有成熟模块治理平台,且合规要求强制所有依赖必须经统一签名中心背书。










