這篇整理一台雲端主機上的服務要暫停一段時間、之後再恢復上線時要做的決定:暫停的範圍從小到大有只停服務、停止主機、終止主機但保留磁碟與網路設定、全部刪除再從 repo 重建,每一種保留哪些資源、恢復要多久、暫停期間付出什麼,以及怎麼拿保留的月費、重建的成本與暫停期間的漂移量來選;暫停時要先收窄的入口;暫停期間仍在計費的資源(磁碟、保留的 IP、備份、網路元件、網域與付費方案),以及仍然指向這台主機、或把這台主機的 IP 當成可信來源的外部設定(DNS 紀錄、CDN 的回源設定、監控的探測、別處的 IP 白名單)在主機不在時造成的結果。

恢復上線時要做的事,這篇整理恢復之前要重新確認的漂移、沒有事先記下基準時從哪裡開始比對,以及依元件之間的依賴排出的恢復順序與每一段完成的驗證方式。範圍是預期會恢復的暫停;服務要永久退場、對外的使用者與資料要另外處理時,見 10.7 分階段退場:停止新建、唯讀、靜態封存、關閉與公告期。主機在運行期間會改變的狀態與維護方式在 長期上線主機的維護項目:會累積的資料、定期讀的 log、對外入口的盤點、安全更新、會到期的設定與檢查間隔的推算,本篇沿用那一篇的四類狀態來源:會累積的資料、會老化的軟體、會漂移的入口、會到期與會改變的外部設定。本篇的「漂移」指這四類狀態在暫停期間的改變:暫停當下記下的值(公開 IP、憑證效期、待裝的更新數),到恢復時已經不是同一個值;它比 IaC 所說的 Drift(設定漂移)(宣告的設定與雲端實際狀態不一致)範圍更寬,IaC 的那一種設定漂移是其中的一種。各家業者停止與終止主機的計費規則在 機型與映像檔:CPU 架構、核心與記憶體、計費模式與作業系統〈停止主機時的計費〉。

暫停時保留的範圍:只停服務、停止主機、終止主機、全部刪除

暫停一個服務,等於決定哪些狀態保留到恢復的時候。保留的狀態越多,恢復越快,暫停期間要付的費用與要管的漂移也越多;刪除的狀態越多,暫停期間越乾淨,恢復時要重建的越多。

暫停的範圍保留停掉或刪除暫停期間的成本恢復的動作
只停服務主機、磁碟、IP、防火牆、DNS應用程式或反向代理的程序主機照常計費;主機繼續暴露在網路上,安全更新照樣要裝啟動程序
停止主機磁碟、網路與防火牆設定、DNS;公開 IP 的去留依業者與 IP 的種類而定,見表格下方主機的運算資源雲端業者的一般機型停止運算計費,磁碟繼續存在;停止的主機是否仍佔服務配額依業者而定從主控台或 API 啟動主機,再照〈恢復的順序〉更新之後才對外開放
終止主機、保留磁碟與網路設定開機磁碟(或它的備份)、虛擬網路與子網路、防火牆規則、保留的 IP、DNS主機本身、主機上的臨時公開 IP磁碟與保留的 IP 繼續存在;配額釋放用保留的磁碟或映像檔建新主機、重新附上 IP 或改 DNS
全部刪除、從 repo 重建repo 裡的部署腳本與設定、要保留的資料的備份、DNS 紀錄(可選)主機、磁碟、網路、防火牆、IP接近零(只剩備份的儲存與網域)重建網路與主機、跑部署腳本、還原資料、改 DNS

