乐趣区

最低成本搭建-golang-透明代理

目标

由于众所周知的原因,golang.org 无法直接访问,golang 文档和安装包无法下载,golang.org/x/net 等官方包无法下载。

常见解决方案是无脑挂代理,解决一切问题,但为了以最小成本解决,我折腾出了这种方法,完全本机运行,无需外部代理和额外的服务器。是不是很爽?

思路

其实有官方镜像可以用:

  • golang.org:https://golang.google.cn/
  • 官方包:https://github.com/golang/

在本机自建 https 透明代理服务,通过 hosts 把 golang.org 解析到本机,代理服务再去请求镜像站。

这里就有另一个需要解决的问题,如 golang.org/x/net 包,经过透明代理后,实际访问的网址是 https://golang.google.cn/x/net。虽然这个网址直接打开没问题,但并不能通过 go get 拉取到包。原因可以看网页源码,里面其实记录了一个跳转网址,告诉 go get 工具,应该到 https://go.googlesource.com/net 拉取源码。很不幸,go.googlesource.com 也无法访问,但可以用官方 github 镜像代替:https://github.com/golang/net

https 自签证书

这个教程已经遍地都是了,我这里就直接上代码了。由于我的电脑系统是 win10,这些命令其实是在 wsl 中执行的。

# 创建工作目录
mkdir ~/ssl
cd ~/ssl

# CA 证书
openssl genrsa -des3 -out ca.key 2048
openssl req -sha256 -new -x509 -days 365 -key ca.key -out ca.crt \
    -subj "/C=CN/ST=HN/L=XC/O=wzv5/OU=wzv5/CN=wzv5Root"
# 这里会提示输入密码,记好密码,之后要用

# 要制作的证书名字及 DNS
export KEYNAME=golang
export DNSNAME="DNS:golang.org,DNS:go.googlesource.com"

# 创建 https 证书
openssl genrsa -des3 -out $KEYNAME.key 2048
# 这里会提示输入密码,随便输一个
openssl rsa -in $KEYNAME.key -out $KEYNAME.key
# 输入上一步的密码,这行命令其实是用来清除密码的
openssl req -new \
    -sha256 \
    -key $KEYNAME.key \
    -out $KEYNAME.csr \
    -subj "/C=CN/ST=HN/L=XC/O=wzv5/OU=wzv5/CN=$KEYNAME"
openssl x509 -req \
    -days 365 -sha256 \
    -CA ca.crt \
    -CAkey ca.key \
    -in $KEYNAME.csr \
    -out $KEYNAME.crt \
    -extensions SAN \
    -extfile <(printf "[SAN]\nsubjectAltName=$DNSNAME")
# 这里会要求输入 CA 证书的密码 

我们只需要 .crt 和 .key 文件,前者是公钥,后者是私钥。

CA 证书的密码要记好,之后如果需要其他域名的证书,可以重复使用 CA 证书。

caddy 透明代理

其实最初我是想用 nginx,配置文件都写一半了,突然意识到这算不算大炮打蚊子呢,这么简单一个需求,至于上 nginx 么,找个简单易用的工具凑合得了,于是就换成了 caddy。

caddy 是 go 语言写的 http 服务器,非常易用,也符合本文的 go 生态,用 go 解决 go 中遇到的问题,多么和谐。

从 https://github.com/mholt/caddy/releases/latest 下载 caddy,只需要压缩包内的可执行文件,其他文件无视。

仍然以 win10 的 wsl 作为运行环境来举例。把解压出来的 caddy 可执行文件放到 PATH 路径中,如 /usr/local/bin/caddy。创建目录 /usr/local/etc/caddy/ssl,把上面创建的 golang.crtgolang.key 文件放进来。创建文件 /usr/local/etc/caddy/Caddyfile,写入以下内容:

https://golang.org {
    tls /usr/local/etc/caddy/ssl/golang.crt /usr/local/etc/caddy/ssl/golang.key
    proxy / https://golang.google.cn/
}

https://go.googlesource.com {
    tls /usr/local/etc/caddy/ssl/golang.crt /usr/local/etc/caddy/ssl/golang.key
    proxy / https://github.com/golang/
}

caddy 的配置文件格式是不是非常简洁?想想 nginx 要写多少。。

最后启动 caddy。

caddy -conf /usr/local/etc/caddy/Caddyfile

系统信任自签证书

由于不同的系统方法不一样,这里就拿我使用的 win10 系统举例。

双击 ca.crt 文件,系统会弹出证书信息界面,选择“安装证书”,安装到“当前用户”的“受信任的根证书颁发机构”。

对于 linux 系统,可以自己查阅 man update-ca-trust,文档也很详细。

git 信任自签证书

网络上铺天盖地全是设置 http.sslVerify = false,但是切记, 不到万不得已千万不要这么干 ,证书链是网络安全的基础,禁用证书校验是非常危险的行为。并且作为程序员,你得为你的用户负责,确保自己的开发环境是安全的。

这里我选择为 git 设置自定义的 CA 证书列表,也就是 http.sslCAInfo

首先从 https://curl.haxx.se/ca/cacert.pem 下载默认证书,用文本编辑器打开 cacert.pem,把上面我们自己创建的 ca.crt 文件的内容追加到末尾,保存退出,就得到了一个包含默认 CA 和我们自签 CA 的证书包文件。

修改 git 设置:

git config --global http.sslcainfo < 改成你自己的路径 >/cacert.pem

如果不想这么麻烦,还有一种方法,就是为指定的域名禁用证书校验。

直接编辑文件 $HOME/.gitconfig,写入以下内容:

[http "https://go.googlesource.com"]
    sslverify = false

也就是只对 go.googlesource.com 域名禁用证书验证。

修改 hosts

127.0.0.1    golang.org
127.0.0.1    go.googlesource.com

由于 DNS 缓存,或许你需要重启才能生效。

最终成果

go get -u -v golang.org/x/net
go get -u -v github.com/gin-gonic/gin

不出意外,上述命令能够在国内网络中正常运行,只不过速度可能有点慢,毕竟 github 在国内的访问并不稳定。

我在实际使用中,其实是把 caddy 开机启动了,这样电脑一启动就是直接可用的状态。同时,caddy 还兼顾修复 steam 社区的作用,具体方法就不说了,免得被封喽,原理都差不多,就是把不能访问的域名解析到本机,然后找到某种可以直接访问的方式,写到 caddy 配置文件中。

退出移动版