隆重推出 Sunlight,一個專為擴展性、易於操作和降低成本而打造的 CT 實作

Let’s Encrypt 很榮幸推出 Sunlight,這是一個全新的憑證透明度日誌實作,我們從頭開始打造,並考慮到現代 Web PKI 的機會和限制。我們與主導設計和實作的 Filippo Valsorda 合作,並納入了來自更廣泛的透明度日誌社群的回饋,包括 Google 的 Chrome 和 TrustFabric 團隊、Sigsum 專案以及其他 CT 日誌和監控營運商。他們的見解對於塑造專案的方向至關重要。
CT 在 Web PKI 中扮演著重要的角色,增強了監控和研究憑證頒發的能力。然而,隨著憑證數量的增加,CT 日誌的運作面臨著越來越多的挑戰。例如,Let’s Encrypt 每天發出超過四百萬張憑證,每張憑證都必須記錄在兩個獨立的 CT 日誌中。我們完善的「Oak」日誌目前擁有超過 7 億個條目,反映了這些挑戰的巨大規模。
在這篇文章中,我們將探討 Sunlight 背後的動機,以及其設計如何旨在提高 CT 生態系統的穩健性和多樣性,同時提高 Let’s Encrypt 日誌的可靠性和效能。
來自資料庫的瓶頸
自 2019 年以來,Let’s Encrypt 一直在執行公開 CT 日誌,並且我們在執行這些日誌方面獲得了豐富的營運經驗,但並非沒有問題。我們為「Oak」日誌部署的架構中最大的挑戰是資料儲存在關聯式資料庫中。我們透過將每年的資料分割成一個擁有自己資料庫的「分片」來擴展規模,然後將分片縮小為涵蓋六個月而不是整年。
將資料庫分割成越來越多的資料庫並非我們想要永遠持續做下去的事情,因為營運負擔和成本都會增加。目前 CT 日誌分片的儲存大小介於 5 到 10 TB 之間。對於單一資料庫來說,這個大小已經夠令人擔憂了:我們之前在 MySQL 中遇到 16TiB 的限制時,曾經有一個測試日誌失敗。
擴展讀取容量需要配備快速磁碟和大量 RAM 的大型資料庫執行個體,這並不便宜。我們有許多 CT 日誌因為客戶端嘗試讀取日誌中的所有資料而超載,進而導致資料庫超載的案例。當實施速率限制以防止超載時,客戶端被迫緩慢地爬取 API,從而降低了 CT 作為檢測錯誤頒發憑證的快速機制的效率。
提供瓦片
最初,Let’s Encrypt 只計劃建立一個新的 CT 日誌實作。然而,與 Filippo 的討論讓我們意識到,其他透明度系統已經改進了原始的憑證透明度設計,而且我們可以透過更改讀取路徑 API 來使我們的日誌更加穩健和可擴展。特別是,Go Checksum Database 的靈感來自憑證透明度,但使用更有效率的格式,將其資料發佈為一系列易於儲存和快取的瓦片。
憑證透明度日誌是一個二元樹,每個節點都包含其兩個子節點的雜湊值。「葉」層級包含日誌的實際條目:憑證,附加到樹的右側。樹的頂部經過數位簽署。這形成了一個稱為 Merkle 樹的密碼可驗證結構,可用於檢查憑證是否在樹中,以及該樹是否僅附加。
Sunlight 瓦片是每個包含 256 個元素的文件,可以是特定樹「高度」的雜湊值,也可以是葉層級的憑證(或預憑證)。Russ Cox 在他的部落格上對瓦片如何運作有很棒的解釋,或者您可以閱讀Sunlight 規格的相關章節。即使是我們目前執行的 CT 實作 Trillian,也使用類似這些瓦片的子樹系統作為其內部儲存。
與先前 CT API 中的動態端點不同,以瓦片形式提供樹不需要任何動態計算或請求處理,因此我們可以消除對 API 伺服器的需求。由於瓦片是靜態的,因此它們可以有效地快取,這與像 get-proof-by-hash 這樣的 CT API 不同,後者每個憑證都有不同的回應,因此沒有共享快取。葉瓦片也可以壓縮儲存,從而節省更多儲存空間!
以一系列靜態瓦片的形式公開日誌的想法是基於我們希望以水平且相對便宜的方式擴展讀取路徑。我們可以將瓦片直接公開在像 S3 這樣的雲端物件儲存中、使用快取 CDN,或者使用 Web 伺服器和檔案系統。
物件或檔案儲存易於取得、可以輕鬆擴展,而且成本遠低於雲端供應商的資料庫。這似乎是顯而易見的前進道路。事實上,我們在現有的 CT 日誌前面已經有一個以 S3 為後端的快取,這意味著我們目前正在儲存兩次資料。
執行更多日誌
瓦片 API 改善了讀取路徑,但我們也希望簡化寫入路徑的架構。使用 Trillian,我們執行一組節點以及 etcd,以進行領導者選舉,從而選擇哪個節點將處理寫入。這有點複雜,我們認為 CT 生態系統允許不同的權衡取捨。
關鍵的認知是,憑證透明度已經是一個分散式系統,客戶端會將憑證提交給多個日誌,並優雅地從任何不可用的日誌故障轉移到其他日誌。每個個別日誌的寫入路徑不需要高可用的領導者選舉系統。一個簡單的單節點寫入器可以滿足 CT 日誌 計畫要求的 99% 服務水準目標。
單節點 Sunlight 架構讓我可以透過相同的運算能力執行多個獨立的日誌。這提高了系統的整體穩健性,即使每個個別日誌的潛在正常運行時間較短。不再需要領導者選舉。我們使用簡單的比較和交換機制來儲存檢查點,並防止意外地同時執行兩個執行個體,這可能會導致分叉樹,但它的負擔遠小於領導者選舉。
不再有合併延遲
CT 的目標之一是限制提交至日誌的延遲時間。新增了一個稱為合併延遲的設計功能來支援這一點。當將憑證提交到日誌時,日誌可以立即傳回簽署的憑證時間戳記 (SCT),並承諾在日誌的最大合併延遲時間(通常為 24 小時)內將其納入日誌。雖然這似乎是為了不減慢頒發速度而做的良好權衡,但曾經發生多起事件和差點發生的事故,其中日誌在未合併憑證的情況下停止運作,未達到其最大合併延遲時間,並打破了這一承諾。
Sunlight 採用不同的方法,在批量處理並將憑證整合到日誌中時暫時保留提交的憑證,從而消除了合併延遲。雖然這會導致少許延遲增加,但我們認為這值得避免 CT 日誌更常見的故障案例之一。
它還允許我們將最終葉索引嵌入到我們的 SCT 擴展中,使 CT 更接近於直接客戶端驗證 Merkle 樹證明。該擴展還讓客戶端可以從新的基於靜態瓦片的 API 擷取日誌包含證明,而無需伺服器端查找表或資料庫。
光明的前景
今天發布 Sunlight 只是開始。我們發布了 Sunlight 的軟體和規格,並且 Sunlight CT 日誌正在運行。前往 sunlight.dev 尋找開始使用的資源。我們鼓勵 CA 開始測試提交到Let’s Encrypt 的新 Sunlight CT 日誌、讓 CT 監控器和稽核員新增支援以使用 Sunlight 日誌,以及讓 CT 計畫考慮信任在這個新架構上運行的日誌。我們希望 Sunlight 日誌在未來能被瀏覽器運行的 CT 計畫用於 SCT,讓 CA 可以依靠它們來滿足瀏覽器的 CT 日誌記錄要求。
到目前為止,我們已收到正面的回饋,例如「Google 的 TrustFabric 團隊(Trillian 的維護者)支持這個方向和 Sunlight 規格。我們一直在朝著相同的目標努力,為其他生態系統建立基於快取瓦片的日誌,並提供 無伺服器工具,並將其納入 Trillian 和 ctfe,同時新增對 Sunlight API 的支援。」
如果您對設計有任何回饋,請加入 ct-policy 郵寄清單或 transparency-dev Slack 上的 #sunlight 頻道(加入邀請)上的對話。
我們要感謝 Chrome 對 Sunlight 開發的支持,以及 Amazon Web Services 對我們 CT 日誌運作的持續支持。如果您的組織監控或重視 CT,請考慮提供財力支持。如需更多資訊,請瀏覽 https://www.abetterinternet.org/sponsor/ 或透過以下電子郵件聯絡我們:sponsor@abetterinternet.org。