Let's Encrypt 自 2019 年起開始運作憑證透明度(CT)日誌,作為我們致力於維持網頁 PKI 生態系統健康的承諾之一。CT 日誌已成為加密網頁的重要基礎設施 1,但其在高度信任層級下的操作具有眾所皆知的困難:目前只有 6 個組織運作被認為是「合格」的日誌。2

我們的 Oak 日誌是唯一完全在開放原始碼堆疊上運作的合格 CT 日誌 3。為了降低其他組織加入 CT 生態系統的門檻,我們想介紹一下最近 Oak 的一些變更,這些變更可能對任何計畫基於 Google 的 Trillian 和 MariaDB 來啟動日誌的人有所幫助。

  • Trillian 在 MariaDB 之上的磁碟 I/O 工作負載,可以透過前端速率限制輕鬆調解,並且

  • 將每個新的年度 CT 日誌分割成各自的 Trillian/MariaDB 堆疊是值得的。

這篇文章將更新先前文章 Let’s Encrypt 如何運作 CT 日誌中的部分資訊。

在保持開放原始碼的同時發展 Oak

Oak 在免費且開放原始碼的堆疊上執行:Google 的 Trillian 資料儲存,由 MariaDB 支援,透過 Amazon 的關聯式資料庫服務(RDS)在 Amazon Web Services(AWS)上執行。據我們所知,Oak 是唯一沒有封閉原始碼組件的受信任 CT 日誌 3

Open Source Stack

開放原始碼堆疊

其他 Trillian 的運營商選擇使用不同的資料庫來區分資料,但提供的 MySQL 相容資料儲存已成功跟上 Let's Encrypt 的 CT 日誌量(目前每月超過 400 GB)。在 MariaDB 之上擴展 Oak 的故事對於任何關聯式資料庫來說都很典型,儘管效能要求非常嚴格。

維持 Oak 的合格性

憑證透明度日誌運營商遵循的政策要求不得有重大停機時間,此外還有更絕對且困難的要求,即日誌本身不得犯錯:鑑於憑證透明度的僅追加特性,看似微小的資料損壞會導致日誌永久喪失資格 4。為了最大程度地減少損壞的影響,以及出於可擴展性原因,CT 日誌通常將其包含的憑證分佈在不同、較小的個別 CT 日誌中,稱為分片。

在許多樹狀結構之間分割多年的資料

Let's Encrypt Oak CT 日誌實際上是由許多個別的 CT 日誌分片組成,每個分片都以一段時間命名:Oak 2020 包含在 2020 年過期的憑證;Oak 2022 包含在 2022 年過期的憑證。為了方便參考,我們將這些稱為「時間日誌分片」,但事實上每個分片都是共享 Oak 家族名稱的個別 CT 日誌。

配置單個 Trillian 安裝來支援多個 CT 日誌分片非常簡單。每個日誌分片都在後端資料庫中分配儲存空間,然後 Trillian 日誌伺服器可以為所有已配置的日誌提供服務。

Trillian 資料庫結構描述相當簡潔且容易理解

  • 每個配置的日誌都有一個樹狀 ID,以及數個表格中的中繼資料。

  • 所有日誌項目(在我們的案例中是憑證)都在 LeafData 中取得一個資料列。

  • 尚未排序的項目會在 Unsequenced 表格中取得一個資料列,通常 Trillian 日誌簽署者服務會使該表格保持空白。

  • 排序後,項目會從 Unsequenced 表格中移除,並以資料列的形式新增至 SequencedLeafData。

Database Layout

資料庫佈局

簡而言之:無論您為給定的 Trillian 副本設定多少不同的憑證透明度樹狀結構和子樹狀結構,它們都會將大部分資料(特別是 DER 編碼的憑證本身)交織到一個 LeafData 表格中。由於 Trillian 日誌伺服器只能使用單個 MySQL 連接 URI 進行配置,因此將其限制為單個資料庫,該單個表格可能會變得非常大。

對於 Oak 來說,資料庫目前以每月約 400 GB 的速度成長;隨著 TLS 的使用不斷增加,以及更多憑證授權單位將其憑證提交到我們的日誌,該速度將持續增加。

