跳转到正文

工作原理

dae 通过 eBPF 将程序加载到 Linux 内核的 tc(流量控制)挂载点运行。该程序会在流量进入 TCP/IP 网络栈前进行分流。下图展示 tc 在 Linux 网络协议栈中的位置(图示为接收路径,发送路径方向相反),其中 netfilter 表示 iptables/nftables 所在的位置。

网络栈路径网络栈路径

流量分流原理

分流条件

dae 支持按域名、源 IP、目的 IP、源端口、目的端口、TCP/UDP、IPv4/IPv6、进程名、MAC 地址等因素分流。

其中,源 IP、目的 IP、源端口、目的端口、TCP/UDP、IPv4/IPv6 和 MAC 地址可通过解析 MACv2 帧获得。

进程名通过监控 cgroupv2 挂载点中的本地进程 socket、connect 和 sendmsg 系统调用获得。随后读取并解析进程控制块中的命令行。此方法显著快于 Clash 等通过扫描整个 procfs 获取进程信息的用户空间程序(后者甚至可能耗时数十毫秒)。

域名通过拦截 DNS 请求,并将请求的域名与相应 IP 地址关联获得。但此方法有一些潜在问题:

  1. 可能导致误判。例如,在短时间内同时访问共用同一 IP 地址的国内和国外网站,或浏览器使用 DNS 缓存时。
  2. 用户的 DNS 请求必须经过 dae。可通过将 dae 设为 DNS 服务器,或在 dae 作为网关时使用公共 DNS 实现。

尽管有这些挑战,与其他方法相比,这种方法已是最优方案。例如,Fake IP 方法无法按 IP 分流,并且存在严重的缓存污染问题。同样,域名嗅探只能拦截 TLS/HTTP 等流量。虽然使用 SNI 嗅探进行流量分流有效,但 eBPF 对程序复杂度的限制以及不支持循环,使我们无法在内核空间实现域名嗅探。

因此,如果 DNS 请求无法经过 dae,基于域名的分流将无法成功。

为缓解 DNS 污染并提高 CDN 连接速度,dae 在用户空间使用域名嗅探。当 dial_mode 设置为 "domain" 或其变体且需要处理代理流量时,dae 会将嗅探到的域名而非 IP 地址发送给代理服务器。因此,代理服务器会重新解析域名,并使用最优 IP 连接。该方法解决 DNS 污染并提高 CDN 连接速度。

此外,已使用其他分流方案且不希望将 DNS 请求路由至 dae、但仍希望某些流量按域名分流的高级用户(例如按目标域名分流 Netflix 节点与下载节点的流量,部分流量通过核心直连),可通过设置 dial_mode: domain++ 强制使用嗅探到的域名进行分流。

dae 通过 tc 挂载点的程序重定向流量实现分流。重定向基于分流结果:将流量重定向至 dae 的 tproxy 端口,或让其绕过 dae 直接通过。

代理机制

dae 的代理机制与其他程序相似。不过,绑定 LAN 接口时,dae 利用 eBPF 在 tc 挂载点将待代理流量的 socket buffer 直接关联到 dae tproxy 监听端口的 socket。绑定 WAN 接口时,dae 将待代理流量的 socket buffer 从网卡的出口队列转移到入口队列,同时禁用校验和,并将目的地址改为 tproxy 监听端口。

从基准测试看,dae 的代理性能略高于其他代理程序,但差异不显著。

PR:implement stack bypass 起,劫持数据路径已改为绕过协议栈,以获得更好的性能并减少协议栈的影响(例如 netfilter、systemd-sysctl)。请参阅 PR 描述以进一步了解。

直连机制

传统上,流量分流会让流量经过代理程序、进入分流模块,然后决定使用代理还是建立直连。此过程要求流量经网络栈解析、处理和复制后送入代理程序,随后又经网络栈复制、处理和封装后发出。这会消耗大量资源。特别是在 BitTorrent 下载等场景中,即使设为直连,仍会消耗大量连接、端口、内存和 CPU 资源。由于代理程序处理不当,它甚至可能在游戏场景影响 NAT 类型,从而导致连接错误。

dae 在更早的内核阶段进行流量分流,通过第 3 层路由转发直连流量。该方法通过减少内核与用户空间之间的切换来降低开销。此时 Linux 的作用是纯交换机或路由器。

为实现有效直连,具有特定网络拓扑的高级用户应确保:配置内核参数禁用 dae 后,当将装有 dae 的设备设为网关时,其他设备仍可正常访问网络。例如,访问 223.5.5.5 应返回 "UrlPathError" 响应。在装有 dae 的设备上执行 tcpdump 时,应能看到客户端设备发出的请求数据包。

因此,dae 不会对直连流量执行 SNAT。在“旁路由”设置中,这会导致非对称路由。在此场景中,客户端设备发出的流量经 dae 到达网关,而接收流量则从网关直接到达客户端设备,绕过 dae。

此处“旁路由”是指:1)作为网关运行;2)对 TCP/UDP 执行 SNAT;3)LAN 和 WAN 接口位于同一网段。

例如,笔记本电脑为 192.168.0.3,旁路由为 192.168.0.2,路由器为 192.168.0.1,则逻辑三层拓扑为:笔记本电脑 -> 旁路由 -> 路由器。在路由器侧,只能看到源 IP 为 192.168.0.2 的 TCP/UDP 流量,不会看到源 IP 为 192.168.0.3 的 TCP/UDP 流量。

据我们所知,我们是这个“旁路由”定义的先驱(笑)。

非对称路由带来一个优势和一个潜在问题:

  1. 可提高性能。由于返回流量不经过 dae,直连性能与没有旁路由时一样快,路径也更短。
  2. 可能破坏有状态防火墙的状态维护并造成丢包(例如 Sophos Firewall)。不过,家庭网络通常不会出现此问题。

从基准测试角度看,dae 的直连性能相对于其他代理方案表现强劲。


来源:dae 上游文档 · AGPL-3.0 许可证