go中私有代理搭建
前言
最近公司的代理出現問題了,剛好借這個機會來學習下,athens 如何構建私有代理
為什麼選擇 athens
私有化代理的選取標準無非就是下面的幾點
1、託管私有模組;
2、排除對公有模組的訪問;
3、儲存公有模組;
athens 的特點:
Athens 首先可以配置訪問私有倉庫;
Athens 的會儲存每次拉取的包,如果該模組之前沒有通過 athens,athens 會向目標地址請求資料,在返回給客戶端的時候,會儲存該模組到儲存中,這樣實現了 go mod download
永遠只會發生一次;
Athens 處理儲存的策略為僅追加,一個模組被儲存,它就永遠不會改變,即使開發人員對 tag 進行了強推,那麼也不會被刪除;
Athens 也可以配置下載策略,過濾一些有安全隱患的包。
Athens 支援 disk, mongo, gcs, s3, minio, 外部儲存/自定義,不過一般建議使用 disk。
使用 docker-compose 部署
官方網站已經,提供了通過 docker 和 二進位制部署的方案,這裡秉著好記性不如爛筆頭的原則,這裡自己也做了記錄
配置私有倉庫的認證資訊
通過 .netrc
檔案來配置,裡面可以放自己的私有倉庫的地址,以及使用者,密碼認證資訊
# cat .netrc
machine gitlab.test.com login test-name password test-pass
有幾個私有倉庫,配置幾個就可以了
配置下載模式
通過 The download mode
(下載模式配置策略)是現在 ATHENS 中比較推崇的,之前通過 Filtering modules
(過濾模式)的方法,目前已經被棄用了。
來看下如何配置
# DownloadMode defines how Athens behaves when a module@version
# is not found in storage. There are 4 options:
# 1. "sync" (default): download the module synchronously and
# return the results to the client.
# 2. "async": return 404, but asynchronously store the module
# in the storage backend.
# 3. "redirect": return a 301 redirect status to the client
# with the base URL as the DownloadRedirectURL from below.
# 4. "async_redirect": same as option number 3 but it will
# asynchronously store the module to the backend.
# 5. "none": return 404 if a module is not found and do nothing.
# 6. "file:<path>": will point to an HCL file that specifies
# any of the 5 options above based on different import paths.
# 7. "custom:<base64-encoded-hcl>" is the same as option 6
# but the file is fully encoded in the option. This is
# useful for using an environment variable in serverless
# deployments.
# Env override: ATHENS_DOWNLOAD_MODE
DownloadMode = "sync"
通過環境變數 ATHENS_DOWNLOAD_MODE 可指定,也可以修改指定的 config.dev.toml
來配置,預設是 sync
ATHENS_DOWNLOAD_MODE 可指定的內容:
1、通過 file:<path>
指定一個 hcl 檔案,裡面可以對不同的倉庫,設定下載模式;
2、通過 custom:<base64-encoded-hcl>
指定一個 base64 編碼的 HCL 檔案;
3、指定具體的全域性策略,sync, async, none, redirect, or async_redirect
,這是一個全域性的設定,上面的兩種是可以定製策略組的。
來看下具體的下載模式
-
sync: 通過 同步從 VCS 下載模組
go mod download
,將其持久化到儲存中,並立即將其返回給使用者。請注意,這是預設行為; -
async:向客戶端返回 404,並非同步下載
module@version
並將其持久化到儲存中; -
none:返回 404 並且什麼也不做;
-
redirect:重定向到上游代理(例如proxy.golang.org),之後什麼也不做;
-
async_redirect:重定向到上游代理(例如
proxy.golang.org
)並非同步下載module@version
並將其持久化到儲存中;
下面看下配置策略的 hcl 檔案
# cat download.hcl
downloadURL = "https://goproxy.cn"
mode = "async_redirect"
download "gitlab.test.com/*" {
mode = "sync"
}
部署
這裡使用 docker-composer 部署
version: '2'
services:
athens:
image: gomods/athens:v0.11.0
restart: always
container_name: athens_proxy
ports:
- "3000:3000"
volumes:
- ./.netrc:/root/.netrc
- ./athens-storage:/var/lib/athens
- ./download.hcl:/root/download.hcl
environment:
- ATHENS_NETRC_PATH=/root/.netrc
- ATHENS_STORAGE_TYPE=disk
- ATHENS_DISK_STORAGE_ROOT=/var/lib/athens
- ATHENS_GOGET_WORKERS=100
- ATHENS_DOWNLOAD_MODE=file:/root/download.hcl
- ATHENS_GONOSUM_PATTERNS=gitlab.test.com
ATHENS_GONOSUM_PATTERNS:配置為私庫地址,配置的倉庫地址,不會進行安全向校驗。
go 處於安全性考慮,為了保證開發者的依賴庫不被人惡意劫持篡改,所以引入了 GOSUMDB 環境變數來設定校驗伺服器
當你在本地對依賴進行變動(更新/新增)操作時,Go 會自動去這個伺服器進行資料校驗,保證你下的這個程式碼庫和世界上其他人下的程式碼庫是一樣的。如果有問題,會有個大大的安全提示。當然背後的這些操作都已經整合在 Go 裡面了,開發者不需要進行額外的操作。
對於我們的私有倉庫,去公共安全校驗庫校驗,肯定是不能通過校驗的,我們可以通過 ATHENS_GONOSUM_PATTERNS 這個環境變數來設定不做校驗的程式碼倉庫, 它可以設定多個匹配路徑,用逗號相隔。
啟動 docker-compose up -d
客戶端設定代理 export GOPROXY=http://xxxx:3000
這樣就能使用我們的代理服務了
因為選擇的 ATHENS_STORAGE_TYPE 為 disk,athens 服務會在拉取資源包的同時,也會下載資源包到配置的 ATHENS_DISK_STORAGE_ROOT 中。
使用祕鑰的方式認證私有倉庫
上面通過 .netrc
的方式來認證私有倉庫,因為賬號密碼是銘文的總歸不太好,可以使用祕鑰的方式來認證
1、配置祕鑰
首先檢視電腦有沒有祕鑰
# cd .ssh
# ls
id_rsa id_rsa.pub
沒有的話通過下面的命令的生成
# ssh-keygen -t rsa -C "youremail@example.com"
郵箱換成自己的,一路回車即可
然後將 id_rsa.pub
公鑰的內容新增到自己的私有倉庫中,如何新增自己 google 吧,比較簡單
2、配置 HTTP 與 SSH 重寫規則
# cat gitconfig
[url "ssh://git@gitlab.test.com"]
insteadOf = https://gitlab.test.com
3、配置 SSH 來繞過主機 SSH 鍵驗證
# cat config
Host gitlab.test.com
Hostname gitlab.test.com
StrictHostKeyChecking no
IdentityFile /root/.ssh/id_rsa
將上面配置的認證資訊,對映到容器中即可
version: '2'
services:
athens:
image: gomods/athens:v0.11.0
restart: always
container_name: athens_proxy
ports:
- "3000:3000"
volumes:
- ./athens-storage:/var/lib/athens
- ./download.hcl:/root/download.hcl
- ./gitconfig:/root/.gitconfig
- ./ssh-keys:/root/.ssh
environment:
- ATHENS_STORAGE_TYPE=disk
- ATHENS_DISK_STORAGE_ROOT=/var/lib/athens
- ATHENS_GOGET_WORKERS=100
- ATHENS_DOWNLOAD_MODE=file:/root/download.hcl
- ATHENS_GONOSUM_PATTERNS=gitlab.test.com
這樣即可實現祕鑰的認證了
需要注意私鑰的許可權,剛開始沒注意,執行報了下面的錯誤
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/root/.ssh/id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "/root/.ssh/id_rsa": bad permissions
git@gitlab.test.com: Permission denied (publickey).
fatal: Could not read from remote repository.
看報錯就可推斷出,是許可權太大了,需要私鑰檔案不能被其他人所訪問。
修改許可權就可以了
ssh-keys # chmod 600 id_rsa
具體的 demo 地址,可參見athens私有代理部署
參考
【介紹 ATHENS】https://gomods.io/zh/intro/
【download】https://github.com/gomods/athens/blob/main/docs/content/configuration/download.md
【athens構建golang私有代理】https://github.com/boilingfrog/Go-POINT/blob/master/golang/go_environment/athens構建golang私有代理.md
【使用 docker-compose 部署 golang 的 Athens 私有代理】https://github.com/boilingfrog/Go-POINT/blob/master/golang/go_environment/athens構建golang私有代理.md