多數網站完成SSL憑證安裝後,判斷「有沒有裝對」的方式通常只有一個。打開瀏覽器,看網址列有沒有跳出警告,只要沒跳,就當作這件事辦完了。這個判準其實沒有那麼可靠,瀏覽器不跳警告,代表的頂多是「這個瀏覽器、這台裝置、現在這一刻,沒有偵測到明顯問題」,不是「這張憑證裝對了」。
同一張憑證,在你自己的電腦上用慣用的瀏覽器打開完全正常,換成用手機的舊版瀏覽器、或某個第三方程式化用戶端去連,卻可能直接連不上或跳出警告。原因往往不是憑證過期,而是安裝當下就少放了一份檔案,或申請時漏列了一個網域,只是某些瀏覽器會自動補救,掩蓋了問題。憑證安裝夠不夠完整,通常牽涉兩件事:憑證鏈(伺服器憑證要跟中繼憑證、根憑證串成完整一條)夠不夠完整,以及涵蓋的網域(這張憑證實際能用在哪些網址上)對不對。這兩項出錯,肉眼在自己電腦上多半看不出來,得等到某個訪客或某支程式連不上才會被發現。
網站前面若掛了 Cloudflare 這類服務,瀏覽器看到的鎖,不代表源站主機也裝對了,這種情況常被忽略,卻是憑證安裝出包的常見死角。
安全鎖標示不會主動抓出憑證安裝的缺陷
安全鎖圖示能證明的東西其實很單一,這段連線目前使用加密傳輸,資料在使用者裝置和它連到的伺服器之間不是明碼傳送。它證明不了的東西,才是真正決定憑證裝得對不對的關鍵。它不會告訴你這張憑證的憑證鏈是不是完整,也不會告訴你憑證涵蓋的網域跟你實際在用的網址對不對得上。某些安裝缺陷,在特定瀏覽器版本下根本不會立刻跳出警告,要等使用者換一台裝置、換一個瀏覽器,甚至換成用程式化的用戶端去連,問題才會浮現。
這個落差在 2023 年被 Google 自己親口證實。Chrome 從第 117 版開始,把從 1990 年代 Netscape 早期版本就用到現在、將近 30 年的掛鎖圖示從網址列拿掉,換成一個看起來中性的「調整」圖示。Chromium 團隊在公告裡給的理由不是技術升級,而是使用者理解出了問題。公告引用的 Google 研究找了 1,880 位使用者做調查,結果 89% 的人誤解了掛鎖圖示實際代表的意思,多半把它解讀成「這個網站整體值得信任」,而不是它真正的意思「這段連線有加密」。連瀏覽器廠商自己都不再靠這個標示做安全判斷,網站經營者更不該把「打開網站沒跳警告」當成憑證裝對的證明。
換句話說,安全鎖能回答的問題只有一個,就是這一次連線有沒有走加密。它答不出「憑證鏈完不完整」「涵蓋的網域對不對」這兩個真正決定安裝品質的問題。「裝壞」具體長什麼樣子,才是真正該弄清楚的地方。
憑證鏈不完整與網域沒對齊是最常見的兩種安裝缺陷
「裝壞」聽起來抽象,實際上收斂下來,最常見的就是兩種樣態。第一種是憑證鏈不完整。一張完整的憑證鏈由伺服器憑證(開給你網域用的那張)、中繼憑證(憑證機構用來簽發伺服器憑證的中間層)、根憑證(瀏覽器與作業系統內建、預先信任的最上層)三層構成,任何一層在伺服器端缺漏,都算安裝不完整,即使伺服器憑證本身沒有問題。第二種是網域涵蓋不對。瀏覽器實際核對的欄位是 SAN(Subject Alternative Name,主體別名),不是很多人以為的 CN(Common Name,主體名稱)。CN 欄位早在 CA/Browser Forum 2012 年 7 月生效的第一版 Baseline Requirements 裡就被列為過時做法,現行主流瀏覽器只認 SAN,SAN 清單裡沒列到的網域,即使憑證本身完全有效,照樣會被判定為「憑證不符」。