Amazon RDS 大小限制

在 2021 年 3 月,我們發現,當 RDS 配置為使用每個表格一個檔案時(如同我們為所有 CT 日誌分片所做的一樣),Amazon RDS 每個表空間有 16 TB 的限制。幸運的是,我們在測試環境 Testflume 日誌中首先達到此限制。

Testflume 的部分目的是在總大小上超越生產日誌,並以比生產 Oak 日誌更積極的配置選項測試成長,在這方面它非常成功。

重新檢視資料庫設計

在我們的部落格文章 Let’s Encrypt 如何運作 CT 日誌中,我們寫到我們計畫每年「凍結前一年的分片,並將其移至成本較低的服務基礎設施,回收其儲存空間以供我們的即時分片使用。」但是,在繼續從同一個資料庫執行個體提供流量的同時,這是不可行的。從正在使用的 InnoDB 表格中刪除數 TB 的資料列是不可行的。Trillian 的 MySQL 相容儲存後端也同意:在實作上,Trillian 的內建 樹狀結構刪除機制會將樹狀結構標記為 「軟刪除」,並將從 LeafData 表格(以及其他表格)中移除資料的任務留給管理員執行。

由於 Trillian 的 MySQL 相容後端本身不支援在多個表格之間分割 LeafData,並且從這些表格中刪除過時的資料會導致整個資料庫伺服器的效能降低,因此為了繼續擴展 Oak CT 日誌,我們必須改用其他方式來修剪掉先前季度資料。

每個日誌分片具有不同結構描述的單個 RDS 執行個體

我們考慮在現有的 MariaDB 支援的 Amazon RDS 執行個體中新增資料庫結構描述。在此設計中,我們將為每個時間日誌分片執行一個 Trillian CT 前端(CTFE)執行個體,每個執行個體都指向個別的 Trillian 日誌伺服器和日誌簽署者執行個體,這些執行個體本身都指向特定時間識別的資料庫結構描述名稱和表空間。這符合成本效益,並且給我們足夠的空間來避免 16 TB 的限制。

One Schema per Shard

單個資料庫中每個日誌分片的不同結構描述

但是,如果需要對基礎資料庫的任何部分進行大量維護,則會影響其中包含的每個日誌分片。特別是,我們從在 Let's Encrypt CA 基礎架構中使用帶有 InnoDB 的 MariaDB 的經驗中得知,截斷和刪除多 TB 的表格會在操作執行時導致整個資料庫的效能問題。在 CA 基礎架構內部,我們僅在資料庫複本上刪除表格資料,以緩解該效能問題;在像 RDS 這樣更為放任的管理式託管環境中,這會更加複雜。

由於我們希望定期清除舊資料作為資料衛生措施,而且 CT 日誌的效能要求非常嚴格,因此此選項不可行。

每個日誌分片的不同 RDS 執行個體

雖然這增加了受管理系統組件的數量,但是為每個時間日誌分片提供其自己的資料庫執行個體要乾淨得多。與每個日誌分片的不同結構描述模型一樣,我們現在為每個時間日誌分片執行 Trillian CTFE、日誌伺服器和日誌簽署者執行個體。但是,每個日誌分片在其日誌的有效生命週期內都會獲得其自己的 RDS 執行個體 5。在日誌關閉時,RDS 執行個體只需取消佈建。

Database per shard

每個日誌使用不同的資料庫

根據 Oak 日誌的原始規格,這將需要分配大量的資料 I/O 資源。但是,多年運作 Testflume 日誌的經驗表明,AWS 中的 Trillian 並不需要最高的磁碟效能。

調整 IOPS

我們使用當時可用的最高效能 AWS 彈性區塊儲存啟動了 Oak:佈建 IOPS SSD(io1 類型)。由於 CT 日誌的效能要求嚴格,我們擔心如果沒有最佳的磁碟 I/O 效能,可能會出現延遲問題,這可能會導致資格喪失。正如我們在部落格文章 Let’s Encrypt 如何運作 CT 日誌中所指出的,我們希望將來可以使用更簡單的儲存類型。

