Hotdry.
security

Netfence eBPF 过滤器的 DNS 解析与 IP 同步机制

解析 Netfence 如何将域名规则转换为 eBPF IP 过滤策略,聚焦增量更新闭环、TTL 过期机制与 specificity 匹配的工程实践。

在云原生环境中,基于 eBPF 实现网络过滤已成为一种高效且灵活的方案。传统的 iptables 或 nftables 规则管理需要在每台主机上单独配置,且缺乏统一的策略同步机制;而直接在内核层面编写 eBPF 程序又面临部署复杂、更新困难的问题。Netfence 采用类似 Envoy xDS 的控制平面模式,通过 gRPC 双向流将策略下发至各主机 Daemon,再由 Daemon 自动完成 DNS 解析与 IP 过滤规则的填充。这种架构将策略定义与内核实现解耦,使得运维团队可以像配置服务网格一样管理网络过滤规则。本文将深入剖析这一机制的核心实现细节,包括域名 specificity 匹配、DNS 解析到 eBPF 映射的增量闭环,以及 CIDR 条目的 TTL 管理策略。

架构设计:从控制平面到内核过滤

Netfence 的整体架构由三个核心组件构成:用户自主实现的控制平面、各主机上运行的 Daemon 进程,以及挂载在网络路径上的 eBPF 过滤程序。控制平面通过 gRPC 双向流与所有 Daemon 保持长连接,接收来自 Daemon 的同步请求、附件订阅与心跳信息,并向 Daemon 推送网络策略变更。Daemon 进程负责管理本地 eBPF 程序的加载与卸载,同时为每个网络附件(Attachment)提供一个独立的本地 DNS 服务端口。当容器或虚拟机需要访问某个域名时,它们首先向该附件专属的 DNS 服务器发起查询,Daemon 根据控制平面下发的域名规则决定是否解析,并将解析得到的 IP 地址自动填充至 eBPF IP 过滤表中。

这种设计的关键优势在于将「域名策略」与「IP 过滤」两层逻辑分离。控制平面只需下发简洁的域名规则,如「允许 *.pypi.org」或「禁止 ads.example.com」,无需关心底层 IP 地址的变化。Daemon 在运行时自动处理 DNS 解析与 IP 缓存,使得策略更新与网络拓扑变化解耦。对于需要严格控制出站流量的多租户环境,这一特性显著降低了策略管理的复杂度。Daemon 与控制平面之间的通信采用流式推送模式,控制平面可以实时下发新的域名规则或 CIDR 条目,Daemon 在接收到变更后立即更新本地 eBPF 程序状态,整个过程的延迟取决于 gRPC 消息的处理开销,通常在毫秒级别完成。

域名匹配与优先级机制

在多域名规则共存的场景下,如何确定某次 DNS 查询应当应用哪条规则,直接影响过滤行为的正确性。Netfence 采用 specificity-based 匹配策略,即更具体的域名规则优先于更宽泛的规则生效。例如,当控制平面同时下发了「允许 example.com」与「允许 api.example.com」两条规则时,针对「api.example.com」的查询将优先匹配后者,而针对「www.example.com」的查询则匹配前者。这种层级化的匹配机制类似于 DNS 本身的域名解析逻辑,支持子域名从父域名继承权限,同时允许通过更具体的规则进行覆盖或排除。

在实现层面,Daemon 接收到 DNS 查询请求后,首先将查询的完整域名与已缓存的域名规则列表进行逐层匹配。匹配过程从完整域名开始,依次尝试去掉最左侧的标签(如从「api.prod.example.com」依次尝试「api.prod.example.com」「prod.example.com」「example.com」「」),直到找到匹配的规则或遍历完所有规则。这种线性搜索在规则数量较少时性能可接受,但当域名规则达到数千条时可能成为瓶颈。实践中建议将高频查询的子域名规则置于规则列表的前部,或通过哈希索引优化匹配效率。Netfence 的规则存储结构对性能敏感的场景进行了优化,但具体实现细节需参考 Daemon 的源码配置。

DNS 解析到 eBPF 映射的增量闭环

当 DNS 查询通过域名规则校验后,Daemon 需要将解析得到的 IP 地址填充至 eBPF 过滤表。这一过程涉及 DNS 解析、IP 去重、eBPF 映射更新三个步骤,每一步都影响着数据一致性与更新效率。Daemon 内置一个轻量级 DNS 解析器,支持 A 记录与 AAAA 记录的查询,解析结果随后与当前缓存的 IP 集合进行比对,仅新增的 IP 地址会被写入 eBPF 映射。对于已存在的 IP 地址,跳过重复写入以避免不必要的内核映射更新操作。

