go get和go mod tidy是唯一能修改依赖版本的命令,所有依赖最终由go.mod决定而非远程lock文件;go.sum必须与go.mod一同提交以保障完整性校验;replace仅在根模块生效,私有模块需正确配置GOPRIVATE。

go get 和 go mod tidy 是唯一能改依赖的命令
你项目里所有依赖版本,最终只由 go.mod 文件决定,不是靠某个远程 lock 文件动态锁定。这意味着只要不手动执行 go get 或 go mod tidy,哪怕上游包发布了恶意新版本,你的构建也不会受影响。
混合开发中常有人在本地跑 go mod tidy 后直接提交,却忘了这会悄悄升级传递依赖——尤其是当某个间接依赖在它自己的 go.mod 里声明了更高版本时,MVS 算法会把它拉进来。
- CI 流水线里禁止自动运行
go mod tidy,只允许go build;失败就说明go.mod不完整,必须人工修复 - 本地开发时,执行
go mod tidy前先用go list -m all对比前后差异,重点关注非直接 require 的模块变动 - 如果团队用私有代理(如 Nexus、JFrog),确保其缓存策略不覆盖已存在版本的内容——Go 依赖内容不可变,但代理若允许重传同版本号包,就破坏了这一前提
go.sum 文件不是可选的校验层
go.sum 不是“锦上添花”,它是构建失败的第一道防线。它记录每个 module 版本的 h1: 哈希值,一旦下载内容与哈希不匹配,go build 直接报错:verifying github.com/some/pkg@v1.2.0: checksum mismatch。
混合模式下容易出问题的点在于:有人把 go.sum 排除在 Git 提交之外,或 CI 构建前清空 go.sum 再重新生成——这等于主动放弃内容完整性校验。
-
go.sum必须和go.mod一起签入 Git,且禁止.gitignore过滤 - 不要在 CI 中执行
go mod download后再删go.sum,也不要用go mod verify替代构建时校验——后者不阻断构建,起不到防护作用 - 若使用 GOPROXY,确认代理返回的响应头包含
X-Go-Mod-Checksum,否则可能绕过校验(某些老旧代理未实现该字段)
replace 指令可能被忽略或覆盖
replace 常用于临时切换私有分支或打补丁,但它只对当前 module 生效,且优先级低于 go.mod 中其他 module 的自身版本声明。混合开发中,多个子模块各自维护 go.mod,很容易出现 replace 失效的情况。
典型现象是:主模块写了 replace github.com/xxx => ./local-fix,但某个子模块的 go.mod 显式 require 了 github.com/xxx v1.5.0,结果构建时仍拉取远程 v1.5.0,本地 patch 完全没生效。
- 全局生效的
replace只能在根 module 的go.mod中定义;子模块里的replace对其他模块无效 - 避免在子模块中写
replace,统一收口到主模块;若必须分散管理,用go mod edit -replace脚本批量同步 - CI 构建前加一步检查:
go list -m -json all | jq -r 'select(.Replace != null) | .Path',确认所有预期替换都实际生效
私有模块路径必须匹配 GOPRIVATE 配置
Go 默认从 proxy.golang.org 下载公共模块,但对私有路径(如 git.internal.company/project)会跳过代理直连 VCS。如果 GOPRIVATE 没配全,部分私有依赖仍走公共代理——而代理可能缓存并返回篡改过的版本,或因 DNS 劫持导向恶意镜像。
常见疏漏是只配置一级路径,比如设了 GOPRIVATE=git.internal.company,但实际模块路径是 git.internal.company/team/repo,中间的 team 层没被覆盖,导致该模块仍走代理。
-
GOPRIVATE应设为完整域名通配,例如GOPRIVATE=*.internal.company,git.internal.company/* - 在 CI 和本地开发环境统一设置,避免开发机走 SSH、CI 走 HTTPS 导致行为不一致
- 验证是否生效:执行
go env GOPRIVATE,再运行go mod download -x观察日志里是否出现direct(表示直连 VCS)而非proxy
go.mod 和 go.sum 的信任是否贯穿整个流程——从开发者本地 go get 的那一刻起,到 CI 构建、镜像打包、生产部署,每个环节都必须保持这两份文件的权威性。任何绕过、重生成、选择性忽略,都在悄悄打开供应链攻击的后门。

















