揭示Kubernetes秘密的秘密

2021-05-07 16:37:51 浏览数 (1)

作者:Ben Hirschberg,ARMO[1]研发副总裁和联合创始人

你能保守秘密吗?希望如此,因为在这个博客中,我揭示了 Kubernetes 秘密的秘密。首先,我将深入研究 Kubernetes 的秘密机制,然后转向如何保护它们。

Kubernetes secrets 是用于存储和管理敏感数据(如密码、云访问密钥或身份验证令牌)的原生资源。你需要在你的 Kubernetes 集群中分发此信息,并同时对其进行保护。在向集群中的每个节点发送密码时,确保只有经过授权的实体(用户、服务或工作负载)能够访问密码非常重要。

Kubernetes 秘密

Kubernetes 计算的构造块是由容器组成的 pod。你可以将敏感密码放入容器镜像中,或将其配置为 pod 定义的一部分。更安全的 Kubernetes 原生方法使用秘密对象,并在 pod 规范中引入它们(例如,文件或环境变量)。

在下一节中,我将介绍 Kubernetes 提供的保护层。

保护

秘密是 Kubernetes 原生资源,Kubernetes 为它们提供了一套基本的保护层。这些保护措施是随着时间而发展的,可分为以下几类:

  • 秘密资源:因为 pod 和秘密是分开的对象,所以在 pod 生命周期中暴露秘密的风险更小。因此,作为第一种安全措施,如果你将敏感信息作为环境变量传递给分离舱,则应该将它们分离并将它们创建为秘密对象。由于秘密是独立的资源,你也可以在 RBAC 中以不同的方式处理它们并限制访问。
  • kubelet:第二组安全特性来自 kubelet——在每个 K8s 节点上运行并在运行时与容器交互的代理。秘密中的数据在容器中使用,它们应该在容器运行的节点上可用。然而,Kubernetes 只在节点有需要秘密的 pod 时才将秘密发送给节点。此外,kubelet 将秘密数据存储在临时文件存储(tmpfs)中,而不是磁盘中。当从某个节点删除或重新调度 pod 时,kubelet 也会从其本地副本中清除该秘密。
  • Pod:一个节点上运行着许多 Pod,但只有这些 Pod 可以访问定义中指定的秘密。最重要的是,pod 由几个容器组成,但秘密只安装在它的 volumeMounts 规范中要求秘密的容器上。因此,这种 pod 结构将秘密暴露在其他 pod 和容器之间的风险降到了最低。
  • Kubernetes API:秘密是通过 Kubernetes API 创建和访问的。因此,Kubernetes 通过 SSL/TLS 来保护用户、API 服务器和 kubelet 之间的通信。
  • etcd:像所有其他 Kubernetes 资源一样,秘密也存储在 etcd 中。这意味着当你访问运行在控制平面中的 etcd 时,有可能获得秘密。Kubernetes 提供的保护措施是对秘密数据使用静止加密。你可以查看官方文档[2]来配置机密数据的静态加密。

这些保护措施确保机密与其他 Kubernetes 资源隔离,并安全访问和存储。不过,Kubernetes 并不是一个防弹的安全系统,也存在一些风险。

风险

当涉及到秘密时,第三方工具和扩展将识别潜在的风险,并对其进行缓解。风险可分为以下几类:

  • etcd:作为秘密存储的最终位置,etcd 必须加密和良好的保护。你应该启用数据加密并限制对 etcd 集群的访问。当然,etcd 节点之间的点对点通信应该使用 SSL/TLS。
  • 配置即代码(Configuration as code,CaC):你可以使用 JSON 或 YAML 清单文件创建秘密对象。只要确保文件没有签入到代码仓库或共享即可。
  • 应用层:在应用程序中加载秘密时,要小心日志记录它们或将它们传输给不受信任的各方。
  • pod:如果用户拥有足够的权限来创建安装和使用秘密的 pod,那么秘密的值也将对用户可见。即使你设置了 RBAC 规则来限制对秘密的访问,用户也可以通过将秘密发送到外部或将其写入 pod 日志来启动一个暴露秘密的 pod。在设计安全概念时,只需考虑一下秘密与其使用者之间不必要的关联。
  • 节点:容器运行在节点上,如果你是节点的根用户,则可以从 Kubernetes API 服务器检索任何秘密。这是通过模拟(impersonate)kubelet 并访问 Kubernetes API 来实现的。所以一定要小心,确保保护你的节点以及 Kubernetes 控制平面。

