Surge + UniFi 的 DoH DNS 防泄露配置实践
在同时使用 UniFi 网关和 Surge 的网络环境中,DNS 应该配置在哪里,很容易变得混乱。经过实际测试,我最终采用了一条简单的原则:没有开启本地代理时,由 UniFi 统一负责 DNS;开启 Surge 后,由 Surge 接管 DNS,并让 DoH 请求本身也经过代理。
核心原则真正影响 DNS Leak Test 结果的,不只是 DNS 服务商位于境内还是境外,更重要的是 DNS 请求最终从哪个网络出口发出。
本文只讨论我实际使用过的两种场景:UniFi 网关的加密 DNS,以及 Surge 接管 DNS 后的 DoH 转发。不同版本的 UniFi Network 和 Surge 可能存在界面或配置差异,请以当前版本的官方说明为准。
一、DNS 泄露是怎样产生的
假设设备当前通过香港、新加坡等境外代理访问网络,正常的网页流量路径是:
设备 ↓Surge ↓香港 / 新加坡代理节点 ↓Internet但如果 DNS 仍然从本地网络直连出去,路径就会变成:
设备 ↓DNS 请求 ↓DIRECT ↓本地运营商网络此时 DNS Leak Test 可能同时看到:
网页出口:香港 / 新加坡DNS Resolver:中国大陆这通常会被判断为 DNS 泄露。
这里需要区分两个概念:
- DoH 解决的是 DNS 查询内容在传输过程中是否加密;
- 代理 DoH 解决的是 DNS 请求从哪个网络出口发出。
因此:
使用 DoH ≠ DNS 一定不会泄露出口信息例如:
Surge ↓AliDNS DoH ↓DIRECT虽然 DNS 查询已经通过 HTTPS 加密,但访问 AliDNS 的连接仍然从真实网络出口发出。如果网页流量正在使用香港代理,DNS Leak Test 仍可能看到真实网络侧对应的 DNS Resolver。
我期望的结构是:
设备 ↓Surge ↓DoH ↓代理节点 ↓DNS Resolver“泄露”的具体含义DNS Leak Test 主要用于比较网页出口与解析器出口是否一致。测试结果中出现某个地区或运营商,并不等于 DNS 查询内容一定以明文传输;DoH 是否加密与 DoH 从哪个出口连接,是两个不同的问题。
二、未开启本地代理:由 UniFi 提供加密 DNS
如果电脑、手机等设备没有运行 Surge、Loon、Clash 等会接管 DNS 的代理程序,最简单的方案就是让 UniFi 统一负责 DNS:
电脑 / 手机 / 平板 ↓ UniFi ↓ Encrypted DNS ↓ AliDNS / DNSPod这样整个局域网只需要在 UniFi 上配置一次,无须在每台设备中重复设置 DoH。
UniFi 配置方法
进入 UniFi Network:
设置→ CyberSecure→ 加密 DNS将模式设置为:
预定义然后添加:
Alidns-dohDnspod应用配置后,DNS 路径为:
客户端 ↓UniFi Gateway ↓AliDNS / DNSPod DoH在我的网络环境中,这种配置可以正常通过 DNS Leak Test。对于没有运行本地代理的设备,没有必要再分别在 Windows、macOS 或 iPhone 上叠加另一套 DoH;直接由 UniFi 统一负责,结构更简单,也更容易排查。
三、为什么开启 Surge 后,UniFi 的 DNS 看起来“不生效”
当 Surge 开启 Enhanced Mode 或 DNS 接管后,DNS 路径会发生变化。
原本的路径是:
Mac ↓UniFi ↓Encrypted DNS开启 Surge 后则会变成:
Mac ↓Surge ↓Surge 自己的 DNS这并不代表 UniFi 的加密 DNS 失效,而是这台设备的 DNS 已经在到达 UniFi DNS 之前被 Surge 接管。
因此可能出现以下现象:
UniFi 已正确配置 Encrypted DNS+Surge 已开启 ↓DNS Leak Test 仍显示异常彻底关闭 Surge 后,路径重新回到:
Mac ↓UniFi ↓Encrypted DNS如果此时 DNS Leak Test 恢复正常,真正需要调整的就是 Surge 的 DNS 配置,而不是继续修改 UniFi。
四、Surge 中仅配置 DoH 还不够
这是我在实际测试中最重要的发现。
我分别测试了境内和境外的 DoH 服务:
| 服务 | DoH 地址 |
|---|---|
| AliDNS | https://dns.alidns.com/dns-query |
| DNSPod | https://doh.pub/dns-query |
| Cloudflare | https://cloudflare-dns.com/dns-query |
https://dns.google/dns-query |
测试结果如下:
| DoH | DIRECT | 经过代理 |
|---|---|---|
| AliDNS | 可以正常解析,但 DNS Leak Test 显示真实网络侧的解析器 | 正常 |
| DNSPod | 可以正常解析,但 DNS Leak Test 显示真实网络侧的解析器 | 正常 |
| Cloudflare | 在我的网络环境中可能无法正常使用 | 正常 |
| 在我的网络环境中可能无法正常使用 | 正常 |
这说明决定测试结果的关键并不是:
境内 DNS vs. 境外 DNS而是:
DoH → DIRECTvs.DoH → Proxy经过代理后,无论是 AliDNS、DNSPod,还是 Cloudflare、Google,都可以在我的环境中正常作为 DoH 使用。因此我最终准备了四个端点,并让它们全部通过 Surge 的代理策略发送:
https://dns.alidns.com/dns-queryhttps://doh.pub/dns-queryhttps://cloudflare-dns.com/dns-queryhttps://dns.google/dns-query五、Surge 的最终 DNS 配置
在 Surge 配置文件的 [General] 中加入:
[General]
dns-server = 223.5.5.5, 119.29.29.29encrypted-dns-server = https://dns.alidns.com/dns-query, https://doh.pub/dns-query, https://cloudflare-dns.com/dns-query, https://dns.google/dns-queryencrypted-dns-follow-outbound-mode = truehijack-dns = *:53其中最关键的是:
encrypted-dns-follow-outbound-mode = true启用后,加密 DNS 请求可以遵循 Surge 的出站模式并进入规则系统。然后在 [Rule] 中加入:
[Rule]
PROTOCOL,DOH,你的代理策略例如:
PROTOCOL,DOH,⚡ 自动选择这样,DoH 请求会交给指定的代理策略:
AliDNS ────────┐DNSPod ────────┤Cloudflare ────┤Google ────────┘ ↓ Surge ↓ 代理策略 ↓ 代理节点 ↓ DNS Resolver这是我目前在 Surge 上实际验证可以消除上述 DNS 出口不一致问题的配置。
替换策略名称
你的代理策略和⚡ 自动选择都只是示例。请替换为配置文件中真实存在且可用的策略组名称,否则规则无法按预期工作。
六、dns-server 与 encrypted-dns-server 的区别
配置中同时存在:
dns-server = 223.5.5.5, 119.29.29.29以及:
encrypted-dns-server = ...两者并不冲突。
正常的域名解析主要交给 encrypted-dns-server,也就是前面配置的四个 DoH;普通的 dns-server 则保留用于基础解析、引导等用途。
这一点很重要,因为代理节点本身也可能依赖 DNS。例如代理服务器填写的是:
node.example.comSurge 必须先得到该域名对应的 IP,才能连接代理节点。如果所有 DNS 都要求先经过代理,就可能形成循环依赖:
建立代理 ↓需要先解析节点域名
使用 DoH ↓又要求代理已经建立因此,保留普通 DNS 可以为代理初始化和 DoH 引导解析提供一条基础路径。
普通 DNS 的边界保留
dns-server是为了处理引导和基础解析,不代表所有正常查询都会绕过encrypted-dns-server。实际行为还会受到 Surge 版本、运行模式、缓存和具体配置影响。
七、代理 DoH 的启动依赖问题
即使已经配置:
dns-server = 223.5.5.5, 119.29.29.29encrypted-dns-follow-outbound-mode = true并使用:
PROTOCOL,DOH,你的代理策略在切换 Surge 配置文件时,我仍然偶尔会遇到:
配置刚切换 ↓所有节点超时 ↓网页完全无法访问这通常与配置重新加载阶段的启动依赖有关:
DNS 需要代理+代理初始化又需要 DNS我的临时处理方法是:
切换配置 ↓如果所有节点超时 ↓将 DoH 策略临时切换为 DIRECT ↓等待代理节点恢复 ↓再将 DoH 切回 ProxySurge 正常运行后,让 DoH 全部经过代理可以稳定工作。这里需要区分:启动阶段的循环依赖与正常运行时的 DNS 防泄露是两个问题。
如果这个问题频繁出现,也应检查代理节点域名能否通过基础 DNS 正常解析、策略组是否可用,以及当前 Surge 版本是否改变了加密 DNS 的初始化行为。
八、hijack-dns = *:53 的作用
我在 Surge 中保留了:
hijack-dns = *:53它的作用不是阻止 DNS,而是将传统 DNS 请求接管到 Surge:
应用 ↓8.8.8.8:53 ↓Surge Hijack ↓Surge DNS ↓DoH ↓代理这与在防火墙中阻止 TCP/UDP 53 完全不同:
| 配置 | 行为 |
|---|---|
hijack-dns = *:53 | 接管传统 DNS,并交给 Surge 继续解析 |
| 防火墙阻止 TCP/UDP 53 | 直接丢弃匹配的 DNS 流量 |
对于由 Surge 负责 DNS 的设备,DNS Hijack 可以减少应用绕过系统 DNS、直接查询传统 DNS 服务器的情况。
它不能接管所有加密 DNS
hijack-dns = *:53针对传统 53 端口 DNS。应用自带的 DoH、DoT、私有 VPN DNS 或其他非 53 端口解析,不一定会被这项配置接管。
九、境内与境外 DoH 应该怎样选择
我的最终配置同时使用:
- AliDNS;
- DNSPod;
- Cloudflare;
- Google。
AliDNS 和 DNSPod 在中国大陆网络中通常具有较好的直连可达性;Cloudflare 和 Google 则提供另外两组独立的解析来源。
不过,在开启 Surge 后,我不会让其中任何一个 DoH 使用 DIRECT,而是统一交给代理策略:
AliDNS → ProxyDNSPod → ProxyCloudflare → ProxyGoogle → Proxy因此,“境内还是境外”不再是最关键的问题。更重要的是同时确认:
DNS 查询是否加密+DoH 请求是否经过预期的代理出口需要注意,多配置几个 DoH 端点并不自动等于更快或更可靠。最终效果仍取决于 Surge 的选择逻辑、代理节点质量、解析器响应,以及具体网络环境。
十、最终推荐架构
整个方案可以简化成两种状态。
不使用本地代理
直接交给 UniFi:
设备 ↓UniFi ↓CyberSecure ↓Encrypted DNS ↓AliDNS / DNSPodUniFi 配置路径:
CyberSecure→ 加密 DNS→ 预定义→ Alidns-doh→ Dnspod使用 Surge
由 Surge 负责设备上的 DNS:
设备 ↓Surge ↓DoH ↓Proxy ↓DNS Resolver[General] 配置:
[General]
dns-server = 223.5.5.5, 119.29.29.29encrypted-dns-server = https://dns.alidns.com/dns-query, https://doh.pub/dns-query, https://cloudflare-dns.com/dns-query, https://dns.google/dns-queryencrypted-dns-follow-outbound-mode = truehijack-dns = *:53[Rule] 配置:
[Rule]
PROTOCOL,DOH,你的代理策略例如:
PROTOCOL,DOH,⚡ 自动选择最终路径为:
AliDNS ────────┐DNSPod ────────┤Cloudflare ────┤Google ────────┘ ↓ Proxy十一、如何判断问题在 UniFi 还是 Surge
实际排查时,最有效的方法之一就是做简单的对照测试。
先保持 Surge 开启,运行 DNS Leak Test;如果结果异常,再彻底关闭 Surge 并重新测试。
如果结果是:
Surge 开启 → DNS 出口异常Surge 关闭 → DNS 恢复正常基本可以判断:
UniFi 的加密 DNS 路径可以工作问题更可能在 Surge 的 DNS 配置或出站策略因为关闭 Surge 后,DNS 已经重新回到:
设备 ↓UniFi ↓Encrypted DNS反过来,如果关闭 Surge 后仍然异常,再去检查 UniFi 的 Encrypted DNS 是否正确启用。
建议的验证步骤
为了减少缓存和连接复用造成的干扰,可以按以下顺序测试:
- 记录当前代理节点及其出口地区;
- 开启 Surge,清理系统与浏览器 DNS 缓存后运行 DNS Leak Test;
- 确认测试页面的公网出口确实属于当前代理节点;
- 彻底关闭 Surge,再次清理缓存并运行同一项测试;
- 比较两次测试中的公网出口和 DNS Resolver;
- 必要时更换测试网站复核,避免只依赖单一检测服务。
不要只看系统 DNS 地址Surge 接管 DNS 后,系统设置中显示的 DNS 地址不一定代表请求最终使用的解析器或网络出口。对照测试比只查看系统 DNS 地址更直观。
总结
这套配置最终可以归结为一个原则:
谁接管 DNS,就在谁那里解决 DNS 防泄露。没有本地代理时:
UniFi 接管 DNS→ 使用 CyberSecure Encrypted DNS开启 Surge 时:
Surge 接管 DNS→ 使用 DoH→ DoH 本身也经过代理在我的实际测试中:
AliDNS / DNSPod→ DIRECT→ 可以正常解析,但 DNS Leak Test 显示真实网络侧的解析器
Cloudflare / Google→ DIRECT→ 在当前网络环境中可能无法正常使用
AliDNS / DNSPod / Cloudflare / Google→ 全部交给 Proxy→ DNS Leak Test 正常所以我最终使用的架构是:
没有 Surge:UniFi → AliDNS / DNSPod DoH
开启 Surge:Surge → AliDNS + DNSPod + Cloudflare + Google DoH → 全部经过代理相比在操作系统、路由器和代理客户端之间同时堆叠大量 DNS 设置,这种分工更容易理解,也更容易定位问题。