表裡的臨時公開 IP 指業者在建立主機時分配、主機終止(有些業者是停止)時收回的位址,保留的 IP 指另外建立、存在到被刪除為止的位址(Oracle Cloud 叫 reserved public IP,AWS 叫 Elastic IP)。停止主機時臨時公開 IP 的去留,各家不同:Oracle Cloud 的文件寫明停止時仍留在主機上、終止時才刪除(一台 A1 主機停止 2 小時再啟動,公開 IP 前後相同,見 Oracle Cloud 主機的暫停與恢復上線實測紀錄:暫停前的基準、收窄入口、停止主機、停止期間的計費與 Cloudflare 的回應、恢復上線的每一步與耗時,以及收尾時 DNS 紀錄與主機的刪除順序);AWS 的文件寫明停止時就收回、再啟動時分配一個新的,所以在 AWS 上沒有 Elastic IP 的主機,指向它的 DNS 紀錄要在停止之前就改掉(原因見〈暫停期間仍指向這台主機的外部設定〉)。其他業者的規則與欄位名稱見 網路:subnet、私有 IP、公開 IP 與防火牆規則〈公開 IP:網際網路上的入口〉;查不到的業者,當成停止時就會收回。「停止運算計費」是雲端業者一般機型的規則;按小時計費的 VPS,部分業者關機照常計費、要刪除實例才停止,要讀各家的計費說明確認。

選哪一種,比的是三個量:保留下來的資源每個月的費用乘上暫停的月數、刪除之後重建要花的成本,以及保留期間要管的漂移:

  • 保留的月費:依計費模式而不同。雲端業者的一般機型停止時,是磁碟加保留 IP 加網路元件的月費,在免費額度內(例如 Oracle Cloud 的 Always Free 區塊儲存)這一項是零;關機照常計費的 VPS 與特殊機型,停止的月費就是整台主機的月費,停止主機省不下任何錢,要省錢只能做快照之後刪除實例(相當於「終止主機、保留磁碟的備份」那一列)。
  • 重建的人力:人力時數要乘上自己的時間成本,才能跟月費比:重建一次要半天、半天的人力換算成某個金額時,保留的月費乘上月數超過那個金額之後,刪除比較划算;刪除之前先照 repo 驗證重建一次(下一項),這一次重建也算進刪除的成本。
  • repo 不完整的風險與事先的驗證:repo 不完整的風險是重建之後才發現少了設定:上線時在主機上手動調大了 nginx 的 body 上限、沒有收進 repo,半年後從 repo 重建,部署腳本跑完、冒煙測試(只確認服務起得來、首頁有回應的那一組最小檢查,涵蓋不到每一條路徑)全部通過,而上傳大檔案的請求回 413,要等使用者回報才發現。這個風險可以事先消除:刪除之前用一台新主機照 repo 重建一次,確認重建得出同樣的服務,做法見 乾淨機器驗證:repo 宣告了什麼、機器實際依賴什麼。免費額度已經用滿、或那種機型沒有容量而建不出第二台時,驗證改在額度以外的環境做(本機上同一個發行版的容器或 VM),驗得到的是部署腳本與主機上的設定,驗不到的是雲端那一層(機型、網路與防火牆規則),那一層改成把規則寫進 repo 或匯出存檔。重建一次實際要花多久,要量過才算數,估計的時間跟實測常差很多,見 Disaster recovery 策略〈Restore 驗證的三個層次〉。
  • 保留期間的漂移:保留的主機在暫停期間沒有安裝任何更新,暫停越久,恢復時要補的更新越多;憑證、網域、token 可能到期;免費額度的主機可能被業者回收(Oracle Cloud 的文件寫了判定閒置的使用率門檻,沒有寫停止中的主機算不算閒置,也沒有寫回收是停止還是刪除)。

