培育我们 Oak CT 日志的持续增长
Let's Encrypt 自 2019 年以来一直在运行证书透明度 (CT) 日志,作为我们致力于维护 Web PKI 生态系统健康的承诺的一部分。CT 日志已成为加密 Web 1 的重要基础设施,但它们在高信任度运营方面享有当之无愧的声誉:目前只有 6 个组织运行被认为是“合格”的日志。2
我们的 Oak 日志是唯一一个完全基于开源堆栈 3 运行的合格 CT 日志。为了降低其他组织加入 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 是唯一一个没有闭源组件 3 的可信 CT 日志。
其他 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 中的一行添加。
简而言之:无论为给定 Trillian 副本设置多少不同的证书透明度树和子树,它们都将存储大部分数据,特别是 DER 编码的证书本身,交织到一个 LeafData 表中。由于 Trillian 日志服务器只能配置一个 MySQL 连接 URI,限制它只能连接到一个数据库,因此这个单个表可能会变得非常大。
对于 Oak 而言,数据库目前以每月约 400 GB 的速度增长;随着 TLS 的使用不断增加,以及更多证书颁发机构将其证书提交到我们的日志中,这个速度还在不断加快。
Amazon RDS 大小限制
在 2021 年 3 月,我们发现 当 RDS 配置为使用每个表一个文件时,Amazon RDS 每个表空间的 限制为 16TB,正如我们一直在对所有 CT 日志分片所做的那样。幸运的是,我们在测试环境中(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 的限制。
但是,如果底层数据库的任何部分需要进行大量维护,则会影响其中包含的每个日志分片。特别是,我们从在 Let's Encrypt CA 基础设施中使用 MariaDB 和 InnoDB 中获悉,截断和删除多 TB 表会导致整个数据库在操作运行期间出现性能问题。在 CA 基础设施中,我们通过仅在数据库副本上删除表数据来缓解此性能问题;这在 RDS 等更加松散管理的托管环境中会更加复杂。
由于我们希望定期清除旧数据作为数据卫生的一部分,并且 CT 日志的性能要求很严格,因此此选项不可行。
每个日志分片都有不同的 RDS 实例
虽然这会增加托管系统组件的数量,但为每个时间日志分片提供自己的数据库实例会更加干净。与每个日志分片有不同模式的模型一样,我们现在为每个时间日志分片运行 Trillian CTFE、日志服务器和日志签名实例。但是,每个日志分片都获得自己用于日志活动寿命的 RDS 实例 5。在日志关闭时,RDS 实例会简单地取消预置。
使用 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 兼容存储后端。
-
完全更改存储后端,也许更改为支持分片的中间件,或另一个更具横向可扩展性的开源系统。
我们还 放弃了我们当前的 Testflume CT 日志,并上线了一个我们称为 Sapling 的替代品。和以前一样,这个仅供测试的日志将评估可能在未来结出硕果的更激进的配置。
与以往一样,数据扩展是难点
尽管对 CT 日志的性能要求很高,但可扩展性方面的大部分困难都与大量数据以及高且不断增长的增长速度有关;这正是关系型数据库的运作方式。水平扩展仍然是解决方案,并且易于应用于开源 Trillian 和 MariaDB 堆栈。
支持 Let’s Encrypt
作为一家非盈利项目,我们 100% 的资金来自社区用户和支持者的捐助。我们依靠他们的支持才能为公众利益提供我们的服务。如果您的公司或组织希望 赞助 Let’s Encrypt,请发送电子邮件至 sponsor@letsencrypt.org。如果您能通过 捐赠 来支持我们,我们请您进行个人捐赠。
-
Chrome 和 Safari 会检查证书是否包含证明证书已提交到 CT 日志的证据。如果证书缺少该证据,则不会被信任。 https://certificate.transparency.dev/useragents/ ↩︎
-
截至发布,以下组织拥有 Google Chrome 认为合格的日志,以便证书颁发机构将其签名的时间戳嵌入其中:Cloudflare、DigiCert、Google、Let’s Encrypt、Sectigo 和 TrustAsia。 https://ct.cloudflare.com/logs 和 https://twitter.com/__agwa/status/1527407151660122114 ↩︎
-
DigiCert 在 AWS 上的 Yeti CT 日志部署 使用自定义的 Apache Cassandra 后端;Oak 是唯一使用 Trillian 项目的 MySQL 兼容后端的生产日志。SSLMate 在 https://sslmate.com/labs/ct_ecosystem/ecosystem.html ↩︎ 上维护着一个已知日志软件列表。
-
在最近的过去,一个宇宙射线事件导致了 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\ ↩︎
-
日志在停止接受新条目后会在线保留一段时间,以提供镜像和存档活动的宽限期。 ↩︎