Docker配置Trojan代理

MelonTe發表於2024-10-24

1、遇到的問題

在做雲端計算作業,使用阿里雲的ECS伺服器嘗試使用docker拉取映象的時候,發現一直無法從倉庫拉取,更換了多個映象源也沒有解決問題,於是決定學會去配置linux的代理,記錄過程。

2、安裝Trojan

何為Trojan?

Trojans是一種加密的代理協議,全稱為Trojan-GFW,是目前最成功的代理加速偽裝技術之一。

Trojan的工作原理?

Trojan透過監聽443埠,模仿網際網路上最常見的HTTPS協議,把合法的Trojan代理資料偽裝成正常的HTTPS通訊,並真正地完整完成TLS握手,以誘騙GFW認為它是HTTPS,從而不被識別。

為什麼使用Trojan?

首先主要原因是因為我使用的提供代理的網站大部分的連線都是採用了Trojan協議的。其次Trojan協議本身並不能被Docker識別,為了讓Docker使用代理,需要藉助Trojan客戶端工具接收Docker發出的http協議的請求,再輸出出去。

我們使用指令wget https://github.com/trojan-gfw/trojan/releases/download/v1.16.0/trojan-1.16.0-linux-amd64.tar.xz從Github下載Trojan的預編譯二進位制檔案。

下載成功後,使用tar -xvf trojan-1.16.0-linux-amd64.tar.xz解壓下載的資料夾。

使用sudo mv trojan /usr/local/bin/移動到可執行檔案路徑,並且使用sudo mkdir /etc/trojan建立配置檔案目錄。

使用/usr/local/bin/trojan/trojan -v可以檢測是否安裝成功。

3、配置Trojan

參考:Linux命令列使用Trojan代理加速

建立並編輯配置檔案 /etc/trojan/config.json,將你的代理資訊填入其中,配置檔案內容如下:

{
  "run_type": "client",//執行型別
  "local_addr": "127.0.0.1",//本地監聽地址
  "local_port": 1080,//本地監聽埠
  "remote_addr": "***",//服務端的ip或域名
  "remote_port": ***,//服務端的ip或埠
  "password": [
    "***"//對應服務端設定的密碼
  ],
  "ssl": {//ssl證書配置
    "sni": "***"
  }
    //若不需要ssl證書配置,請配置如下文
  //   "ssl": {
  //  "verify": false,
  //  "sni": "***"
  //}
}

使用如下命令後臺執行Trojan。

/usr/local/bin/trojan/trojan -c /etc/trojan/config.json &

使用如下命令可以殺死Trojan程序。

pkill -f trojan

此時,Trojan客戶端就會在本地啟動一個SOCKS5代理服務,將Trojans流量轉換成SOCKS5代理,監聽127.0.0.1:8080

4、為Docker配置代理

我們在docker的/etc/docker.daemon.json檔案下新增如下配置

{
  "proxies": {
      "http-proxy": "http://127.0.0.1:1080",
      "https-proxy": "http://127.0.0.1:1080",
      "no-proxy": "localhost,127.0.0.1"
  }
}

然後使用sudo systemctl restart docker重新啟動docker,現在配置已經完成。

再次測試docker run hello-wolrld,檢視是否成功。

哈哈!失敗了。

資訊顯示連線失敗了,那麼我們需要進行錯誤排查。

我們使用如下命令來檢查能否使用SOCKS5協議向docker倉庫傳送資訊。

curl -x socks5://127.0.0.1:1080 https://registry-1.docker.io/v2/
[2024-10-23 22:51:23] [INFO] 127.0.0.1:49036 requested connection to 157.240.17.41:443
[2024-10-23 22:51:25] [INFO] 127.0.0.1:49036 disconnected, 3422 bytes received, 213 bytes sent, lasted for 2 seconds
curl: (51) Unable to communicate securely with peer: requested domain name does not match the server's certificate.

可以看到,失敗的原因是因為證書認證失敗,我們換一個網站進行測試,檢查我們的代理是否面對任何網站都會認證失敗,如果是那就說明是我們的Trojan客戶端配出了問題。

curl -x socks5://127.0.0.1:1080 https://www.example.com

結果成功返回了一個示例,那麼說明我們的代理配置是沒有問題的,應該是使用的協議出了問題導致docker倉庫無法識別我們的證書。

查閱資料,繼續瞭解其代理過程,瞭解到Trojan客戶端實現的具體原理是向本地提供了一個基於SOCKS5協議的代理服務,應用程式的流量將會傳送到這個代理上,接著Trojan伺服器再將流量透過Trojan協議傳輸到目的地上。而Docker的代理配置中,我們配置了https和http協議的代理流量傳送地點,這可能是因為SOCKS5協議和http協議產生了一點衝突,導致證書不能被正確識別。為了解決這個問題,我們可以再加一層中介軟體,負責將https協議的流量轉換成SOCKS5協議的流量,就能正確處理https的請求。

5、安裝配置Privoxy

使用如下命令在centOS上安裝Privoxy

sudo yum install privoxy

接著配置/etc/privoxy/config這個檔案,將Privoxy連線到本地的SOCKS5代理。

forward-socks5   /               127.0.0.1:1080 .

然後啟動Privoxy

sudo systemctl start privoxy
sudo systemctl enable privoxy

Privoxy 預設會監聽本地的 8118 埠,這意味著你可以將應用程式的 HTTP/HTTPS 代理配置為 http://127.0.0.1:8118

接著我們需要再次更改daemon配置,修改為如下

{
  "proxies": {
      "http-proxy": "http://127.0.0.1:8118",
      "https-proxy": "http://127.0.0.1:8118",
      "no-proxy": "localhost,127.0.0.1"
  }
}

重啟docker

sudo systemctl restart docker

最終我們再執行docker run hello-world,成功了。

相關文章