恢復時能接受等多久是另一個限制,也就是這次暫停的 RTO(復原時間目標,見 RTO):重建一次的時間超過它時,不論月費多少都不能選刪除。暫停多久還不知道時(不確定會不會回來),月費乘上月數等於重建成本的那一個月,就是重新評估要不要改成刪除的時間點。由這三個量與這個限制,四種範圍各自適合的情形如下:

  • 只停服務:例如上游的第三方 API 停用幾天、要擋住寫入做資料修正。主機照常計費也照常暴露,長期上線主機的維護項目:會累積的資料、定期讀的 log、對外入口的盤點、安全更新、會到期的設定與檢查間隔的推算 列的每一項(安全更新、入口、會累積的資料)在暫停期間照樣要做,省下的只有服務本身的資源,所以適合恢復要立刻完成、暫停期短到不值得處理主機的情形。
  • 停止主機:例如一個 side project 要休眠幾個月。主機不執行,不會被攻擊、不會累積 log,而磁碟還在,恢復只要開機。保留的月費在免費額度內是零時,這是代價最低的選擇;但免費額度的主機可能在暫停期間被業者回收,而回收時是停止還是刪除沒有寫明,所以在免費額度上停止主機,同樣要先滿足全部刪除的前提:repo 重建得出同樣的服務、資料的備份放在這台主機以外。保留的月費不是零時,月費乘上暫停的月數會在某個時間點超過重建一次的成本,超過之後改成刪除比較划算。免費試用期要結束、要決定主機的去留時,各家業者在試用結束後怎麼處置帳號與資源,見 雲端免費額度與小型主機的收費比較:試用金與固定額度、計費單位、區域限制、試用結束後的處置、出站流量與查價項目〈試用結束後帳號與資源的處置〉。
  • 終止主機但保留磁碟與網路設定:例如要把主機從 x86 換到 ARM 的機型,或把配額讓給另一台主機。恢復要重建主機,所以比停止慢,而網路與防火牆的設定不必重做。在容量常常不足的機型上(Oracle Cloud 的 A1 常回報 Out of host capacity),終止之後不一定建得回同樣的主機,這時停止比終止安全。
  • 全部刪除、從 repo 重建:例如確定之後會重建、但中間有好幾個月用不到。暫停期間幾乎沒有成本,也沒有要管的漂移,恢復時每一項都要重建,前提是部署腳本、設定與資料的備份都在 repo 或備份裡。暫停期長到保留的月費超過重建成本時也選它。不確定會不會回來、而服務有外部的使用者或被別處引用時,這已經是退場,網域的保管人與付款來源也要先確定,否則網域到期後可能被別人註冊,處理方式照 10.7 的退場階段與 10.6 命名空間與網域的處置:續約、名稱保留與回收、懸空 DNS。

暫停時先收窄的入口

停止主機時,雲端防火牆與主機防火牆的規則、DNS 紀錄都保留下來;主機在恢復時一開機,enabled 的服務自己起來,防火牆照舊放行,CDN 照舊把請求送進來,這台缺了暫停期間全部更新的主機,在恢復的第一分鐘就在接受外部連線。要讓恢復時有機會先更新再開放,入口要在暫停的時候就收窄:

  • 雲端防火牆收回對外連接埠的放行,只留管理者 IP 連 SSH(或 bastion),恢復時在主機更新完之後再加回來。
  • DNS 紀錄改指到維護頁(下面〈暫停期間仍指向這台主機的外部設定〉寫做法),或刪除紀錄。

停止主機時,這兩項都要做;在停止時就收回 IP 的業者(AWS 沒有 Elastic IP 的主機),DNS 那一項要在停止之前做。只停服務時主機一直開著、自動更新照常執行,收窄的理由不成立,DNS 那一項只在要讓訪客看到維護頁時做。終止主機時,IP 是保留的就照下面〈暫停期間仍指向這台主機的外部設定〉裡「IP 還在自己手上」那一種處理;臨時公開 IP 被收回、或全部刪除時,DNS 紀錄一定要改(原因見同一節懸空 DNS 那一段),防火牆規則保不保留看要不要沿用。

暫停期間仍在計費的資源

主機停止或終止之後,帳單上可能還留著幾類跟主機分開計費的資源。它們在建立時跟主機一起出現,暫停時卻要各自處理,沒有處理的就成了 孤兒資源,也就是 計費模式理解〈隱藏成本:帳單上的意外〉所說的被遺忘的資源:

免費方案的額度同樣要算進來:免費的區塊儲存額度是開機磁碟與資料磁碟合計,保留下來的磁碟也佔著它,合計的範圍見 Oracle Cloud 的帳號結構與 home region:tenancy、Always Free 的範圍與主控台登入欄位〈Always Free 的額度與它綁在 home region 上的範圍〉。

在作業系統裡下 shutdown 關機,雲端業者那一端記錄的主機狀態不一定跟著變成停止;Oracle Cloud 官方文件〈Resource Billing for Stopped Instances〉寫明這樣關機不會停止計費,要從主控台或 API 停止主機。

