透明代理:cilium dns proxy

5 阅读4分钟

根据 Cilium 官方文档以及其核心架构设计,DNS Proxy 是实现基于域名(FQDN)网络策略的核心组件。其本质是通过 eBPF 透明拦截与**用户态代理(Envoy)**协作,动态地将域名解析结果映射为具体的 IP 地址,从而在内核态实现高效的 L3/L4 访问控制。

以下是 DNS Proxy 实现原理的详细分析:

1. 第一性原理:为什么需要 DNS Proxy?

在云原生环境中,服务的 IP 地址是动态变化的(如外部 API 服务、数据库集群)。传统的防火墙规则基于静态 IP,无法处理 FQDN。

Cilium 的解决思路是:实时“偷听” Pod 的 DNS 解析过程。 当 Pod 知道某个域名的 IP 时,Cilium 也要立刻知道,并动态地将这些 IP 填入该 Pod 的允许访问白名单中。


2. 核心组件与交互流程

实现 DNS Proxy 主要涉及三个部分:

  1. eBPF Datapath: 负责在内核层拦截出站的 DNS 流量(UDP/TCP 53 端口)。
  2. DNS Proxy (Envoy) : 一个运行在用户态的轻量级代理,负责处理 DNS 协议逻辑。
  3. Cilium Agent (FQDN Manager) : 维护域名与 IP 的映射关系,并更新内核 BPF Maps。

流程图示 (TXT):

Plaintext

[ Pod (Network Namespace) ]
      |
      | (1) 发起 DNS 请求 (例如: query google.com)
      v
[ eBPF Datapath (Host/Kernel) ]  <----------------+
      |                                           |
      | (2) 识别到目的端口 53                      | (7) 根据更新后的 Policy 
      |     触发 TPROXY 重定向                     |     放行后续数据流量
      v                                           |
[ Cilium DNS Proxy (Envoy) ]                      |
      |                                           |
      | (3) 转发请求至上游 DNS                      |
      | (4) 获得响应 (google.com -> 1.2.3.4)       |
      |                                           |
      | (5) 提取解析结果 (IP + TTL)                |
      +--------------> [ Cilium Agent ] ----------+
                             |
                             | (6) 更新 BPF Maps (IPCache)
                             |     将 1.2.3.4 关联至 google.com
      |                      v
      | (8) 将 DNS 响应原样返回给 Pod
      v
[ Pod (Network Namespace) ]

3. 详细实现步骤分析

A. 透明拦截 (Transparent Interception)

当 Pod 配置了 toFQDNs 策略时,Cilium Agent 会在 eBPF 程序中下发指令。对于该 Pod 发出的目的端口为 53 的流量,eBPF 不会直接路由转发,而是利用 TPROXY (Transparent Proxy) 机制将其重定向到节点上由 Envoy 监听的本地端口。

B. 协议解析与上下文提取

Envoy 的 DNS 过滤器接收到流量后:

  • 记录上下文:它知道这个请求来自哪个 Pod(通过源 IP 识别身份 ID)。
  • 上游查询:它充当递归或转发服务器,向集群配置的真正的 DNS Server 发起请求。

C. 动态策略注入 (Critical Step)

这是 DNS Proxy 的核心逻辑。当 Envoy 收到 DNS 响应后,它不会立即返回给 Pod,而是先执行以下操作:

  1. 解析响应报文:提取 A、AAAA 或 CNAME 记录。
  2. 通告 Agent:通过内部通道告知 Cilium Agent:“Pod A 刚刚解析了 google.com,得到的 IP 是 1.2.3.4,TTL 是 300 秒。”
  3. 更新白名单:Cilium Agent 验证该域名是否匹配 Pod 的 toFQDNs 策略。如果匹配,则将 1.2.3.4 插入到内核的 Policy Map 中,允许该 Pod 访问此 IP。

D. TTL 与缓存管理

为了保证安全性,Cilium 必须遵循 DNS 的 TTL(生存时间):

  • 过期删除:当 TTL 到期后,Cilium Agent 会从内核 Map 中删除对应的 IP 映射,除非 Pod 重新发起了解析。
  • 垃圾回收:Agent 会定期清理不再使用的域名记录。

4. 关键技术细节

  • CNAME 链条处理:如果 a.com CNAME 到 b.com,DNS Proxy 会跟踪整个链条,确保 Pod 最终获得的 IP 都在授权范围内。
  • 通配符支持:支持 *.example.com 这种策略。当 Pod 解析 api.example.com 时,Proxy 能够匹配通配符并放行。
  • 原子性保证:DNS 响应返回给 Pod 的时刻,与内核 eBPF 策略生效的时刻几乎同步,确保 Pod 拿到回复后立即发起的业务请求不会被拦截。

5. 总结

Cilium 的 DNS Proxy 实现逻辑是: “先拦截解析,后放行流量”

  1. 架构层次:eBPF 负责快速拦截(内核),Envoy 负责复杂协议解析(用户态),Agent 负责逻辑控制(管理面)。
  2. 安全性:这种方案避免了手动维护 IP 列表的繁琐,同时通过劫持解析过程,确保了策略的实时性和准确性。
  3. 可见性:通过这种方式,Cilium 还能提供详细的 DNS 查询日志(通过 Hubble 观测),记录哪个 Pod 在什么时候查询了哪个域名。