根本原因是go不支持代理链,goproxy仅支持单层代理;当需经公司内部代理访问外部代理时,必须配合http_proxy使用http协议的goproxy地址,或自建中间代理服务实现https转发。

为什么 go get 会失败,而设置 GOPROXY 后仍超时?
根本原因不是代理没配,而是 Go 的模块代理机制默认只走单层代理——GOPROXY 指向的地址必须能直接响应 /@v/list、/@v/xxx.info 等请求。如果你的网络需要先过公司内部代理(比如 http://proxy.corp:8080),再访问外部代理(比如 https://goproxy.cn),Go 原生不支持“代理链”,GOPROXY 无法写成 http://proxy.corp:8080/https://goproxy.cn 这种形式。
用 GOPROXY + HTTP_PROXY 组合实现两级代理
Go 在 1.13+ 中会同时读取 GOPROXY 和系统级代理环境变量(HTTP_PROXY / HTTPS_PROXY)。当 GOPROXY 是 HTTPS 地址时,Go 会忽略 HTTP_PROXY;但若设为 HTTP 地址,Go 就会通过 HTTP_PROXY 转发所有对它的请求——这就构成了代理链。
- 把你的上游代理(如公司 proxy)设为
HTTP_PROXY=http://proxy.corp:8080 - 把
GOPROXY设为一个「可被公司 proxy 转发的 HTTP 地址」,例如:GOPROXY=http://goproxy.cn(注意是http://,不是https://) - Go 会把请求发给
http://goproxy.cn,而该请求实际由HTTP_PROXY转发出去,完成链式跳转 - 务必同时设置
NO_PROXY=localhost,127.0.0.1,.corp,避免内部域名被错误转发
自建中间代理服务绕过协议限制
如果上游 proxy 只允许 HTTPS 出站,或你无法控制 HTTP_PROXY(比如 CI 环境权限受限),就得自己搭一层反向代理,把 https://goproxy.cn 映射为本地 HTTP 服务。
最简方式:用 nginx 或 mitmproxy,但更轻量的是用 goproxy 工具本身:
go install github.com/goproxyio/goproxy@latest goproxy -proxy https://goproxy.cn -listen :8081
然后设:GOPROXY=http://localhost:8081,再配合 HTTP_PROXY 或直连使用。注意:goproxy 默认不缓存,加 -cache-dir ./cache 可持久化。
验证代理链是否生效的三个关键检查点
别只看 go build 成功就认为链路通了——很多模块下载看似成功,实则 fallback 到了 direct 模式(即直接 git clone),这会暴露真实 IP 并失败。
- 运行
go env GOPROXY和go env HTTP_PROXY,确认值符合预期(且无空格、多余引号) - 执行
go list -m -u all 2>&1 | head -n 5,观察输出里是否有Fetching...行;若出现go: downloading ...但无 fetching,则大概率走了 direct - 临时改错
GOPROXY为一个不存在的地址(如http://fake.proxy),如果报错是connection refused(而非 timeout 或 git error),说明代理链已介入
真正难调的不是配置项本身,而是不同网络环境下 HTTP_PROXY 对 HTTPS 目标的兼容性差异——有些 proxy 会拒绝转发到非 443 端口的 HTTPS 请求,这时候必须用自建中间代理兜底。