要確認暫停期間不會被扣費,得在暫停前把這幾類逐項列出來、每一項決定保留或刪除:主控台的主機清單只列主機,看不到這些分開計費的資源;成本分析與預算告警看得到它們,但要等業者的計費資料延遲之後才出現,三家的延遲與出處整理在 租用雲端主機之前的費用規劃:費用訊號的延遲、停止之前的最大超支、扣款的信用卡額度、配額與預算門檻的計算,以及停損停到哪一層〈費用訊號的延遲:從資源建立到扣款〉。

暫停期間仍指向這台主機的外部設定

主機停止或刪除之後,指向它的外部設定不會自己改變。它們在暫停期間造成的結果,看停止或終止之後那個公開 IP 還在不在自己手上:

  • IP 還在自己手上(只停服務、停止主機而業者停止時不收回 IP、IP 是保留的):DNS 與 CDN 照樣把請求送到這個位址,請求得到的是連線被拒或逾時(保留的 IP 沒有附在任何主機上時,封包沒有對象可以回應)。經過 Cloudflare 時,訪客看到的是 Cloudflare 的錯誤頁,依源站的反應分成 521(源站拒絕連線,例如主機開著而 nginx 停了)與 522(連線逾時,例如主機停止、封包沒有回應)。Oracle Cloud 的一次演練量到兩種情形都是 522:把只放行 Cloudflare 的 NSG 從主機的網卡拿掉(主機還開著,封包被丟掉而沒有回應),以及主機停止之後,經 Cloudflare 的請求都在約 20 秒後回 522;521 那一種(主機開著、程序沒有在聽)這次沒有量到。演練的每一步與耗時見 Oracle Cloud 主機的暫停與恢復上線實測紀錄:暫停前的基準、收窄入口、停止主機、停止期間的計費與 Cloudflare 的回應、恢復上線的每一步與耗時,以及收尾時 DNS 紀錄與主機的刪除順序。外部的監控探測在這段時間會連續失敗,要讓它們在暫停期間不發告警(Alert Silence(告警靜音)),暫停期間的告警才不會被當成雜訊,恢復之後出現的真告警也不會跟著被忽略。暫停期長達幾個月時,一個結束時間設得很遠的靜音容易被遺忘,比較清楚的做法是暫停期間停用那幾個探測,恢復時再啟用。
  • IP 已經還給業者(停止主機而業者停止時收回 IP、終止主機時收回了臨時公開 IP、刪除了保留的 IP):雲端業者會把收回的 IP 分配給別的客戶。DNS 紀錄還指著這個 IP 時,網域的流量會送到一台陌生人的主機,訪客看到的是對方的內容,對方的主機也收到原本送往這個網域的請求。對方控制了 DNS 指向的那台主機,就能通過 HTTP 驗證(ACME 的 HTTP-01),替這個網域申請到有效的憑證,所以直連 HTTPS 的訪客一樣會連到對方的內容、把 cookie 送過去。要讓對方較難申請到,網域的 CAA 紀錄用 issue 只列自己用的 CA(有 issue 紀錄時,沒列在裡面的 CA 不得簽發;accounturi 與 validationmethods 只約束它們所在那一筆 issue 的 CA),再用 accounturi 限定自己的 ACME 帳號,或用 validationmethods 限定 dns-01(兩個參數的寫法見 Let’s Encrypt 的 CAA 文件;CA 要認得這兩個參數才會照它執行,文件沒有逐一寫明各家 CA 的支援)。設了之後,恢復時有兩個條件要成立:accounturi 綁的是 ACME 帳號,重建主機時要沿用同一個帳號(帳號的金鑰跟其他機密一起備份),新裝的客戶端註冊的新帳號申請不到;validationmethods 要包含續期實際用的驗證方式,只留 dns-01 時 HTTP 驗證一定失敗。網域經過 Cloudflare 而且開著 Universal SSL 時,使用者一加任何 CAA 紀錄,Cloudflare 就自動補上它用的幾家 CA 的 issue 紀錄,其中包括不帶參數的 letsencrypt.org(Cloudflare 的 CAA 文件);這些紀錄在主控台上看不到,要用 dig CAA <網域> 查。同一家 CA 只要有一筆 issue 符合就准許簽發,所以在這種網域上,accounturi 與 validationmethods 限制不了 Let’s Encrypt,防護只剩釋放 IP 之前先改 DNS。這是懸空 DNS(dangling DNS)的成因,處置是在釋放 IP 之前,先刪掉或改掉指向它的紀錄;子網域被接管的情形與處置見 10.6 的〈懸空 DNS 與子網域接管〉。

