首頁 / IT 趨勢洞察 / SSL 三層防護
技術洞察 / 網站資安 / 事件後 postmortem

企業 SSL 憑證自動續期失靈 8 天才發現:三層防護策略實戰

網站資安 · 2026 年 5 月 · 凱茂資訊技術團隊 · 閱讀時間 10 分鐘
分享: LINE 分享
快速回答:Let's Encrypt 自動續期可能「成功但實際失敗」——win-acme 把新 cert 裝進 IIS 但 cert ↔ private key 的 schannel metadata 沒設好,TLS handshake 立刻 reset。傳統依賴 Scheduled Task LastResult 沒人會定期看;Sentry 因為 HTTPS 壞了根本載不到;開發人員 hosts override 自己訪問本來就 https 失敗——三道警戒線同時失效,網站壞 8 天直到使用者體感到。修法是建三層防護:UptimeRobot 5 分鐘外部 HTTPS check + Hourly self-healing Scheduled Task + win-acme renewal.json 加 Script install plugin 0 秒延遲修 metadata。

事件時間線:4/19 遷移 → 4/27 renew → 5/5 才發現

  • 4/19:web server 從 nginx 切換到 IIS。原 nginx-era 的 scripts/post-renew.ps1 沒同步重寫,仍含 Restart-Service nginx 邏輯。Scheduled Task SSL-PostRenew 每天 06:00 跑,每天 exit 1 失敗,但沒人看 LastResult。
  • 4/27 08:32:Let's Encrypt 自動 renew,新 cert 進 LocalMachine\My,win-acme 用 IIS install plugin 把 cert 綁定到 IIS site binding。但 cert ↔ private key 的 schannel metadata(KeyProvInfo)沒設好——cert 安裝成功,private key 在 LocalMachine\Crypto\RSA 內,但 schannel TLS handshake 找不到對應 key file。
  • 4/27 之後 8 天:所有 HTTPS connection TLS handshake reset。Cloudflare cache 部分頁面繼續 serve(看起來像「偶爾壞」),origin 直連完全壞。
  • 5/5 18:42:使用者體感到網站進不去回報。19:30 修好——certutil -repairstore My <thumbprint> 重建 cert ↔ key metadata 關聯,schannel 立即生效,IIS 不需重啟。

為什麼 8 天才被發現?三道警戒線同時失效

事件後做 postmortem,列每一道應該攔下的機制:

  • 沒有外部 uptime monitoring。沒有任何 service 從外網每幾分鐘 ping 首頁。
  • Sentry 監測 SDK 載不到。HTTPS handshake 階段就 reset,瀏覽器根本沒下載 JS 檔案,error tracking SDK 從未啟動。「網站壞了 Sentry 會通知」這條假設依賴 SDK 至少能載入。
  • 開發人員 hosts override 直接訪問 origin。dev 機器把 www.kmau.com.tw 指向內網 IP,origin 沒裝對外的 cert,所以 dev 自己訪問本來就 https 失敗。「真壞」跟「平常 hosts 失敗」沒分別。
  • Cloudflare cache 部分 stale 繼續 serve。某些 user 看到舊頁面,不一定意識到網站已壞。Cache hit 反而蓋住了完全失效的事實。
  • Scheduled Task LastResult 純背景。SSL-PostRenew 每天 exit 1,但沒 alert pipeline,沒人定期看 schtasks。

每一道都是「正常情況下會發現」的機制,但都依賴前一道工作。一旦多道同時失效,故障靜默降級的時間 = MTTR。

Root cause:cert install ≠ schannel ready

真正 root cause 不是 nginx 殘留 script——那是觸發點,不是真原因。真原因是:

win-acme 的 IIS install plugin 把 cert 安裝到 LocalMachine\My,更新 IIS site binding,但沒可靠地設定 schannel 需要的 KeyProvInfo metadata(PROV_INFO 結構)

cert 跟 private key 在憑證儲存區看起來都在,但 schannel 找不到 cert 對應的 key file。對 IIS 來說 binding 看起來正常,對 schannel TLS 處理來說整個 handshake 用不出 key 來簽——直接 RST 連線。

certutil -repairstore 工具重建這個 metadata,把 cert thumbprint 跟 RSA key file 在 KeyProvInfo 上關聯起來。修完後 schannel 立即可用,不需要重啟 IIS

三層防護方案(彼此獨立、互為 backup)

Layer 1:外部 uptime monitoring(5 分鐘 alert)

用 UptimeRobot / Pingdom / Better Uptime 等外部服務每 5 分鐘對首頁做 HTTPS HEAD。任何 5xx / TLS handshake reset / connection refused 立即 email + 推播。

關鍵特性:服務在外網、不依賴自家網站任何元件——即使整個 origin 都炸了也照常 alert。免費版即可,不需要付費版的「cert expiry 提前 30 天通知」(HTTPS check 在 cert 到期當天 5 分鐘內也會 alert,本來就 cover)。

從 8 天 → 5 分鐘,這一道就把事件影響範圍縮 99.96%。

Layer 2:主機端 hourly self-healing

