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 握手過程異常終止。在深入排查前,建議進行基礎連通性與配置檢查:
- 系統時間同步: 透過
date -R
命令驗證 WSL2 系統時間是否與實際時間一致。時間不同步可能導致證書驗證失敗。 - 網絡可達性: 使用
ping your-repo-domain.com
確認目標代碼倉庫域名可解析且網絡可達。 - Git 代理配置: 執行
git config --global http.proxy
和git 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 信任代理伺服器所使用的根證書。
步驟一:獲取代理根證書#
- 從 Windows 瀏覽器導出證書:
- 在 Windows 宿主機瀏覽器中,訪問任意 HTTPS 網站(例如
https://www.baidu.com
)。 - 點擊地址欄左側的鎖圖標,查看證書信息。
- 在證書路徑或認證路徑中,查找由 ** 非公共信任機構(如
WR2
)** 頒發的根證書。 - 選中該證書,點擊 **“查看證書”,切換至“詳細信息”** 選項卡。
- 點擊 **“複製到文件...”** 按鈕,選擇 “Base-64 編碼 X.509 (.CER)” 格式。
- 將文件保存至 Windows 的下載文件夾,文件名示例:
my_proxy_root.crt
。
- 在 Windows 宿主機瀏覽器中,訪問任意 HTTPS 網站(例如
步驟二:複製證書至 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 攔截及證書信任問題。
-
生成 SSH 密鑰對:
ssh-keygen -t ed25519 -C "user_email@example.com"
接受默認路徑及空密碼短語(實現免密)。
-
配置公鑰至代碼托管平台:
- 複製公鑰內容:
cat ~/.ssh/id_ed25519.pub
。 - 登錄目標代碼托管平台(如 GitLab、GitHub),在用戶設置中添加此公鑰。
- 複製公鑰內容:
-
測試 SSH 連接:
ssh -T git@your-repo-domain.com
首次連接將觸發主機指紋驗證提示。務必核對指紋(例如,諮詢管理員獲取官方指紋),確認無誤後輸入
yes
並回車。成功後,將顯示歡迎信息。 -
修改本地倉庫遠程 URL:
進入本地倉庫目錄:
git remote set-url origin git@your-repo-domain.com:your_group/your_repo.git
-
執行
git pull
:git pull
此時,Git 將通過 SSH 協議拉取代碼,繞過 HTTPS 代理及證書信任問題。
此文由 Mix Space 同步更新至 xLog 原始鏈接為 https://blog.kanes.top/posts/default/97655532543870