方向相反的設定也會留下來:這台主機的公開 IP 可能被寫進別處的放行清單,例如第三方 API 或付款服務的 IP 白名單、另一台主機或資料庫的防火牆、郵件中繼的允許來源。IP 還給業者之後,拿到這個 IP 的人就繼承了這些放行。所以 IP 釋放之前,這些設定要一併移除;恢復時拿到新的 IP,它們要改成新的值。

CDN 的回源設定與 DNS 紀錄在 Cloudflare 上是同一筆資料:經過 Cloudflare 的網域,CDN 回源的位址就是 proxied DNS 紀錄的值。要讓訪客在暫停期間看到說明頁、而不是錯誤頁時,常見的做法是把紀錄改指到一個靜態的維護頁(CDN 業者的 Workers、Pages 這類服務,或另一台主機),恢復時再改回來。

恢復上線前要重新確認的漂移

主機或服務在暫停期間沒有執行,而它依賴的設定在主機外面照樣改變。暫停的人在暫停當下就知道哪些項目會漂移,所以暫停前把要確認的項目、確認的指令與暫停當下的值記下來(例如當時的公開 IP、管理者 IP、憑證效期),恢復時才有比對的基準。各項的狀態與數字可以交給檢查腳本的結果檔記:暫停前跑一次維護的檢查、恢復後再跑一次,報告會印出兩次之間的差異,做法見 主機維護清單寫成 TOML:JSON、YAML、TOML 的取捨、TOML 1.0 與 1.1 的版本差異、清單的欄位設計與只讀檢查腳本〈只讀檢查腳本的白名單、輸出、exit code 與結果檔〉,結果檔依階段(--phase)分開存、跟同一個階段的前一次比對的程式碼與它的已知限制在 只讀檢查腳本 host-check.py 的原始碼與逐段說明:選項的切分與各工具的白名單規則、清單的載入與驗證、指令的執行、各項檢查、路徑與時間的量測、結果檔與命令列,以及這一版的已知限制〈結果檔的讀寫與跟前一次的差異〉;IP 與憑證效期這類不是數字的值不在結果檔裡,照樣要另外記。依維護那一篇的四類狀態來源,再加上雲端業者那一端只在重建時才會碰到的狀態(從「會到期與會改變的外部設定」拆出閒置回收,加上機型容量與映像檔版本),恢復前要比對的對象如下:

狀態來源暫停期間發生的改變恢復前要比對的對象與基準
會累積的資料停止主機以上的範圍沒有新的寫入;只停服務時,系統的 log 與套件快取照常累積;從備份還原時,還原的是備份那一刻的資料資料的時間點跟預期的一致、資料完整(資料庫的完整性檢查、筆數或 checksum 跟備份時一致);還原後資料庫的檔案權限與 SELinux 標籤(強制存取控制 依標籤判斷存取)跟暫停前一致
會老化的軟體停止的主機沒有安裝任何更新;暫停越久,恢復時已知漏洞越多待裝的安全更新數量與是否需要重開機;或用的映像檔是不是最新版。套件庫鎖在固定版本的發行版(Amazon Linux 2023),待裝數量是零不代表沒有新的修補,要先查有沒有新的套件庫版本;發行版過了 EOL 時待裝數量永遠是零(見維護那篇的〈會老化的軟體:各條更新管道與更新後的重開機〉);發行版以外的管道(容器映像檔、應用程式、自己建置的程式)各自另查
會漂移的入口主機停止期間,主機自己不會改動防火牆;有雲端帳號權限的人仍可能在主控台改規則;恢復時的重建或更新可能帶進新的接聽程式主機上的接聽程式與各層的放行範圍,跟暫停前的清單一致(量法見維護那篇的〈對外入口:主機上的接聽程式與每一層防火牆的放行範圍〉;防火牆規則由 Terraform 建立時,terraform plan 看得到既有規則被改、看不到主控台另外新增的規則,範圍見多台主機那一篇的〈清單裡要到主控台確認的項目與 terraform plan 的比對範圍〉)
會到期與會改變的外部設定憑證、網域註冊、token、CLI 的登入可能到期;管理者的 IP 與 CDN 的位址段可能改變;停止再啟動或重建的主機可能拿到新的公開 IP憑證效期與續期方式;網域的效期與自動續約;CLI 能否登入;管理者 IP 與 CDN 位址段跟放行規則一致;DNS 紀錄、別處的 IP 白名單與寫死 IP 的設定(防火牆、監控、文件)指向現在的公開 IP
雲端業者那一端的狀態免費額度的主機可能被回收;重建時同一種機型可能沒有容量;映像檔有新版本主機的狀態與配額;同一種機型在原區域有沒有容量;映像檔的版本