這兩種缺陷成因不同,隱蔽性也不同。
憑證鏈缺中繼憑證,多數瀏覽器不會立刻跳警告
憑證商核發憑證時,通常只會直接給你網域本身那張伺服器憑證,中繼憑證要另外下載,安裝時得跟伺服器憑證一起放進主機設定裡,串成完整的鏈。只裝了伺服器憑證、沒把中繼憑證一起放上去,就是憑證鏈不完整。這是安裝環節最常見、也最容易被漏掉的一步,因為漏了之後,你自己在辦公室電腦打開網站,多數時候看起來完全正常。
會「看起來正常」不是巧合。部分瀏覽器內建一種叫 AIA fetching 的機制,會自動嘗試從公開來源把缺漏的中繼憑證補齊,讓連線照樣能建立。問題是不同瀏覽器、不同裝置、不同版本的用戶端,對這種缺漏的容忍度並不一致。在你慣用的桌機瀏覽器上測起來一切正常,換成行動裝置的瀏覽器、或是不具備 AIA fetching 機制的程式化用戶端(例如某支自動抓資料的爬蟲、或後端呼叫的 API),就可能直接連不上或跳出信任錯誤。SSL Labs(Qualys)在自家的評等說明文件 SSL Server Rating Guide 裡,就把憑證鏈結不完整列為會直接把整體評等封頂在 B 的項目之一,代表這在業界被視為一項嚴重、而非可以忽略的缺陷。
這也是為什麼裝好當下就該驗證,比等使用者回報才處理重要得多。憑證鏈不完整這種缺陷,在你自己這一關多半測不出來,得靠專門的工具去模擬不同用戶端的驗證行為,才會浮現。
憑證只涵蓋部分網域,SAN 沒把 www 或子網域列進去
另一種常見缺陷,出在申請憑證的當下,而不是安裝的手法。憑證裝上去了、憑證鏈也完整,但申請時 SAN 欄位只填了裸網域(例如 example.com),沒有一併把 www.example.com 或某個子網域列進去,結果訪客連到那個沒被列進 SAN 清單的網址時,瀏覽器照樣會跳出「憑證不符」的警告,即使憑證本身有效期還很長。
SAN 是憑證裡實際列出這張憑證涵蓋哪些網域或子網域的欄位,一張憑證可以同時列出多個 SAN,讓一張憑證同時保護裸網域、www、以及其他子網域。CN 欄位在這件事上早已退場。CA/Browser Forum 在 2011 年通過、2012 年 7 月生效的第一版 Baseline Requirements,就已經把 CN 欄位標記為過時做法,規定憑證裡若還留著 CN,內容也必須跟 SAN 清單裡的其中一筆一致;IETF 在 2011 年發布的 RFC 6125 更明確要求用戶端在憑證含有 SAN 延伸欄位時,一律以 SAN 為準比對主機名稱,CN 欄位應該被忽略,2023 年取代它的 RFC 9525 則直接規定伺服器身分只能寫在 SAN 裡。換句話說,現在主流瀏覽器根本不會拿 CN 欄位做網域比對,只看 SAN。
常見的疏漏就出在這裡:只申請了裸網域,忘了加 www;或者網站原本只有一個主網域,後來加開了新的子網域,卻沒回頭把憑證擴充進去,讓新的子網域一直用著不涵蓋自己的舊憑證。不需要額外安裝任何工具,瀏覽器本身內建的功能,就能先做第一層檢查。
不裝工具,用瀏覽器內建功能先看憑證核發者與到期日
最低成本的檢查方式,不需要跳到任何第三方網站,直接在瀏覽器裡點開連線資訊就能看到憑證的基本資料。以 Chrome 為例,做法是點網址列左側的圖示(依版本可能是掛鎖,也可能是前面提到的「調整」圖示),選擇連線安全,再點進憑證有效,就能查到憑證的核發單位與有效期限。整個過程不用 10 秒,適合當成裝完當下的第一眼檢查。

這一步能立刻抓到的問題很明確,憑證是不是已經過期、瀏覽器有沒有主動判定這個連線不安全。這兩種狀況一旦發生,瀏覽器通常會直接用醒目的警示頁面攔下來,不太需要靠使用者自己找。但這一步的侷限也同樣明確,它看不到完整的憑證鏈細節,更不知道其他瀏覽器、其他裝置、其他用戶端連過來時會拿到什麼結果。前面提過的兩種常見缺陷,憑證鏈缺中繼憑證、SAN 涵蓋不足,多半就是這一步查不出來的東西,瀏覽器內建的檢查介面,本來就沒有被設計成要模擬別的用戶端行為。
要真正知道自己的伺服器送出的是不是一條完整、涵蓋正確的憑證鏈,得換一種會真的模擬多種連線情境的工具。
SSL Labs 深度掃描揭露憑證鏈、SAN 與評等三個區塊
目前最普遍被推薦、內容也最詳盡的免費線上檢測工具,是 Qualys 維運的 SSL Server Test,也就是俗稱的 SSL Labs。使用方式很單純,在首頁輸入要檢測的網域,也可以勾選不公開測試紀錄,讓報告只有自己看得到,掃描通常需要一到兩分鐘。工具會對伺服器真正建立一次 TLS 連線,把憑證是否被信任、憑證鏈是否完整、到期日與剩餘天數、以及憑證涵蓋的 SAN 清單都整理成報告。
多數人拿到報告只看最上面那個從 A+ 到 F 的評等字母就結案,其實漏掉了報告裡真正有用的內容。評等之外,報告裡至少有三個區塊值得逐一看過:評等本身是怎麼算出來的、Certification Paths(憑證路徑)區塊實際呈現的信任鏈、以及 SAN 清單跟自己網站實際用到的網址對不對得上。

