585 字
3 分鐘

cURL error 35 與 60 怎麼排查:先分清 TLS 握手失敗和 CA 驗證失敗

cURL error 35cURL error 60 常被一起處理,因為都在 HTTPS 連線附近出現;但它們不是同一種錯誤。把 error 60 的 CA 憑證作法直接套到 error 35,常會掩蓋真正的 TLS 握手、cipher、代理或伺服器設定問題。

直接答案是:error 35 先保留完整 TLS 錯誤並檢查握手環境;error 60 則確認 client 是否能驗證遠端憑證鏈。不要用 -k/關閉驗證當成正式修復。

兩個錯誤代表什麼#

curl 將 error 35 定義為 CURLE_SSL_CONNECT_ERROR,表示 SSL/TLS 連線過程失敗;完整訊息通常還會指出協商、憑證、代理或 OpenSSL 細節。error 60 是 CURLE_PEER_FAILED_VERIFICATION,表示遠端 SSL 憑證或 SSH fingerprint 未被判定為可信,且已與舊的 CURLE_SSL_CACERT 統一。

因此先保存完整錯誤文字,以及發生的 URL、PHP/curl/OpenSSL 版本、是否經公司 proxy、是否只有本機失敗。只記錄數字不足以定位問題。

error 60:從憑證鏈開始#

先在同一台機器以命令列重現:

Terminal window
curl -vI https://example.com
curl -V

若命令列成功、PHP 失敗,檢查 PHP 實際載入的 php.ini 與 CA 設定,而不是猜 Homebrew 的固定路徑:

Terminal window
php --ini
php -i | rg 'curl.cainfo|openssl.cafile'

本機開發若使用自簽憑證,應把開發 CA 安裝到正確的信任鏈,或只在受控的 client 設定 CA bundle。正式環境則先修正 server 是否送出完整 chain;不應要求所有 client 降低驗證。

error 35:確認握手的哪一段失敗#

error 35 沒有唯一修法。用 curl -v 看 TLS negotiation,並比對失敗主機與可用主機的協定、cipher、SNI、proxy 和憑證。若是 PHP only,再比對 CLI 與 PHP 各自連結的 curl/OpenSSL 版本與設定。更新套件可修已知問題,但不應在不知道錯誤內容時直接更換 OpenSSL major version。

驗證修復,不只重啟服務#

修正後,從發生錯誤的同一個執行環境測試目標 URL,確認沒有使用 --insecure 或停用 CURLOPT_SSL_VERIFYPEER。若應用程式走 Laravel Valet 或 container,也要在實際 PHP-FPM/container 內測試,因為它未必沿用你的 shell CA bundle。

把 error code 當成分類起點,而不是一串可直接搜尋的指令,才能避免把本機開發的 workaround 帶進正式環境。

參考資料:

curl:libcurl error codes

curl:SSL CA Certificates

cURL error 35 與 60 怎麼排查:先分清 TLS 握手失敗和 CA 驗證失敗
https://laplusda.com/posts/how-to-solve-curl-35-curl-60-errors/
作者
Zero
發佈於
2024-04-24
許可協議
CC BY-NC-SA 4.0
這篇文章有幫助嗎?

回報錯字、失效連結,或告訴我你想看的延伸主題。