資料完整那一格的完整驗證(資料完整性、服務可用性、恢復時間的量測三層)見 Disaster recovery 策略〈Restore 驗證的三個層次〉。

主機不是照計畫暫停的時候(被業者閒置回收、試用結束被停用、管理者離職而沒有交接),手上沒有暫停當下記下的值。這時比對的基準改從三個地方取:repo 裡的部署腳本與設定(應該有的狀態)、DNS 與 CDN 目前的設定值(外面現在指向哪裡),以及雲端主控台上的資源清單(還剩下哪些資源、哪些已經不在)。三者對不起來的地方,就是要先處理的項目。repo 不存在時(前任沒有留下),基準只剩後兩個,而且只看得到外面現在的樣子、看不到應該有的狀態;這時先從主機萃取一份設定收進 repo(萃取的項目見維護那篇的〈接手或第一次盤點一台已經上線的主機〉),再開始比對。Oracle Cloud 上一台 A1 主機被閒置回收之後,停止與刪除兩種情形各自留下的資源,與照原樣重建的腳本,見 Oracle Cloud 私有子網路 Ubuntu 主機的實測紀錄:套件來源的出站(NAT gateway、路由與 NSG)、序列主控台的連線,以及被回收之後的重建〈被回收之後的重建:怎麼發現、留下與消失的資源、重建腳本〉。

恢復的順序:依元件之間的依賴排列

恢復時的順序由兩個依賴決定:每一段要用到前一段的產出,以及對外開放之前主機要先處在安全的狀態。後一個依賴成立的前提,是暫停時已經照〈暫停時先收窄的入口〉收窄了入口;沒有收窄時,主機一開機就對外開放,恢復之前要先在雲端防火牆收回對外的放行,或改成用最新的映像檔重建。照這兩個依賴,恢復分成四段,每一段的產出是下一段的前提:

  • 主機與網路就緒:啟動或重建主機、確認公開 IP、確認管理者 IP 在放行規則裡。這一段的產出是管理者連得進主機,後面每一段都要登入主機。
  • 主機內部就緒:裝安全更新(套件庫鎖在固定版本時先換套件庫的版本,見上面漂移表會老化的軟體那一列)、需要時重開機、跑部署腳本、還原資料並驗證資料完整,再在主機上做只對 loopback 的冒煙測試(服務在聽、回應正確)。應用程式自己的更新(CMS 的核心與外掛)也在這一段做:這時防火牆只放行 SSH,用應用程式的命令列工具(WordPress 的 wp-cli)更新,或經由 SSH 通道連到管理後台(WordPress 會轉址到 siteurl 設定的網域,所以要在本機的 hosts 檔把網域指到 127.0.0.1、通道接在 443;從 WordPress 的轉址行為推論,沒有實測);先開放 443 再從瀏覽器進後台更新,順序就倒過來了。容器映像檔的重新拉取、自己建置的程式跑漏洞掃描並重新建置,也在這一段做(各條管道見維護那篇〈會老化的軟體:各條更新管道與更新後的重開機〉)。這一段的產出是一台已經更新、服務在跑的主機;它是對外開放的前提,因為一台缺了幾週安全更新的主機,在更新裝好之前就接受外部連線,等於把已知漏洞直接放到網路上。恢復時間有壓力、或暫停期長到要補的更新很多時,另一個做法是用最新的映像檔重建,建好時已經是新版本,換到的是省下裝更新與重開機的時間,前提是要能從 repo 完整重建。
  • 對外入口開放:雲端防火牆與主機防火牆放行對外的連接埠,CDN 的位址段更新到最新,並從外面直連主機(繞過 CDN)確認入口只放行該放行的來源。這一段的產出是 CDN 連得到源站,所以排在 DNS 指回之前:DNS 先指回來的話,CDN 回源會失敗,訪客在這段時間看到錯誤頁。部署還沒完成、源站回 404 時(例如 nginx 的預設站),副檔名在 Cloudflare 預設快取清單裡的靜態檔,404 會被快取 3 分鐘;HTML 與 JSON 預設不快取,5xx 也不快取(Cloudflare 預設快取行為的文件)。
  • 流量導回:DNS 紀錄指回這台主機(或從維護頁改回來)、CDN 的設定還原,經過 CDN 從外面驗證網站與寫入端點。外部驗證要經過 CDN 才代表訪客看到的結果,所以排在 DNS 指回之後;監控的探測在驗證通過之後才恢復,否則恢復過程本身會觸發一串告警。

