机场推荐网

DNS 泄露是什么,系统代理和 TUN 模式下各怎么查怎么修

开着代理时,境外网站的域名仍交给国内 DNS 解析,就是 DNS 泄露。只开系统代理时,源头多在内核为匹配规则做的解析;开了 TUN,要看每个程序的解析有没有被截住。

更新于 8 分钟读完作者 阿量参考了 10 份一手资料

程序连一个网站之前,要先问清这个域名对应哪个 IP,这一问一答就是 DNS 解析。代理开着,网页内容确实从节点走了,可这一问有时候照旧发给了国内的 DNS 服务器,没有加密,也不经过节点,对方看得到你问的是哪个域名。这就是 DNS 泄露

我对着 mihomo 的文档、Chromium 讲代理的那篇文档,还有 v2rayN 7.24.9 的界面文字,把这件事按两种模式拆开。只开系统代理和开了 TUN,漏的地方不一样,修的地方也不一样。

先测一次,看替你解析的服务器归谁

搜 DNS leak test 能找到好几个检测页,BrowserLeaks 的 DNS 页是其中之一。它让浏览器去解析 50 个随机生成的域名,一半只有 IPv4 地址,一半只有 IPv6 地址。这些域名只有它自己的服务器收得到查询,所以它知道是哪些 DNS 服务器替你来问的,页面上列出来的就是这些服务器的地址和归属。

看结果只问一件事,列表里有没有国内的服务器。你家宽带运营商的 DNS 算,阿里、腾讯这些国内公共 DNS 也算。测的全是境外域名,它们出现在国内服务器上,就是漏了。列出来的全是 Cloudflare、Google 这类境外服务,或者和你节点所在地区一致的机房,解析走的是代理那一侧。

单测一次不一定准,缓存会让结果慢半拍。改完设置等一两分钟,开个无痕窗口再测一次。

测完先弄清自己开的是哪种模式,系统代理还是 TUN,下面分开讲。

只开系统代理,漏的多半是内核自己的解析

Windows 的系统代理是 HTTP 代理。Chromium 的文档写得很干脆,Chrome 用 HTTP 代理时,域名解析一律交给代理去做。浏览器把完整的域名交给客户端,自己并不去问 DNS。

去问的是代理内核。mihomo 的规则文档里有这么一句,域名开始匹配目标 IP 类的规则时,会触发一次 DNS 解析,看这个域名的 IP 能不能对上。GEOIP、IP-CIDR 都属于这一类。订阅的规则表里常有一条 GEOIP,CN 放在中间,一个境外域名没被前面的域名规则接住,走到这一条,内核就得先把它解析出来。用哪台服务器解析,看配置里的 nameserver,这里填的是国内 DNS,泄露就出在这一步。

Clash Verge Rev 的,订阅页顶部有一排图标按钮,鼠标停上去显示查看运行时订阅的那个,点开是内核实际在用的整份配置。找到 dns: 那一段,看 nameserver 下面是谁。再往下翻到 rules:,看 IP 类规则排在哪里,后面带没带 no-resolve

no-resolve 在规则文档里的说明是跳过 DNS 解析,后面还跟着一句要紧的补充,更早的匹配里已经触发过解析的话,带 no-resolve 的目标 IP 规则照样会被匹配到。它只保证自己那一条不去解析,管不到排在上面的其他 IP 规则。

Clash Verge Rev 里改 DNS,用扩展覆写配置

机场订阅一般自带 dns: 段,直接改订阅文件,下次更新就被冲掉了。Clash Verge Rev 里有两个地方能改。一个是订阅卡片右键菜单里的扩展覆写配置,只管这一条订阅,每次更新后自动合并进去。另一个是设置页 Clash 设置下面的 DNS 覆写,弹窗里写着如果你不清楚这里的设置请不要修改,并保持 DNS 覆写关闭。

我建议用前一个。2.5.2 的源码里,扩展覆写配置和订阅是逐项深度合并的,只写要改的几项,其余照旧用订阅的。下面这几行把境外域名的解析交给境外的加密 DNS,国内域名仍用国内的。

dns:
  respect-rules: true
  default-nameserver:
    - 223.5.5.5
  proxy-server-nameserver:
    - https://dns.alidns.com/dns-query
  nameserver:
    - https://1.1.1.1/dns-query
    - https://dns.google/dns-query
  nameserver-policy:
    "geosite:cn":
      - https://dns.alidns.com/dns-query

每一项在 mihomo 的 DNS 文档里都有对应的说明。nameserver 是默认的域名解析服务器,没被别的项接走的域名都由它解析,所以填境外的。nameserver-policy 按域名指定解析服务器,可以用 geosite,这里把国内域名交给国内的服务。respect-rules 让 DNS 连接遵守路由规则,打开以后,发往 1.1.1.1 的查询也要过一遍规则,通常会落到代理上,文档注明它需要同时配好 proxy-server-nameserver。后者只用来解析代理节点自己的域名,那时候代理还没连上,所以用国内的服务。default-nameserver 用来解析上面这些 DNS 服务器的域名,文档要求必须是 IP。

v2rayN 的对应位置在设置菜单的 DNS 设置里,分成远程 DNS 和直连 DNS。两项的说明都写着默认只在路由阶段被调用解析,远程 DNS 还多一句请确保远程服务器可访问该 DNS,意思是这个查询是从节点那一侧发出去的。v2rayN 的下拉框里给远程 DNS 预设的是 Cloudflare、Google 这类境外 DoH,别把国内的地址填进去。

开了 TUN,每个程序的解析都得被截住

