这篇文章已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已失效。

从网络策略到安全策略

Kubernetes 网络策略 

Kubernetes 支持一种新的网络策略 API,它提供了一个复杂的模型来隔离应用并减少其攻击面。这个特性源自 SIG-Network 工作组,通过使用 Kubernetes 内置的标签和选择器,可以非常容易且优雅地定义网络策略。

Kubernetes 将网络策略的实现留给了第三方,并且没有提供默认实现。

我们想介绍一种新的思考“安全”和“网络策略”的方式。我们想表明,安全和可达性是两个不同的问题,并且使用端点(例如 Pod 标签)定义的安全策略并不一定需要使用网络原语来实现。

我们 Aporeto 的大多数人都来自网络/SDN 背景,我们知道如何使用传统的网络和防火墙技术实现这些策略:将 Pod 的身份和策略定义转换为网络约束,例如 IP 地址、子网等。

然而,我们也从过去的经验中了解到,使用外部控制平面也会带来一系列全新的挑战:ACL 的分发需要在 Kubernetes Worker 之间进行非常紧密的同步;并且每当实例化一个新 Pod 时,所有与其他新 Pod 有相关策略的 Pod 都需要更新 ACL。非常紧密的同步本质上是一个二次状态问题,虽然共享状态机制在小规模下可能有效,但在大规模集群中往往存在收敛、安全和最终一致性问题。 

从网络策略到安全策略

在 Aporeto,我们采取了一种不同的方法来实施网络策略,即真正地将网络与策略解耦。我们将我们的解决方案开源为 Trireme,它将网络策略转换为授权策略,并为 Pod 之间的任何通信实现了透明的身份验证和授权功能。它不使用 IP 地址来识别 Pod,而是为每个 Pod 定义一个与其相关联的标签集作为其经过加密签名的身份。它不使用 ACL 或包过滤器来强制实施策略,而是使用授权功能,使得容器只能接收来自身份与策略要求相匹配的容器的流量。 

Trireme 中的身份验证和授权功能叠加在 TCP 协商序列上。身份(即标签集)被捕获为 JSON Web Token (JWT),由本地密钥签名,并在 Syn/SynAck 协商期间交换。接收端 Worker 验证 JWT 是否由受信任的机构签名(身份验证步骤),并根据策略的缓存副本验证连接是否可以接受。一旦连接被接受,其余流量将流经 Linux 内核及其可能提供的所有保护(如果需要,包括 conntrack 功能)。当前的实现使用一个简单的用户空间进程,它捕获初始协商数据包并将授权信息作为负载附加。JWT 中包含在 Ack 数据包期间进行验证的 Nonce,可以防御中间人或重放攻击。

Trireme 实现直接与 Kubernetes Master 通信,无需外部控制器,并接收有关策略更新和 Pod 实例化的通知,以便维护策略的本地缓存并根据需要更新授权规则。Trireme 组件之间不需要任何需要同步的共享状态。Trireme 可以作为独立进程部署在每个 Worker 上,或使用DaemonSet 进行部署。在后一种情况下,Kubernetes 负责 Trireme Pod 的生命周期管理。 

Trireme 的简洁性源于将安全策略与网络传输分离。策略强制实施直接关联到连接上的标签,而与用于 Pod 通信的网络方案无关。这种身份关联为运维人员提供了极大的灵活性,可以使用他们喜欢的任何网络方案,而无需将安全策略强制实施与网络实现细节绑定。此外,跨联邦集群实施安全策略也变得简单可行。

Kubernetes 和 Trireme 部署

Kubernetes 在其可伸缩性以及为容器和微服务部署提供可扩展安全支持方面是独一无二的。Trireme 提供了一种简单、安全且可伸缩的机制来强制实施这些策略。 

您可以使用提供的 DaemonSet 在 Kubernetes 上部署和试用 Trireme。您需要根据您的集群架构修改一些 YAML 参数。所有步骤都在 deployment GitHub 文件夹中详细描述。该文件夹还包含一个 3 层策略示例,可用于测试流量模式。

要了解更多、下载代码并参与项目,请访问

  • Trireme 在 GitHub
  • Aporeto 的 Kubernetes 版 Trireme 在 GitHub