憑證的續期要排在它的驗證方式需要的那一段之後(自動續期的協定見 ACME Automation);網域設了 CAA 時,續期用的帳號與驗證方式要在 CAA 允許的範圍內(上面〈暫停期間仍指向這台主機的外部設定〉的 CAA 那一段):

  • 用 HTTP 驗證(ACME 的 HTTP-01):CA 依網域的 DNS 連到主機的 80 埠,所以續期要等 DNS 指回這台主機、而且 CA 的連線放得進來之後才做,落在流量導回那一段、DNS 指回之後。源站只放行 CDN 位址段時,CA 的請求要經過 CDN 才送得到源站;DNS 指回之前續期,CA 連到的是維護頁或舊的位址,續期會失敗。
  • 憑證在暫停期間已經過期、又用 HTTP 驗證,前面有 CDN:CDN 回源驗證源站憑證時(Cloudflare 的 Full (strict)),DNS 指回到續期完成之間,CDN 拒絕這張過期的憑證,訪客看到錯誤頁;驗證請求在 CDN 或源站被轉成 HTTPS 時(Cloudflare 的 Always Use HTTPS,或源站 80 埠回 301),CA 跟著轉到 HTTPS、經 CDN 回源,同樣在 CDN 到源站這一段被擋下,續期失敗(CA 自己跟著轉址時不驗證憑證,依 Let’s Encrypt 驗證方式的文件,失敗發生在 CDN 到源站這一段)。SSL 模式是 Full 時這一段不驗證,續期會成功。會失敗的這種情形,這一次續期改用 DNS 驗證,在主機內部就緒那一段先換好憑證。
  • 憑證已經過期、用 HTTP 驗證,前面沒有 CDN:CA 直接連到 80 埠,不受過期的憑證影響,續期照常在 DNS 指回之後做;從 DNS 指回到續期完成之間,直連的訪客看到憑證過期的錯誤,要縮短這段時間,就在恢復前先把 DNS 的 TTL 調低,或改用 DNS 驗證在主機內部就緒那一段先換好。
  • 用 DNS 驗證(DNS-01):續期要的是 DNS 業者的 API token,在主機內部就緒那一段就可以做,而那個 token 本身也是會到期的設定。
  • CDN 業者發給源站用、效期很長的憑證(Cloudflare 的 Origin CA 這類):不必依 DNS 排續期的時機,恢復時查它的效期就好。
  • 源站用的是只給 CDN 驗的自簽憑證、CDN 又不驗證源站憑證:過期不會讓連線失敗,恢復時仍要記下它的效期。

每一段完成的驗證寫成可以重複執行的指令(ss -lntup 的接聽清單、loopback 的 curl、從外面的 curl、DNS 查詢的結果),恢復就變成依序執行這些指令並確認每一段的結果,而不是依靠操作的人記得哪些地方要看。