开 TUN、关掉系统代理以后,程序不再把域名交给代理,它们会自己向系统里设置的 DNS 发查询。这些查询要被虚拟网卡截下来,交给内核的 DNS 模块,mihomo 管这个的是 dns-hijack,Clash Verge Rev 的虚拟网卡模式设置里叫 DNS 劫持,常见的写法是 any:53

文档在这一项下面写了两条限制。一条是在 macOS 和 Windows 上,发往局域网的 DNS 请求无法自动劫持。不少家里的电脑把路由器当 DNS,地址是 192.168 开头的那种,这类查询就截不住,路由器通常再把它转给运营商的 DNS。Windows 上可以用下面这条命令看自己的 DNS 是谁。

ipconfig /all

DNS 服务器那一行要是局域网地址,mihomo 文档没有给现成的办法,Clash Verge Rev 的做法可以参考。它的 macOS 常见问题写着,开 TUN 时会把系统 DNS 改成 223.6.6.6,理由就是 TUN 截不住 macOS 上发往局域网的 DNS 请求,关掉 TUN 再改回来。Windows 上可以照这个思路,把网卡的 DNS 改成一个公网 IP,让查询走进虚拟网卡被截住,改完重新测一次。

另一条是安卓开了私人 DNS 就无法自动劫持,用安卓的在系统设置里把私人 DNS 关掉。

用 Windows 的,再把严格路由打开。文档对 strict-route 的说明是,它会添加防火墙规则,阻止 Windows 多网卡解析行为造成的 DNS 泄露,副作用是 VirtualBox 这类程序在某些情况下可能无法正常工作。电脑上跑着虚拟机的,开之前想一下。

浏览器也要看一眼。Chrome 有个使用安全 DNS 的开关,藏在设置里的隐私与安全,点进安全,在高级那一栏下面。帮助中心写明自动模式下它默认开启。TUN 模式下它会自己发加密查询,检测页显示的就是浏览器自己选的服务商。想看客户端的真实表现,测的时候先把它关了。只开系统代理时,前面说过浏览器把解析交给代理,这个开关不起作用。

fake-ip 能少问一次,也有两个副作用

enhanced-mode 设成 fake-ip 以后,程序来查域名,内核不去真的解析,直接回一个假地址,自己记下哪个假地址对应哪个域名,域名到底对应哪个 IP,留给节点那一端去查。TUN 模式下这能少掉本地一次真实查询。Fake-IP 的默认地址段是 198.18.0.1/16,所以开着它 ping 一个网站,看到 198.18 开头的地址是正常的。

副作用在两类东西上。局域网里的设备、网络对时这些服务,拿到假地址就不能用,它们的域名要写进 fake-ip-filter,在 Clash Verge Rev 的 DNS 覆写弹窗里叫 Fake IP 过滤。另一类是自己解析、只把 IP 交出来的程序,内核拿不到域名,域名规则就对不上,这属于某个 App 不走代理那篇讲的嗅探问题。

改完这些,回到开头那个检测页再测一次。国内的服务器从列表里消失,就算修好了。

常见问题

只开系统代理,会不会 DNS 泄露

Chrome 这一侧基本不会,Chromium 文档写明用 HTTP 代理时域名解析一律交给代理。会漏的是代理内核,mihomo 在匹配 GEOIP、IP-CIDR 这类规则时要先把域名解析出来,用的解析服务器是国内的,境外域名就漏了。查运行时配置里的 nameserver 和 IP 规则。

DNS 泄露检测列出阿里或腾讯的 DNS,算泄露吗

算。检测页让浏览器解析的全是它自己名下的境外域名,这些查询出现在阿里、腾讯的公共 DNS 上,说明国内解析服务知道了你在访问什么。国内公共 DNS 和运营商 DNS 在这件事上没有区别,都要让境外域名改走境外的解析服务器。

Clash Verge Rev 的 DNS 覆写要不要打开

多数人不用开。打开以后,弹窗里的设置会覆盖订阅自带的 DNS 配置,弹窗里自己就写着不清楚就保持关闭。只想改一两项,用订阅卡片右键菜单里的扩展覆写配置,Clash Verge Rev 会把它和订阅的配置逐项合并,没写到的项保持原样。

安卓手机用机场,要不要关掉私人 DNS

开着 TUN 类的客户端时建议关掉。mihomo 文档写明,安卓开启私人 DNS 以后无法自动劫持 DNS 请求,查询会绕过客户端直接发出去。私人 DNS 在系统设置里,不同品牌的位置不一样,在设置里搜私人 DNS 最快。

v2rayN 的远程 DNS 应该填什么

填境外的加密 DNS,比如 Cloudflare 或 Google 的 DoH 地址,下拉框里就有预设。v2rayN 对这一项的说明是默认只在路由阶段调用,并提醒要确保远程服务器可访问该 DNS。别把国内 DNS 填进远程 DNS,国内的那一栏叫直连 DNS。

参考来源

  1. mihomo 文档,DNS 配置
  2. mihomo 文档,TUN 入站
  3. mihomo 文档,路由规则与 no-resolve
  4. Chromium 文档,代理与域名解析
  5. BrowserLeaks 的 DNS 泄露检测页
  6. Chrome 帮助中心,使用安全 DNS
  7. Clash Verge Rev v2.5.2 源码,扩展覆写配置的合并方式
  8. Clash Verge Rev 文档,macOS 常见问题里 TUN 改系统 DNS 的说明
  9. Clash Verge Rev 仓库 v2.5.2 的中文界面文字
  10. v2rayN 7.24.9 的中文界面文字

更新记录

  • 首次发布