go從1.11開始引入了go module,其中有一個go proxy的特性能幫我們解決第三方包的下載,比如 golang.org/x 下的包
在這裏我們利用它不但能下外面的依賴,也能下內部項目的依賴
1.公用的go proxy
常用的go proxy,不用翻牆也能下了
export GOPROXY=https://goproxy.io
export GOPROXY=https://athens.azurefd.net
go get 會去請求go proxy,go proxy有就返回來,沒有就去github、golang.org等vcs去下載,再緩存起來
2.能科學上網的私有的go proxy
一般公司都有自己的gitlab、gogs之類的託管平臺,上面的公用的go proxy下載不了公司內部的依賴,一個簡單的方法就是找一臺能科學上網的內網機器做 go proxy,這樣既能下外網的依賴,也能下內網的依賴。我們可以用這個微軟開源的athens
簡單部署
base=/home/chen/athens
data_dir=$base/data
user_dir=$base/root
name=athens-proxy
# athens默認是3000端口
# 網絡模式用了host模式,以便訪問內網的機器和域名
docker run -d \
-v ${data_dir}:/var/lib/athens \
-v ${user_dir}:/root \
-e ATHENS_DISK_STORAGE_ROOT=/var/lib/athens \
-e ATHENS_STORAGE_TYPE=disk \
--name ${name} \
--net host \
--restart always \
gomods/athens:v0.4.0
# 假設內部域名是git.test.com,可以在/etc/hosts裏面加進去
# go get默認走https協議,如果你的gitlab或者gogs只有http或者ssh兩種訪問方式,用ssh替代https
docker exec ${name} git config --global url."[email protected]:".insteadOf "https://git.test.com"
# 記得進入容器裏面用 ssh-keygen -t rsa 命令生成祕鑰,把公鑰上傳到git服務器
# 公鑰存在容器的/root/.ssh/下
# 假設ip是192.168.1.100
export GOPROXY=http://192.168.1.100:3000
# GO111MODULE=on
# 在容器外面和裏面分別嘗試執行這個指令
go get git.test.com/web/[email protected]
在你的go代碼裏面
# 依賴的go module是 git.test.com/web/server.git ,在go.mod能看到
import "git.test.com/web/server.git/pkg/utils"
3.不用科學上網的go proxy
nginx是個好東西,利用它的路由匹配規則,轉發到不同的go proxy處理,這樣就不用翻牆了
這裏nginx機器是192.168.40.131
# athens.conf
# 把該文件放到/etc/nginx/conf.d/下並執行重啓 nginx -s reload
server {
listen 4000;
# 外部的依賴轉發到外面的go proxy
location / {
# proxy_pass https://goproxy.io;
proxy_pass https://athens.azurefd.net;
}
# 內部依賴的go proxy,也就是上面啓動的athens
location ~ /git\.test\.com/ {
proxy_pass http://192.168.1.100:3000;
}
}
然後
export GOPROXY=http://192.168.40.131:4000
4.解決go get包必須帶 .git 後綴的問題
看上面我們知道每次下載都要加上.git後綴
go get git.test.com/web/[email protected]
代碼裏面
import "git.test.com/web/server.git/pkg/utils"
有沒有辦法去掉路徑裏面的 .git 呢,當然有啦。首先你的gitlab或者gogs等先開啓https,花錢買證書是不可能的,窮人還是會過日子,自己做CA吧,CA簽發證書給服務器用,準確來說給git服務器的nginx代理用,然後客戶端系統和瀏覽器導入CA的根證書
先把https裏面的概念理清楚,再去做,理解了才能靈活運用
關於證書生成:
Centos(重點看): 基於OpenSSL自建CA和頒發SSL證書
Ubuntu: Ubuntu使用OpenSSL生成數字證書詳解
ubuntu導入ca根證書注意:
# 假設ca的根證書是cacert.pem,重命名成crt結尾的
cp cacert.pem cacert.crt
mv cacert.crt /usr/local/share/ca-certificates/
update-ca-certificates
curl -v https://git.test.com #測試
# 如何不成功試試這個格式轉換的,再重新導入
openssl x509 -outform der -in cacert.pem -out cacert.crt
看完上面的文章你應該能生成用於gitlab或者gogs的簽發證書和私鑰了吧
注意: 簽發證書時 Common Name一定要是你要授予證書的服務器域名或主機名,這裏是 git.test.com
不管是gitlab還是gogs,如何利用nginx解決路徑帶.git的問題,看 這篇文章
gitlab開啓https我就不說了,解決路徑帶 .git的問題上面說了
下面說說我用的gitea(gogs的社區版):
gitlab有配套的nginx組件,gitea沒有,那就自己做一個代理好了,直接上nginx的配置
# gitea的地址,好巧也是3000端口,自己可以改
upstream gitea {
server 192.168.40.131:3000;
}
# nginx剛好跟gitea在同一臺機器
server {
listen 192.168.40.131:80;
server_name git.test.com;
# 這裏選擇重定向到https去
rewrite ^(.*)$ https://${server_name}$1 permanent;
# 也可以不重定向
#location / {
# proxy_pass http://gitea;
#}
}
server {
listen 443;
server_name git.test.com;
ssl on;
ssl_certificate /data/gitea/ssl/server.crt; # 自己ca簽發的
ssl_certificate_key /data/gitea/ssl/server.key; # 自己的私鑰
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
proxy_cache off;
proxy_pass http://gitea;
}
location ~* ^/[^/]+/[^/]+$ {
if ($http_user_agent ~* '^go.*') {
return 200 "<!DOCTYPE html><head><meta content='$host$uri git ssh://git@$host:$uri.git' name='go-import'></head></html>";
}
proxy_cache off;
proxy_pass http://gitea;
}
location ~* ^/(?<holder>[^/]+)/(?<project>[^/]+)/.*$ {
set $goRedirect 'https://$host/$holder/$project?$args';
if ($http_user_agent ~* '^go.*') {
return 301 $goRedirect;
}
proxy_cache off;
proxy_pass http://gitea;
}
}
上面是git服務器的,下面輪到go proxy了,不一定跟git同一臺機器,要走回https的老路了
base=/home/chen/athens
data_dir=$base/data
user_dir=$base/root
cert_dir=$base/ca #這裏存放ca的根證書,比如cacert.pem把它重命名cacert.crt,參考Ubuntu是如何導入ca證書的
name=athens-proxy
docker run -d \
-v ${data_dir}:/var/lib/athens \
-v ${user_dir}:/root \
-v ${cert_dir}:/usr/local/share/ca-certificates \
-e ATHENS_DISK_STORAGE_ROOT=/var/lib/athens \
-e ATHENS_STORAGE_TYPE=disk \
--name ${name} \
--restart always \
--net host \
gomods/athens:v0.4.0
docker exec ${name} sh -c 'git config --global http.sslVerify false' #可能需要
docker exec ${name} sh -c 'update-ca-certificates'
# 容器外面和裏面都試一下
curl https://git.test.com
go get git.test.com/web/[email protected]
go代碼裏面
# 路徑裏面沒有.git了,這次舒服了吧
import "git.test.com/web/server/pkg/utils"
總結,go get–>nginx–>go proxy–>nginx–>gitlab,一路走下來不容易啊