机场博客JICHANGBOKE.ORG

DNS 泄漏是什么,怎么查出来,怎么堵住

作者 塔台君发布 约 4 分钟读完

域名解析没走代理、仍然交给本地运营商的 DNS,这就是 DNS 泄漏。检测网站的结果里出现国内运营商的解析服务器,说明境外域名的查询漏了。客户端这边的处理是 DNS 开 fake-ip、境外解析走 DoH、按 IP 匹配的规则加 no-resolve。

代理开着,YouTube 能放,测速也有几十上百 MB/s。这时候打开一个 DNS 检测页面,表格里冒出两三行电信或者联通的服务器地址。网页内容那一段确实从节点走了,问「这个域名对应哪个 IP」的那一步没走。

解析和内容走的不是同一条路

浏览器要连一个站点,得先知道域名对应的 IP。这一问一答由 DNS 完成,传统 DNS 走 53 端口的明文 UDP,途中的设备都看得见你问了什么。

开了代理之后,这一步交给谁,由客户端的 dns 段决定。漏掉的情况在 Mihomo 系客户端里多半出在规则上。Mihomo 的规则文档写明,按目标 IP 匹配的规则,比如 GEOIP、IP-CIDR、IP-ASN,在域名开始匹配它们的时候会触发一次 DNS 解析,内核得先把域名变成 IP 才能判断这条规则中不中。这次解析要是交给了本地的解析服务器,域名就送出去了。

还有一种情况和规则无关。有些程序不读系统设置,自己把域名解析完,只把一个 IP 交给内核,域名规则全部落空。Mihomo 的域名嗅探就是为这种连接准备的,从 TLS 握手的 SNI 或者 HTTP 的 Host 里把域名读回来,详细情况在软件不走代理怎么办那篇里。

检测网站那张表怎么读

搜 DNS leak test 能找出好几个站点,做法一样。页面让你的浏览器去解析一批它自己名下的随机子域名,这些子域名只有它的权威服务器收得到查询,于是它能记下是哪些递归服务器替你来问的,再把这些服务器的 IP、归属地和运营商列出来。

读的时候盯住两件事。表里的服务器如果全在境外,或者归属地和你选的节点落地一致,说明境外域名的解析是从代理那一端出去的。出现国内运营商的地址,比如中国电信、中国联通、中国移动,境外域名的查询就漏到了本地。

有两点容易误判。国内域名交给国内 DNS 解析是分流的正常设计,测的是境外域名,别把国内那一半算进来。另外单次结果会受缓存影响,改完配置等一两分钟,换个浏览器窗口再测一遍,两次一致再下判断。术语表里的 DNS 泄漏那条写了同样的读法。

dns 段按这个写

下面这段给的是 Mihomo 内核的写法,Clash Verge Rev、FlClash、Clash Party 这些客户端都吃它。机场下发的订阅一般自带 dns 段,直接改订阅文件会在下次更新时被覆盖,Clash Verge Rev 里正确的位置是订阅卡片右键菜单的扩展配置,也叫 Merge 配置,它会在每次更新后合并进去。

dns:
  enable: true
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  fake-ip-filter:
    - "*.lan"
    - "+.local"
    - "time.*.com"
    - "+.pool.ntp.org"
  default-nameserver:
    - 223.5.5.5
    - 119.29.29.29
  nameserver:
    - https://1.1.1.1/dns-query
    - https://dns.google/dns-query
  proxy-server-nameserver:
    - https://223.5.5.5/dns-query
  nameserver-policy:
    "geosite:cn":
      - https://223.5.5.5/dns-query

逐行说一下依据。

default-nameserver 的文档原话是「必须为 IP, 可为加密 DNS」。它存在的理由很实际,上面 nameserver 里填的 DoH 地址本身是域名,总得有人先把这个域名解析出来,这个活就交给它,所以它只能填 IP。

nameserver 是境外域名的解析服务器。以 https:// 开头的是 DoH,tls:// 是 DoT,quic:// 是 DoQ。DoH 由 2018 年 10 月的 RFC 8484 定义,把每一对 DNS 查询和应答映射成一次 HTTP 交换,走 443 端口,媒体类型是 application/dns-message。这一段填境外的服务,DoH 那条术语里提醒过,填国内的 DoH,加密归加密,境外域名还是交给了国内解析。

proxy-server-nameserver 的文档说明是「仅用于解析代理节点的域名」。机场节点的服务器地址常常是域名,解析它的时候你还没连上代理,这一项就用来单独指定谁来解析,填国内的服务更快。

nameserver-policy 按域名指定解析服务器,文档注明可以用 geosite。上面这条把国内域名交给国内的 DoH。还有一个 respect-rules,打开后 DNS 连接会跟着分流规则走,文档写明用它必须同时配好 proxy-server-nameserver

fake-ip 的好处和它的副作用

enhanced-mode 有 fake-ip 和 redir-host 两个值,默认是 redir-host。切到 fake-ip 之后,程序查域名时内核不做真实解析,从 fake-ip-range 里分一个假地址返回并记下对应关系,连接带着域名去匹配规则,最后由节点那一端去解析。本地少了一次真实查询,泄漏的机会也就少了一处。

