很多朋友装好我之后网页照样打不开,最后发现问题不在节点,而在 DNS——域名一开始就被解析到了错误的 IP,代理做得再好也白搭。这篇文章讲清楚我的 DNS 模块该怎么配,把污染和泄露两个坑一次填平。

为什么 DNS 需要特殊处理

正常上网时,浏览器先问 DNS 服务器"这个域名的 IP 是多少",再向那个 IP 发起连接。问题出在两个环节:

  • DNS 污染:使用运营商 DNS 查询某些域名时,返回的是伪造的 IP,连接自然失败或超时。
  • DNS 泄露:流量走了代理,但 DNS 查询还在本地明文发出,等于把你访问了哪些网站原样广播出去。

所以我内置了一个 DNS 模块:开启后,设备上所有 DNS 查询都先经过我,由我决定用哪台服务器解析、要不要通过代理去解析。

fake-ip 与 redir-host 的区别

enhanced-mode 有两个取值,决定了我怎么回答系统的 DNS 查询:

模式工作方式优缺点
fake-ip 立刻返回一个保留段假 IP(198.18.x.x),真正的解析推迟到建立连接时进行 响应快、无泄露;个别检测真实 IP 的程序(如某些游戏、网银)可能不兼容
redir-host 老老实实查出真实 IP 再返回 兼容性最好;但解析结果可能被污染,且规则匹配时机更晚

结论:日常首选 fake-ip。遇到不兼容的应用,用 fake-ip-filter 把它排除掉即可,不必整体退回 redir-host:

fake-ip-filter 示例
dns:
  enhanced-mode: fake-ip
  fake-ip-filter:
    - "*.lan"
    - "+.stun.*.*"
    - "+.battle.net"       # game launchers often need real IP
    - "time.windows.com"

nameserver 与 fallback 的分工

这是整个 DNS 配置里最容易配错的部分。正确的心智模型是:

  • nameserver:主力解析组,放国内大厂 DNS(阿里、腾讯),解析国内域名又快又准。
  • fallback:备用解析组,放海外加密 DNS(DoH/DoT),专门处理可能被污染的境外域名。

两组会并发查询。当查询结果命中 fallback-filter 的条件(比如解析出的 IP 不在中国大陆),我就采用 fallback 的结果,从而避开污染:

推荐的完整 DNS 配置
dns:
  enable: true
  listen: 0.0.0.0:53
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  nameserver:
    - 223.5.5.5                       # AliDNS
    - 119.29.29.29                    # DNSPod
  fallback:
    - https://1.1.1.1/dns-query       # Cloudflare DoH
    - https://dns.google/dns-query    # Google DoH
  fallback-filter:
    geoip: true
    geoip-code: CN
    ipcidr:
      - 240.0.0.0/4                   # bogus IPs returned by poisoning

这份配置的效果:国内域名走阿里/腾讯 DNS 秒解析;境外域名一旦解析结果可疑,自动改用加密 DNS 的结果,污染防住了,查询也不明文外泄。

如何验证配置生效

  1. 打开控制面板的「日志」页,把级别调到 debug,能看到每条 DNS 查询用了哪个服务器。
  2. 访问 dnsleaktest.com 做泄露测试:显示的 DNS 服务器应该是你 fallback 里配置的(或节点侧的),而不是本地运营商。
  3. nslookup 查一个已知被污染的域名,返回 198.18 开头的假 IP 说明 fake-ip 在正常工作。
常见坑 改完 DNS 配置后记得重载配置并清空浏览器 DNS 缓存(Chrome 地址栏输入 chrome://net-internals/#dns);安卓端还要重启一次 VPN 连接才会全部生效。

路由器全局代理下要多留意什么

如果我跑在路由器或者 NAS 上,给全屋设备做透明代理,DNS 配置的重要性会再上一个台阶——因为这时候没有"客户端自己解析"这个退路,所有设备的域名解析都要经过我一道关。这种场景下有两点建议:

  • listen 绑定到局域网网卡:默认只监听 127.0.0.1 的话,其他设备的 DNS 请求根本进不来,记得改成 0.0.0.0:53 并在路由器的 DHCP 选项里把网关同时设置成 DNS 服务器。
  • 给智能电视、游戏机单独开白名单:这类设备的联网校验逻辑往往比较死板,一旦 DNS 结果和它预期的地理位置不符就直接罢工,遇到这种情况优先加进 fake-ip-filter,而不是关掉整屋的 fake-ip。

另外提一句,很多人喜欢直接填 8.8.8.8 当主 DNS,图个简单省事。但国内网络访问 Google DNS 本身就可能绕路或超时,拿它做主力解析反而更慢——记住之前那条分工原则:nameserver 交给国内大厂 DNS,fallback 才轮到加密 DNS 出场。

两个常见误解

最后澄清两个新手常有的误会,省得走弯路:

  1. "开了 fake-ip 我就再也看不到真实 IP 了"——不是的,fake-ip 只是把系统层面看到的 IP 换成了假地址,我内部依然会在建立连接时完成真实解析,日志和连接页面照样能看到目标真实 IP,不影响你排查问题。
  2. "DNS 配置越复杂越安全"——恰恰相反,nameserver 和 fallback 各放两三个足够用,塞太多服务器只会拖慢首次查询的耗时(因为要等并发结果),简洁清晰远比"大而全"更实用。

把这份 DNS 配置抄进你的 config.yaml,重载一次,基本上就能和污染、泄露这两个老大难问题说再见了。

和规则分流的联动:DNS 也能参与决策

如果你的规则集里用了 GEOIP 判断,DNS 解析结果会直接影响分流是否准确——解析错了 IP,GEOIP 自然也判断错国家,最终可能把国内网站送去了代理、或者把该代理的网站放了行。这也是为什么强调"先把 DNS 配对,再谈规则调优"的顺序:地基没打好,上层规则写得再精细也是空中楼阁。遇到"某个网站分流结果不符合预期",不妨先怀疑一下是不是 DNS 解析本身就出了偏差,而不是急着去改规则。

小结

这篇文章其实只讲了一件事:让该走的域名走该走的路,别让 DNS 拖后腿。回顾一下核心结论——首选 fake-ip,遇到不兼容的应用用过滤名单排除而不是整体退回;nameserver 负责国内域名,fallback 负责可能被污染的境外域名,两者分工明确、互不越界;配置改完记得清缓存、重载、验证,三步走完才算真正生效。把这些原则记牢,日后无论换设备、换客户端,都能很快配出一份稳妥的 DNS 配置,不用每次都从头摸索。

如果你是刚接触我的新用户,建议先照抄本文给出的完整配置示例跑起来,观察一段时间没问题之后,再根据自己的网络环境微调 nameserver 和 fallback 里的具体服务器地址——先跑通,再优化,比一开始就追求完美更省心。