接下来,我将介绍开源的、特定于云计算的、更具包容性的工具,以减轻上述风险并保护 Kubernetes 的秘密。

保护 Kubernetes 秘密

有各种各样的工具和策略可以将你的 Kubernetes 秘密安全性提升到下一个级别。在本节中,我将介绍可用的工具以及它们的优缺点,以帮助你选择一个(或多个)用于设计集群。

云密钥管理系统

像 GCP 和 AWS 这样的云提供商有他们自己的云密钥管理系统(KMS),这是一个集中式的云服务,通过它你可以创建和管理密钥来执行加密操作。这些系统还可以作为附加的安全层,用于在应用层加密 Kubernetes 秘密。

当然,KMS 的最大好处是它能够防止获得 etcd 副本访问权的攻击者。但是,它的集成可能有点棘手,所以一定要首先研究如何将 KMS 集成到集群中,并确保它符合你的安全操作。另一方面,KMS 有两个主要的缺点:首先,你需要更改你的应用程序代码以与 KMS 提供者一起工作;其次,它依赖于验证节点,所以如果攻击者已经在该节点上,他们可以轻松访问你的数据。

Sealed Secrets

Sealed Secrets[3]通过在本地将秘密加密为可以安全存储和发布的格式,有助于降低与 CaC 相关的风险,并将秘密泄露到代码仓库中。当集群需要使用秘密时,它只由运行在集群中的控制器解密。

这种方法需要在集群中安装一个控制器,并在本地工作站上安装一个名为 kubeseal 的客户端工具。如果你只关心将秘密对象作为文件保护,那么安装和操作是非常简单的。但是,你需要小心使用 sealed secrets,因为它们只能防止代码仓库的盗窃。例如,如果在安装过程中提取工作站的密钥和秘密,它们将处于危险之中。

Helm 秘密插件

Helm 是在集群中安装复杂应用程序的有用工具,包括它们的配置和敏感数据。然而,将秘密值泄露到代码仓库的问题仍然适用于 Helm chart。运营团队在代码仓库中维护 Helm chart,值文件位于不同的甚至相同的位置。

Helm secrets 是一个通过 Mozilla 的开源SOPS[4]项目加密秘密的 Helm 插件。它也是一个可扩展的平台,支持外部密钥管理系统,如谷歌 Cloud KMS 和 AWS KMS。如果使用 Helm 部署应用程序并在值中存储敏感数据,则需要确保 Helm chart 值的安全。与 sealed secrets 类似,Helm secrets 插件只保护代码仓库中的敏感数据。它没有为 Kubernetes API 或 etcd 中的秘密存储提供任何保护。

总结

总之,Kubernetes 秘密是在云中存储和管理敏感信息的云原生方式。尽管 Kubernetes 提供了一些保护,但仍有许多尚未解决的风险需要考虑。通过在操作堆栈中合并一个或多个工具,你可以减轻这些风险。

*ARMO 增强 DevOps、DevSecOps 和安全团队的信心,让他们相信 Kubernetes 部署是受保护的,每个工作负载、容器和微服务都是安全的。访问我们的网站了解更多信息,安排一个演示,或者通过免费试用 ARMO 为你的 Kubernetes 集群添加无缝保护的第一步。

关于作者

Ben 是 ARMO 研发副总裁和联合创始人。Ben 有云架构和 DevOps 平台的实际操作经验,从云原生技术的早期开始,他有超过 15 年的软件安全经验。

参考资料

[1]

ARMO: https://www.armosec.io/

[2]

官方文档: https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/

[3]

Sealed Secrets: https://github.com/bitnami-labs/sealed-secrets

[4]

SOPS: https://github.com/mozilla/sops

0 人点赞