憑證鏈是什麼,以及誰負責送出

一張網站憑證不是單獨成立的,它靠一條信任鏈往上追溯:你的憑證(leaf)→ 中繼憑證(intermediate)→ 根憑證(root)。驗證方必須能一路連到自己信任的根憑證,才會認可這張憑證。

關鍵在於各段的來源不同。根憑證預先內建在作業系統或瀏覽器的信任庫裡,不需要傳送;但中繼憑證不在裡面,必須由你的伺服器連同 leaf 一起送出。伺服器只送 leaf 的話,驗證方手上就缺了中間那一段,鏈接不起來。

客戶端 缺中繼憑證時的行為 使用者看到
桌面瀏覽器 多半會依 AIA 欄位自行下載,或沿用先前快取的中繼憑證 一切正常,完全無感
行動 App 與 WebView 通常不會自行補齊 連線失敗或憑證警告
curl、wget 不會 憑證驗證失敗,直接中斷
程式的 HTTP 客戶端(Python、Node.js、Java) 不會 擲出憑證驗證例外
監控與健康檢查工具 不會 持續告警,或誤判服務中斷
伺服器漏送中繼憑證時,各類客戶端的反應。差異就是症狀時好時壞的原因。

那為什麼有些裝置還是能正常連線?因為部分客戶端會自己想辦法補。下表是差異所在。

三種造成鏈不完整的情況

幾乎所有案例都來自這三種操作,而且都不會在當下報錯:

  1. 上傳了只含 leaf 的憑證檔 這是最常見的一種。憑證機構通常會給你數個檔案,其中一個只有你的憑證本身,另一個才是包含中繼憑證的完整鏈。以 Let's Encrypt 為例,cert.pem 只有 leaf,fullchain.pem 才是完整的——裝設定時挑錯檔案,服務會正常啟動,錯誤要等到特定客戶端連進來才浮現。
  2. 手動安裝時漏掉中繼憑證 在需要分別貼上憑證與中繼憑證的管理介面(許多主機商與負載平衡器都是這種設計),中繼憑證那一欄留空仍然可以儲存成功。介面不會提醒你少了什麼,因為從它的角度看,欄位本來就是選填的。
  3. 憑證機構更換了中繼憑證 憑證機構會輪替自己的中繼憑證。續簽後拿到的 leaf 可能由新的中繼憑證簽發,但伺服器上還放著舊的那一張——鏈一樣接不起來。這種特別難查,因為「上次好好的、這次就壞了」,而你可能什麼都沒改。

為什麼症狀會時好時壞

桌面瀏覽器有兩套補救機制。第一是憑證裡的 AIA 欄位(Authority Information Access),它記載了簽發者憑證的下載網址;瀏覽器發現鏈斷了,就照這個網址把中繼憑證抓下來自行補上。第二是快取——瀏覽器會保留先前在其他網站看過的中繼憑證,下次遇到就直接沿用。

這兩套機制加起來,讓問題在瀏覽器上幾乎隱形。更麻煩的是行為不一致:各家瀏覽器、各個版本對 AIA 抓取的支援程度不同,而快取的內容取決於使用者先前逛過什麼網站。所以同樣一台電腦、換個瀏覽器結果就不一樣,甚至同一個瀏覽器在不同人手上表現也不同。

反過來說,非瀏覽器的客戶端多半沒有這些機制。它們拿到什麼就驗什麼,缺了中繼憑證就直接失敗。所以最先回報問題的通常是 App、API 串接方,或是監控系統——而不是一般網頁使用者。

怎麼確認伺服器送出了什麼

最直接的方式是用 openssl s_client -connect 網域:443 -servername 網域 -showcerts 連上去,它會列出伺服器實際送出的所有憑證。輸出裡每一個 s:(subject)與 i:(issuer)配對就是鏈的一段——如果只看到一張憑證,那就是只送了 leaf。

正常的情況下,你會看到 leaf 的 issuer 等於下一張憑證的 subject,一路串接到根憑證或某張已知的中繼憑證為止。檢查要從外部發起,而且要對著使用者實際連到的位址——如果服務前面有 CDN,要確認你測的是哪一層,因為 CDN 節點與源站可能裝著不同的憑證。

三個層次的處理

確認問題存在之後,依序處理:

一、換成完整鏈的憑證檔

把設定指向包含中繼憑證的那個檔案(Let's Encrypt 是 fullchain.pem),或在管理介面把中繼憑證補進對應欄位。根憑證送不送都可以,多送一張只是多幾百位元組,不會造成錯誤。改完記得重新載入服務——檔案換了但服務沒 reload,等於沒改,Nginx 的憑證載入機制一文有詳細說明。

二、確認每一個終止 TLS 的位置都改到

源站、每個 CDN 節點、負載平衡器都各自持有憑證。只改了源站而 CDN 節點還是舊的,對使用者而言問題依然存在。這一點跟憑證到期的處理是同一個道理——憑證問題幾乎都出在「有些地方改了、有些沒有」。

三、把檢查納入續簽流程

憑證機構輪替中繼憑證時不會通知你。真正能防住的做法,是在每次續簽部署後自動確認鏈的完整性,而不是等使用者回報。這跟到期監控是同一套機制,只是多驗一個項目。

排查時該先確認的三件事

在動手改設定之前,這三項能省下大量時間:

  1. 確認問題確實是鏈不完整 憑證過期、網域不符、系統時間錯誤都會產生類似的錯誤訊息。先用 openssl 看清楚伺服器送出幾張憑證,再決定方向,避免改錯地方。
  2. 確認你檢查的是哪一層 有 CDN 的架構下,從外部測到的是邊緣節點的憑證。如果問題出在回源,那要另外測源站。搞錯層級會得到完全相反的結論。
  3. 確認失敗的客戶端是哪一類 如果只有部分行動裝置失敗、桌面全部正常,中繼憑證缺失的可能性很高。如果連桌面瀏覽器都失敗,那通常是別的問題——因為瀏覽器連鏈不完整都能自己補救。

小結

「我的瀏覽器打得開」在憑證問題上不是有效的驗證,因為瀏覽器會替你把缺失的中繼憑證補回來,而你的 App、API 客戶端與監控系統不會。判斷方式只有一個:檢查伺服器實際送出什麼,而不是某個客戶端最後有沒有連上。

這類錯誤的根源通常是手動部署——挑錯檔案、漏填欄位、或憑證機構換了中繼憑證而沒同步。如果不想每次都靠人工確認,我們的 SSL 憑證自動化平台在簽發後會把完整鏈直接部署到各節點,省掉手動貼上憑證這個最容易出錯的環節。

參考資料