根本原因是穿透链路劫持tls握手或http重定向,导致go mod download超时或x509证书错误;解决方法是设goproxy=direct并gosumdb=off直连,或自建go proxy并通过tcp模式穿透其端口,禁用中间件干扰。

Go模块依赖下载在内网穿透环境下失败,根本原因不是“网络不通”,而是 go mod download 默认走 HTTPS + GOPROXY,而穿透链路往往不透明地劫持或丢弃 TLS 握手、HTTP 重定向、或代理认证头——尤其当穿透工具(如 frp、cpolar、ngrok)未启用 TCP 模式或未透传原始连接时。
为什么 go mod download 在穿透后经常超时或报 x509: certificate signed by unknown authority
Go 的模块下载默认依赖 GOPROXY(如 https://proxy.golang.org),该地址强制 HTTPS。若你的穿透服务:
- 用的是 HTTP 反向代理(如 Nginx 转发到内网 Go proxy),但没正确透传 Host 和 TLS SNI;
- 或客户端走的是 HTTPS → 穿透服务器 → 内网代理,而穿透服务器证书是自签的(比如 ngrok 自建服务用的 server.crt),go 不信任该 CA;
- 或穿透链路中间做了 HTTP 302 重定向,但 Go 的 net/http 默认不跟随跳转(尤其对非 GET 请求);
就会触发证书错误或连接中断。
常见现象:go mod download -x 显示卡在 GET https://proxy.golang.org/…,几秒后报 context deadline exceeded 或 x509 错误。
绕过 GOPROXY 直连模块源(适用于 GitHub/GitLab 等公开仓库)
如果目标模块托管在 GitHub、GitLab 等支持 Git 协议的平台,可让 Go 直接走 Git over SSH 或 HTTPS,跳过代理:
- 设置环境变量:
GOPROXY=direct,同时确保GOSUMDB=off(避免校验和服务器也走代理) - 强制指定 Git 协议行为:
git config --global url."https://github.com/".insteadOf "https://github.com/"(看似冗余,实为防止某些镜像域名被 GOPROXY 替换) - 若用 SSH,确认
~/.ssh/id_rsa已加载且git@github.com可连(穿透需支持 TCP 模式,HTTP 模式无法透传 SSH)
示例命令:
GO111MODULE=on GOPROXY=direct GOSUMDB=off go mod download -x
自建 Go proxy 并穿透其 8080 端口(推荐稳定场景)
比直连更可控:部署一个 goproxy.cn 或官方 proxy.golang.org 兼容的代理(如 athens 或 goproxy),再用穿透工具暴露其端口:
- 启动 proxy(以
goproxy为例):GOPROXY=off GOSUMDB=off goproxy -listen :8080 -cache-dir ./cache - 穿透时必须用 TCP 模式(不是 HTTP)——frp 填
type = tcp,cpolar 选tcp隧道,ngrok 启动时加-proto=tcp - 客户端设置:
GOPROXY=http://your-tunnel-domain:port(注意:不能带https://,除非你给穿透域名配了有效 TLS 证书) - 避免路径问题:proxy 的根路径必须是
/,不要设成/proxy/,否则 Go 客户端会请求http://x/y/@v/list失败
调试阶段必须检查的三个连接点
别只盯着 go mod download 报错——先验证底层链路是否真正通:
- 用
curl -v http://your-tunnel-domain:port看能否拿到200 OK和Content-Type: text/plain(proxy 根路径应返回欢迎文本) - 用
telnet your-tunnel-domain port测试 TCP 层连通性;失败说明穿透未生效或防火墙拦截 - 在穿透服务器上抓包:
tcpdump -i any port 8080 -w proxy.pcap,确认请求是否抵达、响应是否发出
最容易被忽略的是:很多穿透工具(尤其是免费 Web 控制台版)默认只转发 HTTP 流量,对 Go proxy 所需的长连接、HEAD 请求、分块传输支持极差——必须手动切到纯 TCP 模式,且关闭所有“自动重写 Host”“添加 X-Forwarded-* 头”等中间件逻辑。