默认的这一段是 198.18.0.1/16。IANA 的 IPv4 特殊用途地址登记表里,198.18.0.0/15 这条名字写的是 Benchmarking,来源是 1999 年 3 月的 RFC 2544,登记的标志里 Globally Reachable 为 False。留给设备做基准测试的地址,正常上网不会碰到,拿来当假 IP 不会和真实站点撞车。所以开着代理 ping 一个域名,回来 198.18 开头的地址,那是对的。

副作用在 fake-ip-filter 上。局域网设备、网络时间同步、游戏主机的联网检测这类必须拿到真实 IP 的域名,拿到假地址会直接不工作,要写进这个列表。Fake-IP 那条术语里列了同样的注意事项。

规则里的 IP 条目要加 no-resolve

配完 dns 段,回头看规则。原则是域名规则排在 IP 规则前面,然后给 IP 规则加 no-resolve,文档对这个参数的说明是跳过 DNS 解析。

rules:
  - DOMAIN-SUFFIX,openai.com,PROXY
  - DOMAIN-SUFFIX,github.com,PROXY
  - GEOIP,CN,DIRECT,no-resolve
  - IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
  - MATCH,PROXY

这里有个坑,文档专门提了一句。如果前面已经有规则触发过 DNS 解析,域名仍然会去匹配带 no-resolve 的目标 IP 规则。也就是说 no-resolve 只管住它自己那一条,管不住列表上方的其他条目。规则表很长的时候,从上往下扫一遍,看看有没有哪条 IP 规则站在了域名规则前面。

开 TUN 的时候多两个开关

只开系统代理时,DNS 的去向由上面那段配置说了算。开了 TUN 模式,整机流量都进虚拟网卡,DNS 查询也要一起截住。

dns-hijack 负责这件事,写法是 any:53 或者 tcp://any:53,把发往 53 端口的查询交给内核自己的 DNS 模块。文档同时给了三条限制。macOS 和 Windows 上,发往本地网络 DNS 服务器的请求不会被自动拦截。安卓上开着私人 DNS,自动拦截也不生效。

Windows 用户还可以打开 strict-route,文档写的是在 auto-route 开启的前提下,Windows 上它会添加防火墙规则来阻止 DNS 泄漏。同一句话后面跟着一条提醒,某些情况下它会影响 VirtualBox。虚拟机跑着重要东西的话,先确认这一点。

浏览器和手机各有一份自己的 DNS

改完客户端,检测结果还是对不上,看这两处。

Chrome 的设置里有一项「使用安全 DNS」,路径是设置、隐私与安全、安全。官方帮助页写的是,在自动模式下这个功能默认开启,Chrome 在此模式下查找某个网站出问题时,会改用未加密模式再查一次。Edge 和 Firefox 都有对应的开关。想让检测结果反映客户端的设置,测之前先把浏览器这一处关掉。

安卓系统设置里的私人 DNS 是同一类东西,上一节引的 Mihomo 文档已经点名说它会让 TUN 的 DNS 拦截失效。iPhone 上的客户端多数不让改这么细,Shadowrocket、Stash 这类应用有自己的 DNS 设置页,能填的项比桌面少,按客户端自己的文档来。

堵住之后还能看到什么

泄漏堵住,本地运营商看不到你查过哪些域名了。它能看到的是你这台设备和某个境外 IP 一直在传加密流量,这一层代理和 VPN 都消不掉,两者的分工写在机场和 VPN 的区别里。

顺带说一句排障顺序。DNS 改坏了的典型表现是网页打不开但节点延迟正常,和别的原因长得像,先按连不上的排查顺序走一遍,确认是 DNS 这一段的事,再回来动上面这些配置。

常见问题

DNS 泄漏检测网站显示国内的 DNS 服务器,严重吗

要看漏的是哪些域名。境外域名的查询出现在国内运营商的服务器上,说明你访问过哪些站点对方能看到,网页内容走了代理也补不回来。国内域名交给国内 DNS 解析是分流的正常设计,不算泄漏。按文中的顺序改客户端的 dns 段和 IP 类规则,改完再测一次。

开了代理 ping 域名返回 198.18 开头的地址是不是出问题了

这是 fake-ip 模式的正常现象。Mihomo 的 fake-ip 默认从 198.18.0.1/16 里分配假地址,IANA 的登记表里这一段名字叫 Benchmarking,来自 RFC 2544,标注为不可全球路由,正常上网碰不到它,所以拿来当假 IP 不会撞车。必须拿到真实 IP 的域名写进 fake-ip-filter。

DoH 填了以后就不会泄漏了吗

不一定。DoH 由 2018 年 10 月的 RFC 8484 定义,它把查询塞进 443 端口的 HTTPS 请求,解决的是传输途中被人看到和改掉。填的要是国内的 DoH 服务,境外域名照样交给了国内那一端去解析,这一层 DoH 管不了。境外域名的解析服务器要选在境外。

开了 TUN 模式还会 DNS 泄漏吗

会,要看 dns-hijack 有没有一起打开。Mihomo 的文档写明,macOS 和 Windows 上发往本地网络 DNS 服务器的请求不会被自动拦截,安卓开了私人 DNS 也会让拦截失效。Windows 上可以再打开 strict-route,文档说明它会加防火墙规则来阻止 DNS 泄漏。

来源

DNS 泄漏Fake-IPDoHMihomo

接着读