為了測試這一點,我們為測試用的 CT 日誌 (Testflume) 使用了通用型 SSD 儲存類型 (gp2 類型),並在日誌的整個生命週期中獲得了預期的結果。實際上,更高的效能是不必要的,因為 Trillian 能夠善用資料庫索引。從第一個葉節點下載整個日誌樹是磁碟 I/O 最主要的需求,而這種操作方式可以透過負載平衡層的速率限制輕鬆管理。

我們 2022 年和 2023 年的 Oak 分片現在使用 gp2 類型儲存,並且運作良好。

協同作用下,先前將每個時間日誌分片都運行在獨立的 RDS 執行個體上的變更也進一步降低了 Trillian 的 I/O 負載:更多縮減後的資料可以放入 MariaDB 的記憶體緩衝池中。

更多未來的改進

顯然,CT 日誌的成長速度將會持續加快。最終,如果我們繼續使用此架構,即使是單一年度的 CT 日誌也會超過 16 TB 的表格大小限制。在此之前,我們必須採取進一步的行動。其中一些可能包括:

  • 將我們的時間日誌分片策略變更為比一年更短的間隔,可能每 3 或 6 個月一次。

  • 透過重複資料刪除中間憑證來降低 Trillian 的 MySQL 相容儲存後端的絕對儲存需求。

  • 貢獻補丁以在 Trillian 的 MySQL 相容儲存後端中新增表格分片功能。

  • 完全變更儲存後端,可能改為使用支援分片的 Middleware,或是其他更具水平擴展性的開放原始碼系統。

我們也移除目前的 Testflume CT 日誌,並啟用了替代的日誌,我們將其命名為 Sapling。和以前一樣,這個僅供測試的日誌將評估未來可能有所成果的更積極配置。

一如既往,擴展數據是困難的部分

雖然 CT 日誌的效能要求嚴格,但擴展性的主要困難在於大量資料和不斷增加的成長速度;這是關聯式資料庫的特性。水平擴展仍然是解決方案,並且很容易應用於開放原始碼的 Trillian 和 MariaDB 技術堆疊。

支援 Let’s Encrypt

作為一個非營利項目,我們 100% 的資金來自於我們的使用者和支持者的捐款。我們依賴他們的支持,才能為公眾利益提供服務。如果您的公司或組織想要贊助 Let’s Encrypt,請寄電子郵件至sponsor@letsencrypt.org。如果您可以透過捐款支持我們,我們懇請您進行個人捐款。



  1. Chrome 和 Safari 會檢查憑證是否包含憑證已提交至 CT 日誌的證據。如果憑證缺少該證據,則不會被信任。https://certificate.transparency.dev/useragents/ ↩︎

  2. 截至發布時,這些組織的日誌已被 Google Chrome 認為是憑證授權單位可以嵌入其簽署時間戳的合格日誌:Cloudflare、DigiCert、Google、Let's Encrypt、Sectigo 和 TrustAsia。https://ct.cloudflare.com/logshttps://twitter.com/__agwa/status/1527407151660122114 ↩︎

  3. DigiCert 在 AWS 上的 Yeti CT 日誌部署使用自訂的 Apache Cassandra 後端;Oak 是唯一使用 Trillian 專案的 MySQL 相容後端的生產日誌。SSLMate 維護了一個已知的日誌軟體清單,網址為 https://sslmate.com/labs/ct_ecosystem/ecosystem.html ↩︎

  4. 最近,宇宙射線事件導致 CT 日誌被取消資格。Andrew Ayer 在他的文章「憑證透明度日誌如何失敗以及為什麼沒關係」中對此進行了很好的討論:https://www.agwa.name/blog/post/how_ct_logs_fail,其中引用了在 ct-policy 清單上的發現:https://groups.google.com/a/chromium.org/g/ct-policy/c/PCkKU357M2Q/m/xbxgEXWbAQAJ ↩︎

  5. 日誌在停止接受新條目後會保持在線上一段時間,以便為鏡像和歸檔活動提供寬限期。 ↩︎