环境模式安全深入解析
深入探讨最近宣布的 Istio 环境模式(Istio 的无边车数据平面)的安全隐患。
我们最近宣布了 Istio 的新环境模式,它是一个无边车数据平面,也是环境网格模式的参考实现。 如公告博客中所述,我们通过环境网格解决的首要问题是简化操作、扩展应用程序兼容性、降低基础设施成本和提高性能。在设计环境数据平面时,我们希望在操作、成本和性能方面仔细权衡,同时不牺牲安全性或功能。由于环境网格的组件运行在应用程序 Pod 之外,因此安全边界发生了变化——我们相信这会更好。在本博文中,我们将详细介绍这些变化以及它们与边车部署的比较方式。
回顾一下,Istio 的环境模式引入了分层网格数据平面,其中包含一个安全覆盖层,负责传输安全和路由,并可以选择为需要它们的命名空间添加 L7 功能。要了解更多信息,请参阅 公告博客 和 入门博客。安全覆盖层由一个节点共享组件 ztunnel 组成,它负责 L4 遥测和 mTLS,并作为 DaemonSet 部署。网格的 L7 层由航点代理提供,航点代理是全面的 L7 Envoy 代理,按身份/工作负载类型部署。这种设计的一些核心影响包括
- 将应用程序与数据平面分离
- 安全覆盖层的组件类似于 CNI
- 操作的简便性有利于安全
- 避免多租户 L7 代理
- 边车仍然是首选支持的部署
将应用程序与数据平面分离
虽然环境网格的主要目标是简化服务网格的操作,但它确实有助于提高安全性。复杂性会导致漏洞,企业应用程序(及其传递依赖项、库和框架)极其复杂,容易出现漏洞。从处理复杂的业务逻辑到利用 OSS 库或有错误的内部共享库,用户的应用程序代码是攻击者(内部或外部)的主要目标。如果应用程序被入侵,则凭据、密钥和密钥会暴露给攻击者,包括已挂载或存储在内存中的凭据、密钥和密钥。当查看边车模型时,应用程序入侵包括接管边车和任何关联的身份/密钥材料。在 Istio 的环境模式中,没有任何数据平面组件在与应用程序相同的 Pod 中运行,因此应用程序入侵不会导致访问密钥。
Envoy Proxy 作为潜在漏洞目标怎么样?Envoy 是一个非常坚固的基础设施,受到严格审查,并在 关键环境中大规模运行(例如,用于生产中以面向 Google 的网络)。但是,由于 Envoy 是软件,因此它并非不受漏洞影响。当这些漏洞出现时,Envoy 拥有强大的 CVE 流程来识别它们,快速修复它们,并在它们对客户产生广泛影响之前将其推广出去。
回到之前关于“复杂性会导致漏洞”的评论,Envoy Proxy 最复杂的方面在于其 L7 处理,事实上,历史上大多数 Envoy 的漏洞都存在于其 L7 处理堆栈中。但是,如果您只是将 Istio 用于 mTLS,那又何必冒着部署完整 L7 代理的风险呢?当您不使用该功能时,L7 代理更有可能出现 CVE?在这里,L4 和 L7 网格功能的分离发挥了作用。在边车部署中,即使只使用一部分功能,您也会采用所有代理,但在环境模式下,我们可以通过提供安全覆盖层并仅在需要时添加 L7 层来限制暴露。此外,L7 组件完全独立于应用程序运行,不会提供攻击途径。
将 L4 推送到 CNI
环境模式数据平面的 L4 组件作为 DaemonSet 运行,或每个节点运行一个。这意味着它是在特定节点上运行的任何 Pod 的共享基础设施。此组件特别敏感,应与节点上的任何其他共享组件(例如任何 CNI 代理、kube-proxy、kubelet,甚至 Linux 内核)处于同一级别。来自工作负载的流量被重定向到 ztunnel,ztunnel 然后识别工作负载并选择正确的证书以在 mTLS 连接中表示该工作负载。
ztunnel 对每个 Pod 使用不同的凭据,这些凭据仅在 Pod 当前在节点上运行时才会颁发。这确保了受损 ztunnel 的爆炸半径仅是当前在该节点上排队的 Pod 的凭据会被盗取。这与其他良好实施的共享节点基础设施(包括其他安全的 CNI 实现)具有类似的属性。ztunnel 不使用集群范围或每个节点的凭据,如果这些凭据被盗取,则会导致集群中的所有应用程序流量立即受到攻击,除非还实现了复杂的二级授权机制。
如果我们将此与边车模型进行比较,我们会注意到 ztunnel 是共享的,入侵可能会导致运行在该节点上的应用程序的身份泄露。但是,此组件中出现 CVE 的可能性低于 Istio 边车,因为攻击面大大减少(仅 L4 处理);ztunnel 不进行任何 L7 处理。此外,边车中的 CVE(攻击面更大,包括 L7)并非真正仅限于该被入侵的特定工作负载。边车中的任何严重 CVE 都有可能重复到网格中的任何工作负载。
操作的简便性有利于安全
最终,Istio 是必须维护的关键基础设施。Istio 受信任来代表应用程序实施零信任网络安全的一些原则,按计划或按需推出补丁至关重要。平台团队通常具有可预测的补丁或维护周期,这与应用程序的周期截然不同。应用程序可能会在需要新功能时进行更新,并且通常是某个项目的一部分。这种应用程序更改、升级、框架和库补丁的方法是高度不可预测的,允许大量时间过去,并且不利于安全的安全实践。因此,将这些安全功能作为平台的一部分并与应用程序分离,更有可能带来更好的安全态势。
正如我们在公告博客中所确定的那样,操作边车可能更复杂,因为它们具有侵入性(注入边车/更改部署描述符、重新启动应用程序、容器之间的竞争条件等)。对带有边车的工作负载进行升级需要更多计划,并需要进行滚动重启,这些重启可能需要进行协调,以避免应用程序出现故障。使用环境模式,对 ztunnel 的升级可以与任何正常的节点补丁或升级相吻合,而航点代理是网络的一部分,可以根据需要完全透明地为应用程序进行升级。
避免多租户 L7 代理
在数据平面中支持 HTTP 1/2/3、gRPC、解析标头、实施重试、使用 Wasm 和/或 Lua 进行自定义等 L7 协议比支持 L4 复杂得多。要实现这些行为(包括用于 Lua 和 Wasm 等的用户自定义代码)需要大量的代码,而这种复杂性可能导致潜在的漏洞。因此,在这些 L7 功能领域中发现 CVE 的可能性更高。
在环境模式下,我们不会在代理中跨多个身份共享 L7 处理。每个身份(Kubernetes 中的服务帐户)都有自己的专用 L7 代理(航点代理),这与我们在边车中使用的模型非常相似。尝试将多个身份及其不同的复杂策略和自定义项共置在一个共享资源中,会导致成本分配不公平,最糟糕的情况是完全入侵代理。
边车仍然是首选支持的部署
我们理解有些人对边车模型及其已知的安全边界感到满意,并希望继续使用该模型。在 Istio 中,边车是网格的第一公民,平台所有者可以选择继续使用它们。如果平台所有者希望同时支持边车模式和环境模式,他们可以这样做。使用环境数据平面的工作负载可以原生地与已部署边车的工作负载进行通信。随着人们对环境模式的安全态势有了更好的了解,我们相信它将成为 Istio 首选的数据平面模式,边车将用于特定优化。