最低成本搭建 golang 透明代理

目標

由於衆所周知的原因,golang.org 無法直接訪問,golang 文檔和安裝包無法下載,golang.org/x/net 等官方包無法下載。

常見解決方案是無腦掛代理,解決一切問題,但爲了以最小成本解決,我折騰出了這種方法,完全本機運行,無需外部代理和額外的服務器。是不是很爽?

思路

其實有官方鏡像可以用:

在本機自建 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 配置文件中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章