离线环境不能直接用go mod download,因其默认依赖proxy.golang.org和github等外网仓库,而物理隔离网络无dns解析与https出口,必然报错;可行方案是预下载模块三件套(.info/.mod/.zip)并用goproxy提供符合go module fetch协议的静态http服务。

离线环境为什么不能直接用 go mod download
因为 go mod download 默认会访问 proxy.golang.org 和模块源仓库(如 GitHub、GitLab),而物理隔离网络完全无外网出口,DNS 不通、HTTPS 请求超时,执行后直接报错:Get "https://proxy.golang.org/...": dial tcp: lookup proxy.golang.org: no such host 或 unable to fetch module。这不是配置问题,是网络路径根本不存在。
真正可行的离线方案:用 goproxy + 预下载 zip 包构建本地镜像
核心思路不是“代理转发”,而是“静态文件服务”——把所有依赖模块提前在有网机器上打包成 .zip 归档,复制进隔离网,再用轻量服务(如 goproxy)提供符合 Go Module Fetch 协议的 HTTP 接口。关键点:
-
goproxy必须启用GOPROXY=direct模式(即不向上游代理),否则仍会尝试外连 - 所有模块必须以
module@version.info、module@version.mod、module@version.zip三件套形式组织,缺一不可,否则go get会报invalid version - 推荐用官方工具
goproxy.io/cmd/goproxy(非goproxy.cn服务端),它支持纯文件系统模式,无需数据库 - 预下载命令示例:
go mod download -json github.com/gin-gonic/gin@v1.9.1 > /tmp/gin.json,再用脚本提取 URL 并下载对应.zip(Go 官方模块服务器返回的Zip字段值)
目录结构和 GOPROXY 配置必须严格匹配协议要求
Go 客户端请求格式为 GET $GOPROXY/<module>/@v/<version>.info</version></module>,所以离线服务根目录必须按此路径存放文件。常见错误:
- 把
github.com/foo/bar@v1.2.3.zip直接丢进/mirror/,但 Go 会找/mirror/github.com/foo/bar/@v/v1.2.3.zip—— 路径层级少了一级@v - 用普通 HTTP 服务器(如 Python
http.server)但未设置Content-Type: application/json(对.info文件)或application/zip(对.zip),导致go mod verify失败 -
GOPROXY环境变量设成http://10.0.0.10:8080,但没加末尾斜杠,Go 会拼出http://10.0.0.10:8080github.com/...,404
验证是否真离线可用:关掉网卡再跑 go mod tidy
别信日志里 “downloaded” 就代表成功——Go 有时会从本地缓存($GOCACHE)读取,而非走代理。验证步骤:
- 临时清空
$GOCACHE和$GOPATH/pkg/mod/cache - 拔掉网线 / 关闭虚拟机 NAT / iptables DROP 所有 outbound 流量
- 执行
go mod tidy -v,观察是否出现go: downloading github.com/xxx且无超时或 DNS 错误 - 检查生成的
go.sum是否完整,对比在线环境生成的哈希值是否一致(可选但强烈建议)
最常被忽略的是 .mod 文件缺失——它包含模块校验和,没有它,go mod verify 会失败,但 tidy 可能静默跳过,直到构建阶段才暴露。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











