banner
kanes

kanes

WSL2 中 `git pull` 失敗的 TLS 握手錯誤排查與解決

WSL2 中 git pull 失敗的 TLS 握手錯誤排查與解決#

在使用 WSL2 環境執行 git pull 操作時,可能遇到因 TLS/SSL 握手失敗導致的連接錯誤。常見的錯誤信息包括 gnutls_handshake() failed: The TLS connection was non-properly terminated.OpenSSL SSL_connect: SSL_ERROR_SYSCALL。此類問題通常與網絡代理、SSL 證書信任鏈或底層 TLS 庫相容性相關。


問題定位#

錯誤消息直接指示 TLS/SSL 握手過程異常終止。在深入排查前,建議進行基礎連通性與配置檢查:

  1. 系統時間同步: 透過 date -R 命令驗證 WSL2 系統時間是否與實際時間一致。時間不同步可能導致證書驗證失敗。
  2. 網絡可達性: 使用 ping your-repo-domain.com 確認目標代碼倉庫域名可解析且網絡可達。
  3. Git 代理配置: 執行 git config --global http.proxygit config --global https.proxy 檢查 Git 全局代理設置。如存在配置,可嘗試使用 git config --global --unset http.proxy 臨時移除。

若基礎檢查無異常,且問題依舊,則需進一步分析 TLS 握手過程。透過 curl -v 命令可獲取詳細的連接日誌:

curl -v https://your-repo-domain.com/path/to/repo.git/info/refs?service=git-upload-pack

curl -v 輸出中若包含 Uses proxy env variable https_proxy == 'http://X.X.X.X:YYYY',且代理連接成功 (CONNECT tunnel established, response 200),但最終因 OpenSSL SSL_connect: SSL_ERROR_SYSCALL 失敗,則高度指向代理對 TLS 流量的攔截。代理通常運行在 Windows 宿主機上,並透過其 IP 地址(例如 WSL2 的默認網關 IP)提供服務。此類代理進行 HTTPS 流量攔截時,會使用自身生成的 SSL 證書充當中間人,而 WSL2 默認不信任此證書。

例如,若證書頒發者顯示為非公共信任的機構(如 WR2),則進一步證實代理攔截是核心問題。


解決方案:信任代理根證書#

核心解決方案是使 WSL2 信任代理伺服器所使用的根證書。

步驟一:獲取代理根證書#

  1. 從 Windows 瀏覽器導出證書:
    • 在 Windows 宿主機瀏覽器中,訪問任意 HTTPS 網站(例如 https://www.baidu.com)。
    • 點擊地址欄左側的鎖圖標,查看證書信息
    • 在證書路徑或認證路徑中,查找由 ** 非公共信任機構(如 WR2)** 頒發的根證書。
    • 選中該證書,點擊 **“查看證書”,切換至“詳細信息”** 選項卡。
    • 點擊 **“複製到文件...”** 按鈕,選擇 “Base-64 編碼 X.509 (.CER)” 格式。
    • 將文件保存至 Windows 的下載文件夾,文件名示例:my_proxy_root.crt

步驟二:複製證書至 WSL2#

假設 Windows 用戶名為 YourWindowsUsername

cp "/mnt/c/Users/YourWindowsUsername/Downloads/my_proxy_root.crt" ~/

步驟三:將證書添加至 WSL2 信任存儲#

sudo cp ~/my_proxy_root.crt /usr/local/share/ca-certificates/my_proxy_root.crt
sudo update-ca-certificates

執行 update-ca-certificates 命令後,系統將更新其信任證書列表,並報告證書已成功添加。

步驟四:驗證並重試 Git 操作#

確認 WSL2 會話中代理環境變量已正確設置(例如 https_proxy)。必要時可手動設置:

# 驗證代理環境變量
echo $https_proxy

# 必要時手動設置
# export https_proxy='http://[代理IP]:[代理端口]'
# export http_proxy='http://[代理IP]:[代理端口]'
# export no_proxy='localhost,127.0.0.1,::1,[內部IP範圍]'

git pull

推薦替代方案:切換至 SSH 協議#

若 HTTPS 代理配置複雜或穩定性不足,SSH 協議是更簡潔、更可靠的解決方案。SSH 連接不依賴 HTTP/HTTPS 代理,從而規避了 SSL 攔截及證書信任問題。

  1. 生成 SSH 密鑰對:

    ssh-keygen -t ed25519 -C "user_email@example.com"
    

    接受默認路徑及空密碼短語(實現免密)。

  2. 配置公鑰至代碼托管平台:

    • 複製公鑰內容:cat ~/.ssh/id_ed25519.pub
    • 登錄目標代碼托管平台(如 GitLab、GitHub),在用戶設置中添加此公鑰。
  3. 測試 SSH 連接:

    ssh -T git@your-repo-domain.com
    

    首次連接將觸發主機指紋驗證提示。務必核對指紋(例如,諮詢管理員獲取官方指紋),確認無誤後輸入 yes 並回車。成功後,將顯示歡迎信息。

  4. 修改本地倉庫遠程 URL:

    進入本地倉庫目錄:

    git remote set-url origin git@your-repo-domain.com:your_group/your_repo.git
    
  5. 執行 git pull

    git pull
    

    此時,Git 將通過 SSH 協議拉取代碼,繞過 HTTPS 代理及證書信任問題。


此文由 Mix Space 同步更新至 xLog 原始鏈接為 https://blog.kanes.top/posts/default/97655532543870

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。