Scheduled Task 每小時跑 idempotent 腳本:

  1. LocalMachine\My 內最新(NotAfter 最遠)的 cert
  2. probe RSA private key accessibility(嘗試讀 KeyProvInfo)
  3. 不通就 certutil -repairstore My <thumbprint>
  4. netsh http show sslcert 驗證 IIS binding(避免 hairpin NAT 直接做 outbound HTTPS)
  5. 失敗就 POST 到 /api/error-report → Sentry alert

worst case 從 24 小時降到 1 小時。注意是 idempotent——成功狀態下重跑 100 次也不副作用。

Layer 3:ACME post-renew Script hook(root cause fix)

真正解決問題的不是 mitigation,是從根源消除 metadata 不一致。win-acme 的 renewal config 加 Script install plugin(與 IIS install plugin 並列):

{
  "InstallationPluginOptions": [
    { "Plugin": "iis", ... },
    { "Plugin": "script",
      "Script": "C:\\inetpub\\kmauWeb\\scripts\\post-renew.ps1",
      "ScriptParameters": "-Thumbprint {CertThumbprint}" }
  ]
}

renew 後 win-acme 會依序:(1)IIS plugin 安裝 cert + 更新 binding、(2)Script plugin 立刻跑 post-renew.ps1 修 metadata。0 秒延遲,不靠 hourly safety net。

這層才是 root fix——下次 cert renew 完成那一刻 metadata 就對了。Layer 1 跟 Layer 2 變成「萬一 Layer 3 也壞了」的多重保險。

Mitigation vs Root fix:差別在哪?

事件當天為了讓網站立刻好,跑 certutil -repairstore 是 mitigation——治了當下,沒解未來。下次 renew 還會壞。

真 root fix 是讓 renew 的那一刻就修好,不靠 hourly poll。差別:

方案修復延遲覆蓋未來類型
事件當下 certutil -repairstore0(只當下)Mitigation
Layer 2 hourly self-healing≤ 1hSafety net
Layer 3 win-acme Script hook0Root fix
Layer 1 UptimeRobot5 min(alert,不修)Detection

三層各司其職:Detection(你發現) + Self-healing(系統自修) + Root fix(從源頭不再壞)。任何一層失效,其他兩層仍 cover。

架構遷移後的審查 SOP

事件追到底,根因是「nginx → IIS 遷移時沒清舊架構的 Scheduled Task / script」。post-renew.ps1 從遷移那天起 16 天每天都失敗,但失敗對 happy-path(cert 沒 renew)沒影響。直到 4/27 renew 觸發新路徑才壞。

未來架構切換的審查 SOP:

  1. 列出舊架構所有 Scheduled Task / cron / hook script(一個都不能漏)
  2. 逐個評估:刪除 / 重寫 / 保留(含解釋為何保留)
  3. 砍 service 同時砍 file(如 C:\nginx\ 直接 rename 成 .deprecated.YYYYMMDD
  4. 切換後 prod 至少跑一次真實的 hot path(如手動 renew 一張 cert),不只看 happy path
  5. Postmortem 寫進 runbook,下次同類遷移直接照單檢查

給其他企業 IT 主管的 5 個 takeaway

重點摘要

  • 外部 uptime monitoring 不選——任何企業網站都該有。免費版每 5 分鐘 HTTPS check 就把 MTTR 從天級降到分級,沒理由不裝。
  • Sentry / 自家 monitoring 不能當唯一警戒線——它依賴你的網站還能載 JS。HTTPS handshake 階段壞了,Sentry 不會通知你。
  • 「自動化」不等於「不會壞」——LE 自動續期是過程自動化,不保證結果正確。每個自動化都要有 fail-safe + alert。
  • 架構遷移必審 legacy script——切換 web server / DB / framework 時,舊架構的 cron / Scheduled Task 通常被忘記。「砍 service 順手砍 script」是流程紀律。
  • Mitigation 是急救,不是治療——事件後一定要追到 root cause,否則下次同樣方式會再壞。

需要協助設計企業網站的 SSL / TLS 監測、ACME post-renew hook、或事件後 postmortem 流程?凱茂提供包含 Layer 1-3 完整方案的網站維運諮詢。

預約 30 分鐘免費網站維運架構諮詢 →

相關方案:資安與網路方案

凱茂資訊為您提供完整的規劃、建置與維運服務,歡迎諮詢。

瞭解我們的資安防護方案 → 預約諮詢
IT 技術電子報

覺得這篇文章有幫助?

訂閱電子報,每月收到最新 IT 趨勢與實務文章

專業顧問諮詢

讀完這篇文章,是否有更多問題?

凱茂資訊提供 30 分鐘免費架構評估,由專業顧問針對您的企業現況給出具體建議,不推銷、不強迫。

預約 30 分鐘免費諮詢 預約諮詢

✓ 免費諮詢,無義務購買 ✓ 中部地區可現場拜訪 ✓ 一般於 1 個工作天內回覆

凱茂
安裝凱茂資訊 App
快速存取報修、報價與 IT 資源
需要 IT 顧問協助?
30 分鐘免費評估 · 一般 1 個工作天內回覆