評等從 A+ 到 F,鏈結不完整最高只能拿到 B
「看到 A 或 A+ 才算過關,B 差不多就好」是一個常見誤解。SSL Labs 的評等機制內建一套封頂邏輯,只要伺服器踩到某些特定缺陷,不管其他設定(加密套件、通訊協定版本)調得多好,整體評等都會被直接封頂在某個上限之下,不會因為其他項目表現優異而拉高。憑證鏈不完整,正是 SSL Labs 評等說明文件裡列出的封頂條件之一,踩到它,評等最高只能拿到 B。
這代表一件很實用的事。看到報告給出 B 開頭甚至更低的評等,第一件該做的事不是急著去調整加密套件、關掉舊版通訊協定這些細節設定,而是直接去看報告裡有沒有標示憑證鏈的問題。反過來說,光憑一個字母評等,並不能直接判斷憑證裝得對不對,得往下看真正列出問題的區塊,也就是下面這個經常被忽略的 Certification Paths。
Certification Paths 區塊揭露瀏覽器實際採用的信任路徑
報告裡最直接回答「鏈結完不完整」的區塊,不是最上面的字母評等,而是往下捲才會看到的 Certification Paths。這個區塊會列出伺服器實際送出的憑證,以及對應到不同信任庫(不同作業系統、不同瀏覽器各自維護一套)分別建構出的驗證路徑,從伺服器憑證一路連到根憑證,缺漏哪一層會直接顯示出來。
如果某一條路徑顯示缺少中繼憑證,或路徑本身呈現中斷的狀態,就是一個明確訊號,該回頭去補上中繼憑證,重新套用到伺服器設定。比起只看一個籠統的字母評等,這個區塊等於是把別人的瀏覽器實際上怎麼驗證你的憑證直接攤開來看,比自己猜要精確得多。
SAN 清單決定憑證涵蓋的網域範圍,CN 欄位已經被瀏覽器忽略
報告的憑證資訊區塊,也會完整列出這張憑證的 Subject Alternative Names。核對方法很直接,把網站實際對外使用的每一個網域、子網域都列出來,一一比對是不是都在 SAN 清單裡,只要有一個網址不在清單裡,該網址被訪客打開時,就會被瀏覽器判定憑證不符,即使憑證整體是有效的。
這個核對動作,正好對照前面提過的那種安裝缺陷:申請當下只填了裸網域、漏了 www,或者加開新子網域後沒有回頭擴充憑證,SAN 清單裡照樣不會出現那個網域。CN 欄位在這裡已經沒有比對意義,前面已經說明過,主流瀏覽器只依 SAN 判斷,依據就是這份清單本身,不需要另外去猜。
線上工具解決的是單次、手動、一次測一個網域的檢查需求。如果手上管的網域不只一個,或者想把這套驗證排進固定週期自動跑,就會需要指令列工具。
openssl 與 testssl.sh,做批次驗證與自動化監控
線上工具一次只能測一個網域,還得手動打開瀏覽器點進去看報告;對自己管理主機、或者要驗證多個網域的人來說,指令列工具能寫進腳本、排進排程自動跑,一次驗證多個網域,這是網頁版做不到的事。這一節談的兩支工具,是進階或自動化情境下的選項,不是要取代前面提到的瀏覽器檢查與 SSL Labs,三者可以搭配使用。
openssl s_client 連線伺服器,列出憑證鏈與驗證代碼
openssl 幾乎是每一套 Linux 與 macOS 環境都內建的工具,不需要額外安裝。核心指令是 openssl s_client -connect <網域>:443 -servername <網域> -showcerts,其中 -showcerts 這個參數,依 OpenSSL 說明文件,會照伺服器送出的順序,列出交握過程中伺服器實際送出的每一張憑證,而不只是伺服器憑證本身,伺服器漏送的那一層也就不會出現在清單裡;-servername 則用於指定 SNI(Server Name Indication),確保同一台主機掛了多個網域時,回傳的是正確那一個網域的憑證。
跑完指令後,輸出裡的 Certificate chain 區塊會依序列出編號 0(伺服器憑證本身)、編號 1 以上(中繼憑證;根憑證多半內建在用戶端,伺服器通常不送),每一層都附上簽發者,一層一層照順序排下來,缺了哪一層一目了然。真正該盯著看的是輸出末尾的 Verify return code。這個代碼是 0,代表憑證鏈驗證通過;不是 0,就代表鏈結有問題,需要對照代碼實際的意義,回頭確認是缺了哪一層、還是根憑證不在信任清單裡。這種能直接讀出驗證結果、而不只是連得上或連不上的特性,是 openssl 比單純打開瀏覽器更精確的地方。

