LabHub
学习 学习路径 课程

CCA — Cilium 认证助理

阻断DNS的防火墙与扩大访问范围的允许规则

在 LabHub 中继续学习

目标

在真正的 Cilium 环境中区分策略方向、namespace 选择器、DNS 依赖、允许规则的并集以及显式拒绝。

为什么这很重要

安全配置变更后出现 timeout 时,如果立刻重启服务器,可能会抹掉问题原因。请通过对比 IP 对照请求和名称请求来定位依赖关系,并同时检查正常请求与被拒绝的请求。要验证的是实际访问范围,而不是策略数量。对照对象会一直保留到最后,因此最终评分也会重新检查当前状态。

只使用 VM 内的个人 k3s。新环境使用 Cilium 1.20.1 和 k3s 1.35.8+k3s1,启动可能需要数分钟。仅完成步骤的准备工作并不等于解决了当前步骤。策略传播完成前,观测结果可能会暂时不同,请在观测后再次评分。会话结束时工作文件会消失,如有需要请先导出。

步骤

  1. 使用工具的 inventory 命令,将 11 个 Pod 的 namespace、name、uid、ip、identity 保存到 /root/cca-policy/inventory.json。cca-blue/client 和 cca-red/client 的 role 标签相同,但 namespace 标签和 identity 不同。请读取并比较输出中的实际值。如果 Pod 已被重新创建,也必须更新记录。
  2. 在 /root/cca-policy/native.yaml 中编写并应用 cca-blue 的 native-only NetworkPolicy。podSelector.matchLabels 为 target=native,policyTypes 为 [Ingress];唯一一条 ingress 中的唯一 from 只设置 podSelector.matchLabels.role=client。对于 native,只有蓝方 client 应返回 200,蓝方 stranger 和红方 client 应 timeout。无策略的 baseline 中三者都应返回 200。
  3. 在 /root/cca-policy/ingress.yaml 中编写并应用 cca-blue 的 blue-ingress CiliumNetworkPolicy。endpointSelector.matchLabels.target=ingress;唯一一条 ingress 中的唯一 fromEndpoints 只设置 matchLabels.role=client。只有蓝方 client 应返回 200,stranger 和红方 client 应 timeout。不要删除 native 策略。
  4. 在 /root/cca-policy/dns-blocked.yaml 中编写并应用 cca-blue 的 dns-blocked CNP。endpointSelector.matchLabels.client-mode=blocked。在唯一一条 egress 中,只设置 toEndpoints.matchLabels={role: api, target: egress} 和 toPorts.ports=[{port: "8080", protocol: TCP}]。不要添加 DNS 允许规则。dns-blocked 客户端通过 egress 服务器 IP 发出的请求应返回 200,通过 Service 名称发出的请求应 timeout。
  5. 在 /root/cca-policy/dns-open.yaml 中编写并应用 cca-blue 的 dns-open CNP。选择 client-mode=open。第一条 egress 项与上一步保持一致,使用同一个 API 目标和 TCP 8080。第二条的 toEndpoints.matchLabels 为 k8s:io.kubernetes.pod.namespace=kube-system 和 k8s:k8s-app=kube-dns,toPorts.ports 包含字符串 53 的 UDP 和 TCP 两项。dns-open 通过 IP 和名称访问都应返回 200。保留 dns-blocked 的限制。
  6. 保留初始 blue-union CNP。在 /root/cca-policy/union.yaml 中编写并应用 cca-blue 的 red-union NetworkPolicy。选择 target=union,并设置 policyTypes=[Ingress]。在唯一一条 ingress 的唯一 from 中,同时设置 namespaceSelector.matchLabels.team=cca-red 和 podSelector.matchLabels.role=client。蓝方 client 和红方 client 应返回 200,stranger 应 timeout。
  7. 保留初始 blue-deny CNP 和 red-deny NetworkPolicy。在 /root/cca-policy/deny.yaml 中编写并应用 cca-blue 的 deny-red CNP。选择 target=deny;在唯一一条 ingressDeny 的唯一 fromEndpoints 中,同时设置 matchLabels 的 k8s:io.kubernetes.pod.namespace=cca-red 和 k8s:role=client。蓝方 client 应返回 200,stranger 和红方 client 应 timeout。
  8. 将工具的 report 命令结果保存到 /root/cca-policy/report.json。红方 client 向 baseline、union、deny 发出的三个请求应分别为 200、200、timeout。请在输出中对照当前 Pod 的 UID/IP/identity、策略 UID/spec 哈希、请求 source port,以及同一节点和时间的 Hubble FORWARDED/DROPPED 流量。如果修改了策略或 Pod,请重新生成报告。最终完整评分时,前面各步骤也必须全部保持有效。

参考

记录两个团队的实际 Pod 和安全身份