增量更新的设计目标是避免全量同步带来的性能开销。在大规模场景下,单个 Daemon 可能需要管理数万个 IP 条目,每次策略变更都全量替换映射内容会导致 eBPF 程序重新验证、内核锁竞争以及短暂的过滤窗口。Netfence 通过 delta update 模式,仅将变更的 CIDR 条目推送至 eBPF 映射。控制平面下发的「AllowCIDR」与「DenyCIDR」消息携带具体的网络前缀与可选的 TTL,Daemon 在接收到后立即执行映射的插入或删除操作。对于被多个域名解析共用的 IP 地址,去重逻辑确保仅存在一条映射条目,避免存储空间的浪费与过滤规则的歧义。然而,当同一 IP 被不同的域名分别「允许」与「拒绝」时,优先级的判定取决于控制平面下发的顺序与模式配置,这一点需要在策略设计阶段明确。

TTL 管理是增量闭环中的另一关键机制。动态 IP 地址的解析结果并非永久有效,CDN 服务或云厂商的负载均衡器可能随时变更 IP 映射。Netfence 支持在 CIDR 规则中指定 TTL(单位为秒),Daemon 在填充 IP 映射时会记录对应的过期时间戳。当 TTL 到期后,映射条目自动失效,后续对该 IP 的访问将被拦截,直到域名再次解析出新的地址。这一机制有效应对了 IP 地址的动态变化场景,减少了手动清理失效条目的运维负担。对于未指定 TTL 的 CIDR 条目,条目将永久保留,需要通过显式的「RemoveCIDR」消息进行删除。

落地参数与监控建议

在生产环境中部署 Netfence 时,以下工程参数可作为初始配置的参考依据。TTL 的设置需要平衡安全性与可用性,过于激进的短 TTL(如 60 秒以内)会导致 DNS 查询频率升高,增加解析延迟并可能触发上游 DNS 服务器的限流;过于保守的长 TTL(如 3600 秒以上)则使得 IP 地址变更后的生效时间延长,期间可能出现访问被错误拦截的情况。对于面向公网的服务,建议将 TTL 设置在 300 秒至 600 秒区间;对于内部服务或 IP 相对稳定的场景,可适当延长至 1800 秒或更长。单台 Daemon 管理的 CIDR 条目规模建议控制在 10000 条以内,超出此规模后 eBPF 映射的查找性能可能出现明显下降,此时应考虑通过命名空间或附件隔离的方式分散负载。

监控指标方面,应重点关注三类数据:控制平面与 Daemon 之间的 gRPC 连接状态与消息延迟、eBPF 映射的条目数量与变更速率,以及 DNS 查询的命中率与被拦截流量比例。gRPC 连接的健康状况直接影响策略下发的及时性,断连或重连过程中的状态同步需要特别关注。eBPF 映射条目数量的异常增长可能暗示 DNS 解析的循环或缓存泄漏,需要及时排查。DNS 查询被拦截的比例反映了策略配置的合理性,初期部署时可能出现较高的误拦率,需要根据业务流量日志持续调优规则。Netfence 的 Daemon 在启动时会暴露 Prometheus 格式的指标端点,可直接对接现有的监控基础设施。

适用场景与演进方向

Netfence 的设计特别适用于以下几类场景:多租户云环境中的网络隔离与出站控制、服务网格或服务发现系统中的细粒度流量策略,以及对性能敏感且需要在内核层面实现过滤的安全网关。在这些场景中,传统的 iptables 规则管理难以应对策略的频繁变更,而基于用户空间代理的方案又引入了不可忽视的延迟。eBPF 过滤程序在数据包进入网络栈的早期阶段即可完成决策,将被拦截的流量在占用任何内核资源之前丢弃,实现了真正的「零损耗」过滤。

从演进方向来看,Netfence 未来可能在以下方面增强能力:更丰富的域名匹配语法(如正则表达式或通配符组合)、与现有服务网格(如 Istio 或 Linkerd)的集成点,以及针对 IPv6 场景的优化。此外,DNS 解析结果的持久化与跨 Daemon 共享缓存也是值得考虑的方向,可以避免重复解析同一域名带来的延迟与上游 DNS 服务器压力。对于希望在内核层面实现灵活网络控制、同时保持策略管理便捷性的团队,Netfence 提供了一个值得参考的实现范式。


资料来源

查看归档