Cilium网络策略重新定义:正确的Deny用法和mTLS认证 🔐

大家好!负责Kubernetes网络安全的各位,在技术世界中,学习、修正和进步至关重要。我承认之前的文章中关于Cilium的Deny策略存在错误信息,现在我带着正确的内容回来了。

今天,我们将深入探讨Cilium网络策略中精确的拒绝(Deny)规则使用方法,并进一步了解超越IP和端口的验证工作负载身份的mTLS认证。

1. 基本原则:’Default Deny’(允许列表)依然有效

首先,最基本的“Default Deny”原则没有改变。当任何Pod应用了egress或ingress规则时,除了明确允许的流量外,所有流量都将被阻止。这是集群安全最重要的起点。

“如果你的名字不在邀请名单(egress/ingress规则)上,你就不能进入。”

这种允许列表方式构成了零信任安全的基础。


2. 正确的拒绝(Deny)规则:egressDeny 和 ingressDeny 🚫

在之前的文章中,我错误地指导您使用了action: Deny字段。正确的方法是使用独立的顶级字段egressDeny和ingressDeny。

这些规则的运作方式非常明确和强大。

规则评估顺序:Deny规则总是优先于Allow规则进行检查和评估。

  1. [第一优先级] Deny规则检查:从Pod发出的流量首先与egressDeny规则进行比较。如果找到匹配的规则,流量将

    立即被阻止(DENY)

    。不再检查其他规则。

  2. [第二优先级] Allow规则检查:不符合egressDeny规则的流量,此时才与egress(允许)规则进行比较。如果找到匹配的允许规则,流量将

    被允许(ALLOW)

    。

  3. [最终] 默认阻止:如果流量既不符合Deny规则,也不符合Allow规则,则根据“Default Deny”原则,流量将

    最终被阻止(DENY)

    。

示例:“允许所有外部通信,但绝对禁止访问数据库服务”

YAML

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "correct-deny-database"
  namespace: "team-orange"
spec:
  endpointSelector:
    matchLabels:
      type: messenger
  
  # 第二优先级评估的'允许'规则
  egress:
    - toCIDR:
        - "0.0.0.0/0" # 允许与所有外部IP范围的通信
  
  # 第一优先级评估的'拒绝'规则
  egressDeny:
    - toServices:
        - k8sService:
            serviceName: database
            namespace: team-orange

此策略对messenger Pod的操作如下:

  • 如果Pod尝试与数据库服务通信,它将首先匹配egressDeny规则并立即被阻止。
  • 如果Pod尝试与Google DNS(8.8.8.8)等其他外部IP通信,它将不符合egressDeny规则,因此会转到egress规则。由于它符合toCIDR: [“0.0.0.0/0”]规则,因此将被允许。

3. 身份验证时间:通过mTLS进行相互认证 (Authentication) 🛡️

到目前为止,我们已经通过IP、端口、服务名称等网络层(L3/L4)控制了流量。但是,如果黑客伪造IP,或者渗透到授权的Pod中尝试恶意通信,该怎么办呢?

此时,我们需要的就是“身份认证”。这不仅仅是验证网络路径是否正确,更是确认“尝试通信的工作负载是否真的是我们信任的那个工作负载?”Cilium通过相互TLS (mTLS)来实现这一点。

简单比喻:如果网络策略是“检查名字是否在邀请名单上”,那么mTLS认证就是“核对身份证照片和本人面部,确认是同一个人”。

示例:客户端只能与经过认证的服务器通信

让我们为客户端Pod与服务器Pod通信的规则添加mTLS认证。

YAML

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "mtls-auth-policy"
  namespace: "default"
spec:
  endpointSelector:
    matchLabels:
      app: client
  egress:
    - toEndpoints:
        - matchLabels:
            app: server
      toPorts:
        - ports:
            - port: "8080"
              protocol: TCP
      # --- 这正是强制身份认证的部分 ---
      authentication:
        mode: "required"
  • authentication: mode: “required”:添加此设置后,当客户端Pod尝试与服务器Pod通信时,必须出示其加密的身份(SPIFFE ID)。
  • 服务器Pod也会验证客户端的身份,并且只有在有效的情况下才接受通信。
  • 如果伪装的Pod尝试访问服务器但身份验证失败,即使网络路径被允许,连接也将在认证阶段被阻止。

最终总结:构建深度防御(Defense in Depth)

今天,我们纠正并学习了两个重要概念:

  1. 正确的Deny:显式阻止使用egressDeny / ingressDeny字段,这些规则始终优先于Allow规则。
  2. 强大的认证:通过authentication: mode: “required”为网络策略添加身份验证层(mTLS),可以进一步增强零信任安全。

希望您能通过超越简单控制网络路径、验证工作负载身份的多层防御策略,更安全地保护您的Kubernetes集群。


Cilium, NetworkPolicy, Kubernetes, Security, CNI, EgressDeny, IngressDeny, mTLS, Authentication, SPIFFE, Zero Trust, DevSecOps, Cilium, Kubernetes, Security


Comments

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注