Kubernetes有一个用于管理网络安全性的内置对象:NetworkPolicy。它是一种以应用为中心的结构,允许你设置如何允许 Pod 与网络上的各类服务通信,但它是基本的,并且需要非常精确的IP映射。我所接触的开发或运维人员,很少有使用它的。
仍然被防火墙困住了吗?
过去,网络安全策略是使用IP地址和子网定义的。你将定义源和目标,端口,操作和跟踪选项。多年以来,防火墙不断发展壮大,已成为可识别和防护高级恶意软件。它不再是防火墙,而是完整的网络安全解决方案。
但是,即使在今天,大多数网络安全解决方案都还在使用IP地址和范围作为源和目标。当迁移到云时,挑战就来了。
在如此快速变化的环境中,如何定义源IP/目标IP?因为IP地址一直在变化。另外,如果你想了解云并在网络地址转换之前查看连接,则必须位于应用程序内部。在大多数情况下,在Kubernetes中,当Pod连接到外部资源时,它将通过网络地址转换,这意味着目的地会将源IP视为工作节点地址而不是Pod。
对于IaaS云部署,大多数公司可以通过在虚拟机(VM)上安装具有代理的网络安全解决方案来解决这一难题。
但是当涉及到Kubernetes时,它是行不通。为什么?
- Kubernetes中的普通Pod仅有几MB,因此你无法在Pod中部署完整的网络安全解决方案。将其放置在Kubernetes之外可以在某种程度上解决南北流量问题(网络内外的流量),但不能解决东西(网络内的流量和集群内连接性)的问题。
- Kubernetes中的Pod可以快速扩展,随之IP分配更改。
- Kubernetes内部深层数据包,没有要求检测。
幸运的是,Kubernetes中每个Pod都可以定义Ingress策略和Egress策略。两种策略都可以利用IP地址,子网和标签。不幸的是,Kubernetes在安全策略中不支持FQDN(完全限定域名)。
网络安全由网络层实施,最常见的层是Calico,Flannel和Cilium。根据设计,Kubernetes网络是扁平的。来自一个名称空间的一个微服务可以连接到另一个微服务。
构建有效的Kubernetes网络策略
你可能希望用户使用网络策略,但是大多数用户并未使用它。
创建网络策略是一项反复的任务:
映射不同元素,访问应用程序的资源,应用程序连接的资源,端口和协议之间的通信。 创建一个策略。 运行该应用程序,观察是否一切正常。 查找并修复你错过的事情。 每当你的网络或应用程序发生更改时,都要重复一次。
问题在于,在Kubernetes中,由Pod(微服务)组成的应用程序每天都可能更改。你无法与开发团队保持同步,并且每次他们将更改推送到应用程序时,都会更新网络策略。
想象一下,你映射了所有通信模式,相应地创建了一个网络策略,并且一切正常。几个小时后,开发人员正在推送新版本的微服务,该微服务使用来自其他Pod的API,并且停止与现有Pod以及与外部网站的通信。由于你忘记更新网络策略,因此新的微服务停止工作。你无法调试出什么问题,因为Kubernetes中没有网络日志。即使你成功解决了该问题,你仍可能希望保留旧的策略,该策略允许新的Pod与停止与之通信的Pod进行通信。
最后,Kubernetes不具有用于可视化网络流量的内置功能,因此,如果你断开了两个微服务之间的连接,则祝你调试时运气好。
Kubernetes的网络策略是通过允许而不是通过阻止来配置的。这意味着,如果要阻止来自特定目标的单个对象,则需要选择其他解决方案。
最后,最烦人的部分是,Kubernetes网络策略的设置方式是:如果Pod A和Pod B需要通信,则需要为Pod A定义出口流量,为Pod B定义入口流量。这容易出错,并且调试非常困难。
所以,该网络策略示例:
- 带有 “app=c” 标签的所有名字空间中的 Pod
大多数组织只是进行南北网络安全(在集群外部),并祈祷没有任何事情会破坏这种安全控制。
根据设计,Kubernetes的安全性还会遇到以下问题:
- 身份问题:如果Pod A有两个容器,连接到Pod B,Pod B会看到来自Pod A的传入连接,但是,它不知道Pod A哪个容器创建了此连接。这意味着无法在Pod级别上足够实现安全防护。因此,如果恶意软件在我的Pod中运行,它将能够与其他Pod通信。
- 未加密的通信方式:Kubernetes中的应用程序都具有HTTP REST API,攻击者可以拦截和解码该通信(到目前为止,大多数集群内通信尚未加密)。
如上图,网络管理员将策略设置为允许Web到数据库的连接。他的意图是允许在Web中运行的NGNIX与SQL Server通信。但是,这也意味着在一个Web容器中运行的恶意软件也可以与SQL Server通信。
Istio的解决办法
服务网格是一种控制应用程序的不同部分如何彼此共享数据的策略。与其他用于管理网络通信的系统不同,服务网格是直接内置在应用程序中的专用基础结构层。该可见的基础结构层可以记录应用程序的不同部分之间交互的良好程度,因此可以更轻松地优化通信,避免随着应用程序的增长而出现停机。
Istio是当今最流行的服务网格解决方案。
为了克服到目前为止我们讨论的问题,Istio添加了一个sidecar容器,以识别各个工作负载并将东西方流量转移到mTLS。现在,如果Pod A连接到Pod B,则Pod A和B将通过首先验证其证书进行通信。恶意攻击者将无法拦截和破解流量。
这很棒!但事实是,大多数组织仍未使用Istio。实际上,CNCF于2020年末发布的最新报告表明,只有30%的Kubernetes用户正在使用服务网格(Istio或其他)。这可能是因为Istio非常复杂,并且会降低性能。
不仅如此,它还会遭受与上述相同的身份问题-即,如果恶意行为者进入Pod A并创建与Pod B的连接,只要Istio策略允许,它仍将被允许访问。
在上图中,每个Pod都有一个Envoy(代理),该代理通过使用双向TLS隧道来确保与原始容器的通信安全。可以看出,代理(Envoy)并不关心容器的身份。但它可能是与其他服务通信的恶意容器,被授予了Istio/Envoy提供的身份。
Kubernetes网络安全最佳实践
Kubernetes网络安全解决方案应遵循以下准则
- 实施“零信任”:每个微服务都充当其自己的允许者。因此,建议遵循零信任模型:不信任,并始终进行验证!从而在允许访问之前对每个请求进行身份验证和授权。
- 升级到双向TLS:建议使用双向TLS来加密不同微服务之间的通信。这样可以确保即使主机上存在攻击者,也无法拦截和解码流量。
- 提供网络可见性:你无法保护看不到的东西。可见性是理解网络通信模式的关键,不仅看到是什么起作用,还有什么不起作用。
- 应用强大的策略来应对快速变化:请使用可应付不断变化的微服务的策略。
译文链接: https://thenewstack.io/the-kubernetes-network-security-effect/