停止信任容器注册中心,验证镜像签名
作者:Wojciech Kocjan / Tyson Kamp / 产品, 用例
2022 年 10 月 18 日
导航至
简介
InfluxData 的主要产品之一是 InfluxDB Cloud。它是一个云原生 SaaS 平台,用于以无服务器、可扩展的方式访问 InfluxDB。InfluxDB Cloud 在所有主要的公有云中均可用。
InfluxDB Cloud 从头开始构建,以 支持自动扩展 并处理不同类型的工作负载。在底层,InfluxDB Cloud 是一个基于 Kubernetes 的应用程序,由在多云、多区域设置中运行的微服务集群组成。
该应用程序由存储层组成,该存储层使用 持久卷 和云原生对象存储(例如 AWS 云上的 S3)进行持久化。它使用 Kafka 和 Zookeeper 对传入数据进行排队,并使用托管 SQL 数据库来存储其他数据。该应用程序还包含大约 50 个无状态微服务,这些微服务执行各种操作,例如写入和查询时间序列数据,以及定期运行 任务。
在 InfluxDB 的云原生产品中,我们识别出一个特定的安全问题。该应用程序在第三方注册中心存储了数千个容器,然后部署到我们的集群中。我们如何知道在拉取/运行时,容器与我们的 CI/CD 管道中使用的容器相同?如果第三方注册中心遭到破坏怎么办?
容器镜像需要签名
根据基于云的系统的标准风险所有权模型,实体(公司等)负责其产品供应链和组件的安全性,无论构成该产品的组件提供商或服务/系统供应商是谁。“不是我们”是不可接受的。
在考虑如何缓解容器注册中心的完全泄露时,一个有些粗暴的想法浮现在脑海中。在推送镜像后,远程注册中心会返回摘要,这对于识别镜像和验证其完整性非常有用。缓解解决方案的一种选择是创建一个摘要数据库,应用程序在推送容器后立即获得这些摘要。如果您信任哈希和标准加密工具,并且可以接受维护此信息数据库,那么这或多或少可以处理镜像的真实性和完整性。但是,这种方法会带来额外的挑战。您需要确保容器镜像的所有使用者都可以及时访问摘要数据库。
第二种,也是更具吸引力的选择是在容器推送时为每个容器镜像创建签名,并使可以验证签名的公钥列表易于访问。毕竟,公钥并不敏感。公钥列表很重要(考虑重放攻击),但稍后会详细介绍。
对于 Influx 的利益,当我们能够验证所有计划在 InfluxData 托管集群上运行的相关 OCI 容器镜像都源自 InfluxData(在某个时间点或从一开始),并且未被篡改(真实性和完整性)时,我们认为风险已得到缓解。签名使我们能够检测到任何篡改,因此它们对于这种缓解策略非常有吸引力。稍后我们将更深入地研究供应链的自动完整性和真实性管理,但我们正在采取“小步快跑”的方法。
架构和镜像
我们主要使用内部编写的代码和集成来构建 InfluxDB Cloud。我们使用 CI 系统来构建代码,并使用 CD 系统来部署代码。这确保我们可以尽快构建和部署对应用程序代码的任何更改。
我们还使用了 InfluxData 的多个开源组件,例如 Telegraf 或 Telegraf-operator,以及第三方组件,例如 Kafka 和 HashiCorp Vault。InfluxDB Cloud 团队不构建(在某些情况下也不想构建)或控制这些第三方镜像。尽管如此,该团队有能力审查和选择接受特定的镜像(最好是使用它们的 SHA 摘要)并对这些镜像进行签名。我们将签名保存在一个单独的位置,我们将在下一节中更详细地描述。
我们希望做的是经常创建签名密钥对和签名,并使公共验证密钥易于访问。这种方法比跟踪摘要和担心一致性更简单且更具可扩展性。InfluxData 目前管理着跨三个云提供商的大量生产集群,我们认为这种容器签名想法应该可以很好地扩展。
添加数字签名
在这个项目的早期阶段,团队研究了两个 GitHub 仓库:Connaisseur 和 SigStore 项目 policy-controller。Connaisseur 被证明非常容易设置,并且易于配置以进行概念验证。Policy-controller 的配置更加耗时和复杂,但我们接受了这种权衡,因为配置性通常会滋生复杂性。该团队最终通过自动化 ClusterImagePolicy 的创建并重新应用它使 policy-controller 正常工作。接下来,他们自动化了测试环境的启动,并创建了一个 Bash 脚本来对签名验证进行正面和负面测试。
Connaisseur 在其开发中似乎更成熟,但它不是像 SigStore 那样针对供应链风险的更大系统的一部分。此外,Connaisseur 是用 Python 编写的,并且似乎开发和参与度较低。鉴于 policy-controller/SigStore 在满足供应链风险需求方面的更完整性、其积极的开发(尽管成熟度较低)以及它像 InfluxDB 一样是用 Golang 编写的事实,InfluxData 选择了 policy-controller。
对于创建签名密钥对以及执行签名创建和验证,我们选择了 cosign。这是一个容易做出的选择。它正是这项工作的合适工具。
我们还希望使轮换密钥对变得容易,其中自动化作业轮换签名密钥对以创建和验证签名。我们仍在调整轮换频率,但我们的目标是至少每周轮换一次,每天不超过几次。我们将签名密钥对存储在 HashiCorp Vault 中,它们永远不会离开它,利用 Vault 执行签名过程。
一个安全且受信任的端点,在我们内部网络中可用,使非敏感公钥可用。所有使用镜像并执行验证的集群都会定期拉取最新的公钥集,并相应地更新其本地配置。如果集群无法使用从受信任端点返回的公钥列表验证签名,则集群将不会加载镜像。
这使 InfluxData 能够创建短期密钥对和签名,同时还使使用镜像的集群能够验证容器镜像的签名。
对于我们所有的内部代码,CI 系统会自动对所有经过审查、批准并计划在生产环境中运行的代码进行签名。我们将这些容器镜像的数字签名存储在与镜像本身相同的位置。
我们从外部引用开源和第三方镜像的容器镜像,并将 InfluxDB Cloud 的签名保存在我们控制的专用镜像注册中心中。这样,InfluxDB Cloud 可以引用上游镜像,但在我们的镜像注册中心中创建和维护签名。Sigstore cosign 和 policy-controller 完全支持这种方法。
作为 InfluxDB Cloud 元数据的一部分,管理基础设施的团队维护允许运行的所有开源和第三方镜像的列表。该列表由特定镜像及其 SHA 摘要组成。所有这些镜像都会定期签名,签名会写入 InfluxData 控制的 OCI 注册中心。这使我们的 Kubernetes 集群(验证签名)能够运行镜像,即使镜像本身位于上游注册中心中。
当需要更新任何不属于 InfluxDB Cloud 代码的应用程序时,此设置确实会增加一些额外负担。任何更新都需要获取更新的上游镜像列表,并确保在执行任何更新之前对它们进行签名。然而,这是一个优点,因为它确保审查镜像更改成为审查更新外部组件过程的一部分。
在 InfluxData 定义了上述方法和流程后,签名和验证的部署和启用就开始了。首先对一部分镜像进行签名,然后在单个 Kubernetes 集群中部署 policy-controller 并验证这些镜像。
在经历了一些最初的挑战之后,并且一旦在一个集群中验证工作正常,我们在其他集群上启用了 policy-controller,并更新了我们的检查以包含所有镜像。
InfluxData 使用 GitOps 管理其基础设施,因此为生产环境启用它意味着启用 policy-controller 以及用于更新镜像验证策略的逻辑,并保持有效的公钥列表为最新。
一旦所有这些设置在其他 Kubernetes 集群上上线,InfluxDB Cloud 工作负载就可以验证其容器镜像。
以下是我们的基础设施设置方式的图表
InfluxDB Cloud 容器信任
处理安全事件
我们特别关注在安全事件发生时保持密钥轮换尽可能简单。此解决方案是事件场景中需要关注的众多解决方案之一,因此我们尽可能简化了该过程。
配置项尽可能少,并且我们尽可能简化了架构。文档接收来自多个团队的输入,并且只有当对实施几乎一无所知的人员可以按照为重置系统而创建的指示进行操作时,文档才会被视为“通过”。这包括
-
轮换安全控制工件,例如从 CI 系统到镜像签名端点的身份验证密钥
-
为容器镜像的数字签名生成新的密钥对
-
为所有容器镜像创建新签名
-
加速弃用可能泄露的密钥对(这会导致旧签名失效)
我们可以在几个小时内完成此系统的完全恢复,包括在所有集群中重新部署新签名的容器镜像。
结束语
在设计此系统时,我们考虑的主要威胁向量之一是重放攻击。在这种情况下,重放攻击是指将具有已知漏洞的软件组件重新安装到系统中的能力。例如,如果攻击者发现一组容器镜像中存在严重漏洞,他们可以从注册中心获取这些镜像及其签名,以便稍后尝试将它们(以及漏洞)重新引入系统。
InfluxData 解决方案如此频繁地轮换签名密钥,以至于重新引入具有已知漏洞的镜像实际上是不可行的。签名的有效时间窗口太小,对攻击者来说没有实际用途,因为签名的有效寿命最多只有几天或几周。
该解决方案仅使用公开可用的加密解决方案和最先进的加密标准。InfluxData 不创建任何自己的安全组件,而是以快速 CICD GitOps 框架部署众所周知的组件和控件。InfluxData 相信这种模式的内在优势。
Influx 容器信任解决方案的实施仅依赖于 Kubernetes 和 SigStore 组件。该解决方案与容器注册中心和云提供商无关,并且可以在 Influx 管理的任何 K8s 集群中运行。因此,在 Influx 域中的采用是无缝的。
虽然显然没有“一刀切”的解决方案,但 InfluxData 努力以最适合其需求的方式缓解注册中心泄露威胁。该方法与其他群体(公司、政府等)的需求重叠,并希望为解决这些类型的风险和采用这种威胁缓解解决方案提供一些想法。InfluxData 部署团队成员 Wojciech Kocjan 和 Tyson Kamp 将于 2022 年 10 月 25 日星期二在美国密歇根州底特律举行的 SigStoreCon 上 演讲,以扩展这篇博文。欢迎参加或联系他们以获取更多信息。