testssl.sh 額外核對 Apple、Microsoft、Mozilla 等多套信任庫
openssl 的驗證代碼雖然精確,但仍然要自己會讀懂代碼的意義,testssl.sh 補的正是這個環節。這是一支開源、以 Bash 撰寫的 TLS/SSL 檢測工具,依 testssl.sh 網站的說明,內建對多套信任庫的鏈結信任度比對,包括 Apple(作業系統)、Linux(作業系統)、Microsoft(作業系統)與 Mozilla(Firefox 瀏覽器)各自維護的版本,3.0 版起再加入 Java 的根憑證庫,跑完之後會直接告訴你這張憑證鏈在哪些信任庫下會被判定為可信、哪些不會,不用自己去查代碼對照表。
跟 openssl 相比,testssl.sh 的定位更接近一次看到多個用戶端環境下的結果,適合對單一網域做一次全面體檢,也適合用在成批網域清單上,排進排程做定期健檢。這正好呼應前面提過的重點。憑證鏈不完整這種缺陷,往往要換一個用戶端環境才會被抓出來,testssl.sh 一次就模擬了好幾套環境。
Cloudflare 等 CDN 前端的鎖不代表源站憑證正確
前面提到的瀏覽器檢查、SSL Labs、openssl、testssl.sh,驗的其實都是使用者實際連到的那個端點。如果網站前面掛了 Cloudflare 這類 CDN 或反向代理服務,使用者的瀏覽器實際連上的是 CDN 的邊緣節點,不是站主自己的主機。這代表 TLS 連線其實分成兩段,使用者到 CDN 是一段,CDN 到源站主機又是另外一段,而瀏覽器與多數線上檢測工具,預設只驗證得到第一段。邊緣節點的憑證裝得再漂亮,也不代表 CDN 到主機那一段是安全的,甚至是有加密的。
許多自架 WordPress 網站會搭配 Cloudflare 的免費方案。Cloudflare 的加密模式設定,決定的正是第二段(CDN 到源站)有沒有真的加密與驗證,不同模式差別相當大。