使用工具的 inventory 命令,将 11 个 Pod 的 namespace、name、uid、ip、identity 保存到 /root/cca-policy/inventory.json。cca-blue/client 和 cca-red/client 的 role 标签相同,但 namespace 标签和 identity 不同。请读取并比较输出中的实际值。如果 Pod 已被重新创建,也必须更新记录。

名称相同并不意味着是同一个端点。请同时查看 UID 和安全标签集合。

标准 NetworkPolicy 也通过标签进行选择

在 /root/cca-policy/native.yaml 中编写并应用 cca-blue 的 native-only NetworkPolicy。podSelector.matchLabels 为 target=native,policyTypes 为 [Ingress];唯一一条 ingress 中的唯一 from 只设置 podSelector.matchLabels.role=client。对于 native,只有蓝方 client 应返回 200,蓝方 stranger 和红方 client 应 timeout。无策略的 baseline 中三者都应返回 200。

不要把策略的目标选择器和入站对端选择器颠倒理解。请确认 peer 未设置 namespaceSelector 时的作用范围。

在 CNP 中也确认两个团队的边界

在 /root/cca-policy/ingress.yaml 中编写并应用 cca-blue 的 blue-ingress CiliumNetworkPolicy。endpointSelector.matchLabels.target=ingress;唯一一条 ingress 中的唯一 fromEndpoints 只设置 matchLabels.role=client。只有蓝方 client 应返回 200,stranger 和红方 client 应 timeout。不要删除 native 策略。

并不会仅仅因为名称是 CNP,就自动连接所有 namespace。也要保留另一个团队中具有相同 role 的对象作为对照请求来源。

复现 API 正常而只有名称解析被阻断的故障

在 /root/cca-policy/dns-blocked.yaml 中编写并应用 cca-blue 的 dns-blocked CNP。endpointSelector.matchLabels.client-mode=blocked。在唯一一条 egress 中,只设置 toEndpoints.matchLabels={role: api, target: egress} 和 toPorts.ports=[{port: "8080", protocol: TCP}]。不要添加 DNS 允许规则。dns-blocked 客户端通过 egress 服务器 IP 发出的请求应返回 200,通过 Service 名称发出的请求应 timeout。

服务器 egress Pod 在端口 8080 上充当对照组。如果缺少 DNS 时连直接使用 IP 的路径也被阻止,还需要检查选择器或方向。

在另一个对照客户端上仅添加 DNS 以恢复访问

在 /root/cca-policy/dns-open.yaml 中编写并应用 cca-blue 的 dns-open CNP。选择 client-mode=open。第一条 egress 项与上一步保持一致,使用同一个 API 目标和 TCP 8080。第二条的 toEndpoints.matchLabels 为 k8s:io.kubernetes.pod.namespace=kube-system 和 k8s:k8s-app=kube-dns,toPorts.ports 包含字符串 53 的 UDP 和 TCP 两项。dns-open 通过 IP 和名称访问都应返回 200。保留 dns-blocked 的限制。

不要开放所有外部连接,只允许名称解析端点和相应端口。请检查恢复用客户端的选择器。

新增允许规则后,另一个团队也获得访问权限

保留初始 blue-union CNP。在 /root/cca-policy/union.yaml 中编写并应用 cca-blue 的 red-union NetworkPolicy。选择 target=union,并设置 policyTypes=[Ingress]。在唯一一条 ingress 的唯一 from 中,同时设置 namespaceSelector.matchLabels.team=cca-red 和 podSelector.matchLabels.role=client。蓝方 client 和红方 client 应返回 200,stranger 应 timeout。

两个条件应放在同一个 peer 中,但已有 CNP 与新 NP 的允许规则会作为不同路径合并。

让显式拒绝优先于允许策略

保留初始 blue-deny CNP 和 red-deny NetworkPolicy。在 /root/cca-policy/deny.yaml 中编写并应用 cca-blue 的 deny-red CNP。选择 target=deny;在唯一一条 ingressDeny 的唯一 fromEndpoints 中,同时设置 matchLabels 的 k8s:io.kubernetes.pod.namespace=cca-red 和 k8s:role=client。蓝方 client 应返回 200,stranger 和红方 client 应 timeout。

如果通过删除允许策略来阻止红方团队,就无法再比较显式 deny 的优先级。请保留最初的两条允许规则。

使用当前策略和同一请求的流量编写故障报告

将工具的 report 命令结果保存到 /root/cca-policy/report.json。红方 client 向 baseline、union、deny 发出的三个请求应分别为 200、200、timeout。请在输出中对照当前 Pod 的 UID/IP/identity、策略 UID/spec 哈希、请求 source port,以及同一节点和时间的 Hubble FORWARDED/DROPPED 流量。如果修改了策略或 Pod,请重新生成报告。最终完整评分时,前面各步骤也必须全部保持有效。

不要随意附上一行 DROPPED。请匹配 TCP 源端口和两端的端点,并区分 HTTP 结果与数据包转发观测。