Flexible 模式讓瀏覽器端顯示安全,源站其實還在用 HTTP
最容易踩的一個設定,就是 Cloudflare 的 Flexible 模式。依 Cloudflare 說明文件,在這個模式下,使用者到 Cloudflare 之間走的是 HTTPS,看起來一切正常,網址列也會顯示安全;但 Cloudflare 到源站主機之間,走的其實只是 HTTP,沒有任何加密。也就是說,瀏覽器顯示的安全鎖,只反映了第一段連線,這段沒加密的流量代表 Cloudflare 到主機之間的資料,理論上仍有被窺視或竄改的風險。
這正是為什麼前面提到的所有驗證方法都測不出這個問題。它們驗的是使用者實際連到的那個端點,也就是 CDN 的邊緣節點,不是源站本身。源站有沒有裝憑證、裝得對不對,在 Flexible 模式下根本不在驗證範圍內。這個模式通常是給那些源站沒有安裝憑證、或主機環境不支援 TLS 的網站用的過渡選項,不是長期建議的設定。
Full(Strict)模式才會驗證源站憑證是否有效
正確的做法,是把加密模式升級到 Full,或更嚴格的 Full(Strict)。依 Cloudflare 說明文件,這兩個模式下,Cloudflare 到源站這一段同樣會走 HTTPS,其中 Full(Strict)還會額外驗證源站憑證,確認它由公開受信任的憑證機構或 Cloudflare 自家的 Origin CA 核發、沒有過期,而且 CN 或 SAN 對得上請求的主機名稱,等於把源站也一併納入驗證範圍,不再只驗第一段。
要切換到這個模式,有個前提得先做到。源站自己至少要先裝好一張有效憑證(公開受信任憑證機構核發的,或 Cloudflare 的 Origin CA 憑證),一般自簽憑證在 Strict 模式下不會被接受,若源站根本沒有憑證,或者憑證本身已經過期、驗證失敗,切換過去反而會連不上,訪客會直接看到 Cloudflare 的錯誤頁(源站憑證不符合要求時是 526 錯誤)。換句話說,前面章節談的所有驗證方法,在掛了 Cloudflare 這類服務的情況下,真正該拿去驗證的對象是源站主機本身,不是透過 Cloudflare 網域打開網站看到的那個結果,兩者測到的其實是不同的端點。
鏈結不全或網域沒對到,多半是憑證商或主機設定沒補齊
驗證做完、真的抓到問題之後,接下來要知道的是該往哪裡修,而不是卡在知道壞了但不知道找誰。前面提到的兩種安裝缺陷,憑證鏈不完整、SAN 涵蓋不足,分屬不同層次的問題,修法也不一樣。這裡談的是安裝當下就存在的缺陷,跟憑證過期、續期失敗這類原本裝對、後來到期沒處理的情境不同,屬於不同層次,不重複討論。
中繼憑證由憑證商提供,安裝時要與主要憑證一起上傳
憑證鏈不完整的修法相對單純。憑證商在核發憑證的同時,通常會一併提供中繼憑證檔案,可能是單獨的一份檔案,也可能已經包在憑證商提供的完整鏈結檔裡。多數主機控制台或憑證安裝介面,會把憑證跟憑證鏈、中繼憑證分成兩個欄位,安裝時兩個欄位都要貼上對應的內容,只貼主要憑證那一欄,就是前面提到、最常見的那種缺陷。
補上去之後,別憑感覺就當作解決了,回頭用前面任一種方法重新驗證一次。瀏覽器自己看不出來,但 SSL Labs 的 Certification Paths 區塊或 openssl 的 Verify return code,能明確告訴你鏈結是不是已經補完整。
SAN 涵蓋範圍在申請當下就決定,裝好後才發現要重新簽發
SAN 涵蓋不足的修法,比補中繼憑證麻煩得多。SAN 清單是憑證內容的一部分,在核發那一刻就已經寫死在憑證裡,不是伺服器端的設定值,沒辦法靠調整主機設定去擴充或覆蓋。發現漏了某個子網域、或漏了 www,代表得回頭跟憑證商申請一張涵蓋正確網域的新憑證,等於要重跑一次簽發流程,不像補中繼憑證那樣裝上去就好。
這也是為什麼裝完當下就該驗證這件事這麼重要。網站架構若還在成長期,加開新的子網域、換過網址結構之後,很容易忘記回頭檢查現有憑證還涵不涵蓋得到那些新增的網址。新憑證裝上後同樣要重新跑一次前面提到的驗證流程,確認 SAN 清單真的更新了。
憑證換過或搬過主機之後,同一套驗證流程要重跑一次
驗證不是裝好那天做一次就結束的事。任何會動到憑證本身、或動到連線路徑的異動,都值得重新跑一次前面整套流程,因為每一種異動都可能重新引入同樣的兩種缺陷。憑證商到期自動續期後,中繼憑證版本有時會跟著換掉,舊的鏈結設定不一定還適用;搬遷主機時最常見的疏漏,是忘了把中繼憑證一起搬過去,只搬了主要憑證;調整 CDN 或反向代理的加密模式設定之後,也該重新驗證源站端,而不是只看瀏覽器顯示的那個鎖。
這些異動的共同點,是它們都會在使用者完全沒察覺的情況下,重新製造出憑證鏈不完整或 SAN 涵蓋不足的老問題。第一次裝的時候驗證過一次,不代表半年後搬了主機、換了憑證商,同一套設定還原封不動。把「驗證」當成跟著每一次異動走的固定動作,而不是裝好那天做一次就結案的檢查項目,才不會等到訪客連不上才發現問題。
把這幾種情境放在一起看,能歸納出的原則其實很單純。安全鎖標示能確認的事很少,真正決定憑證裝得對不對的,是憑證鏈完不完整、SAN 涵蓋對不對這兩件事,而這兩件事都需要主動驗證才看得出來。不管是用瀏覽器內建的檢查、SSL Labs 的完整報告,還是排進排程的 openssl 與 testssl.sh,能做的都是同一件事,把「沒跳警告」換成「真的驗證過」。憑證裝完那一刻順手跑一次驗證,往後每一次換憑證或搬主機都養成同樣的習慣,遠比等到某個訪客或某支程式連不上才回頭查,要省事得多。
