V2Ray DNS 分流配置:国内域名直连解析与境外域名防污染设置

从 DNS 模块结构讲起,演示国内域名走本地解析、境外域名走远程 DNS 的分流写法,并说明 FakeDNS、缓存与路由联动中的常见误区。

本文速览

本文面向已经有可用代理出站、需要调整 DNS 策略的用户。先区分解析器选择与查询传输路径,再合并国内规则、远程 DoH 和直连出站配置,最后通过独立测试入口检查解析链路。示例采用 V2Ray 风格 JSON 片段,不替换订阅中的服务器配置,也不假定所有客户端使用相同内核。

一、DNS 分流分成解析器选择与查询路由

DNS 分流不是把两个服务器地址写进列表就结束。第一层决定某个域名交给哪个解析器,第二层决定发往解析器的连接走直连还是代理。只有两层都明确,才能判断境外域名的查询是否经过预期链路。加密 DNS 可以保护查询传输,但不能保证解析服务本身的返回结果始终正确。

域名进入内核 选择解析器 匹配查询路由 取得解析结果 建立目标连接

内核 DNS 也不等于操作系统 DNS。应用通过 SOCKS 传入域名时,代理协议可能把域名交给服务器解析;应用先调用系统解析器拿到 IP 时,内核可能只看到 IP。仅修改配置中的 dns 对象,不会自动接管电脑或手机上全部程序的查询。

二、配置前确认内核、规则文件与出站标签

v2rayN 是桌面配置管理客户端,实际行为取决于当前选用的内核。安卓端的 v2rayNG 使用 Xray 内核,v2flyNG 使用 V2Fly 内核。两者许多字段相近,但不能据此认定所有 DNS 选项、FakeDNS 行为和默认值完全一致。先记录内核名称及版本,再对照相应配置文档检查字段支持情况。

  1. 在 v2rayN 的「设置」→「参数设置」中检查与当前内核有关的选项;具体 DNS 编辑入口随客户端版本变化,以实际界面为准。
  2. 备份当前配置,查看生成配置中的 outbounds,记录代理与直连出站的真实 tag。
  3. 确认运行目录中的 geosite.dat 可读取且包含 cn 分类。只有使用 IP 分类时,才需要相应的 geoip.dat 规则。
  4. 先验证代理连接可用,再调整 DNS。代理出站自身不可达时,远程查询失败不能直接归因于解析器。
53
示例直连 DNS 的 UDP 端口
443
示例远程 DoH 的 HTTPS 端口
1053
后文回环测试入口端口

这些数字是配置中的端口约定,不是性能测量结果。下文把现有代理出站称为 proxy,直连出站称为 direct;如果实际标签不同,需要同步替换引用,不能只复制规则中的名称。

三、国内域名使用直连 DNS,其他查询使用远程 DoH

以下片段合并到现有配置顶层的 dns 字段。国内分类优先查询 223.5.5.5,没有命中该分类的查询使用 https://1.1.1.1/dns-query。这两个地址是具体的配置示例,不代表它们在每个网络环境中都可达,也不代表必须固定使用这组公共解析服务。

{
  "dns": {
    "queryStrategy": "UseIPv4",
    "servers": [
      {
        "address": "223.5.5.5",
        "port": 53,
        "domains": [
          "geosite:cn"
        ],
        "skipFallback": true
      },
      {
        "address": "https://1.1.1.1/dns-query"
      }
    ]
  }
}

远程地址使用 IP 字面量,可以减少“为了连接 DoH,先解析 DoH 域名”的引导依赖,但仍需通过 TLS 证书验证。不要为解决连接报错而关闭证书验证。若改用域名形式的解析服务,应同时安排该服务域名的引导解析,避免再次依赖同一条尚未建立的 DNS 链路。

四、为 DNS 查询指定出站,避免默认路由改变链路

下面的规则片段采用 AsIs,先处理两个解析端点,再处理国内域名,最后将其余 TCP 与 UDP 连接交给代理。普通 https:// DoH 与带有本地直连语义的 https+local:// 不能混用理解:本例需要查询连接经过内核路由,因此使用前者。

{
  "routing": {
    "domainStrategy": "AsIs",
    "rules": [
      {
        "type": "field",
        "ip": ["223.5.5.5"],
        "port": "53",
        "network": "udp",
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "ip": ["1.1.1.1"],
        "port": "443",
        "network": "tcp",
        "outboundTag": "proxy"
      },
      {
        "type": "field",
        "domain": ["geosite:cn"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "proxy"
      }
    ]
  }
}

这是便于观察链路的基础策略,不包含局域网、企业内网或广告分类等规则。合并时应保留已有的必要规则,并检查顺序:规则通常按顺序匹配,放在末尾的兜底项不能提前遮住解析端点规则。上面的 IP 与端口规则还会匹配访问同一端点的其他连接,并非只识别 DNS 模块产生的流量。

对于直连出站,还需要检查 Freedom 的域名策略。下面是已有直连出站应具有的结构;应修改对应项,而不是添加第二个同名标签。UseIP 使该出站通过内置 DNS 取得目标 IP,否则默认行为可能继续依赖系统解析。

{
  "tag": "direct",
  "protocol": "freedom",
  "settings": {
    "domainStrategy": "UseIP"
  }
}

结论:分别验证解析去向与连接去向

先确认国内直连出站确实调用内置 DNS,再确认远程 DoH 连接匹配到代理。仅看到网页能打开,不能证明 DNS 分流已经生效;代理请求携带域名时,目标解析仍可能发生在服务端。

五、用独立 DNS 入口验证,不把浏览器缓存当结果

为了直接测试内置解析模块,可以在现有 inbounds 与 outbounds 数组中分别追加下列对象。入站只绑定 127.0.0.1,不要改成对外监听地址。该入口用于本机排障,不会自动修改系统 DNS,也不会自动接管浏览器查询。

{
  "tag": "dns-in",
  "listen": "127.0.0.1",
  "port": 1053,
  "protocol": "dokodemo-door",
  "settings": {
    "address": "1.1.1.1",
    "port": 53,
    "network": "tcp,udp"
  }
}
{
  "tag": "dns-out",
  "protocol": "dns",
  "settings": {}
}

再把下面这条规则放到前文 routing.rules 的最前面,让测试请求进入 DNS 出站,而不是被末尾的代理兜底规则接走。DNS 出站对 A、AAAA 查询调用内置解析模块;其他记录类型的处理与转发行为应单独验证,不要用一次 TXT 查询代替本例的地址记录测试。

{
  "type": "field",
  "inboundTag": ["dns-in"],
  "outboundTag": "dns-out"
}
  1. 重启内核,先检查配置加载日志,排除端口占用、未知字段和规则文件读取失败。
  2. 在安装了 dig 的环境执行下列命令,分别触发国内分类与远程解析路径。
  3. 结合 DNS 调试日志与出站访问日志,确认两个解析端点实际使用的标签。排障期间可临时提高日志级别,完成后恢复。
  4. 每次只改一项设置。重复查询可能命中缓存;必要时重启内核并清理应用或系统缓存,再对照结果。
dig @127.0.0.1 -p 1053 www.baidu.com A
dig @127.0.0.1 -p 1053 www.example.com A

测试域名是否命中分类,仍以当前规则文件为准。解析结果不同不一定表示污染,CDN 调度、解析服务位置和缓存状态都可能改变答案。应观察查询是否发给预期解析器、是否出现超时,以及最终目标连接是否成功,而不是仅比较两次返回的 IP。

六、FakeDNS、缓存与路由解析策略的边界

FakeDNS 返回的是供内核映射使用的合成地址,不是目标站点的真实地址。它主要解决流量进入代理后保留或恢复域名信息的问题,不能代替真实解析服务,也不能修复不可达的代理服务器。开启前应确认当前内核、流量接管方式和域名恢复链路均支持相应配置。

设置或机制实际作用常见误判
DNS queryStrategy控制内置解析模块查询或使用的地址族。设成 IPv4 后,误以为所有应用都停止发起 IPv6 流量。
routing.domainStrategy控制路由匹配时是否为域名取得 IP。把 AsIs 理解为整个内核永远不解析域名。
Freedom domainStrategy控制直连出站建立连接时如何处理域名。只改 DNS 列表,却仍让直连出站依赖系统解析。
FakeDNS维护域名与合成地址的映射,需要后续流量回到可恢复映射的内核。只开启合成应答,未保证对应连接也被接管。
DNS 缓存复用此前取得的解析结果,减少重复查询。修改配置后仍看到旧结果,就认定新配置未被加载。

IPIfNonMatch 会在域名规则未命中时尝试解析,再继续 IP 规则匹配;IPOnDemand 会在匹配需要 IP 的规则时触发解析。两者都可能增加本地查询。若配置里已经有必然命中的兜底规则,不要想当然地认为每个域名都会进入 IP 解析阶段。

七、DNS 分流常见问题与排查顺序

写了远程 DNS,为什么浏览器仍请求本地解析器?

先确认查询是否进入内核。使用上文的 1053 端口测试入口单独验证,再检查浏览器安全 DNS 和系统代理行为。普通系统代理主要处理应用连接,不等于接管操作系统的 UDP 53 查询。

国内网站能打开,境外域名解析一直超时怎么办?

检查 1.1.1.1:443 是否匹配 proxy,确认该标签存在且代理连接正常。随后检查 TLS 错误和系统时间。若代理服务器地址本身是域名,还要排除它的引导解析依赖远程 DoH 所造成的循环。

更新订阅后,刚写的 DNS 配置怎么不见了?

检查改动是否写在客户端临时生成的运行配置中。生成文件可能在切换节点或重启时被覆盖。应使用当前版本提供的 DNS 设置或自定义配置入口保存,再重新查看生成结果,确认字段及标签确实保留。

开启 FakeDNS 后部分程序完全连不上,先改哪里?

先恢复普通解析并重启内核,清理相关应用缓存。确认恢复后,再检查合成地址对应的连接是否回到同一内核,以及入站域名恢复设置是否匹配当前内核要求。不要让拿到合成地址的程序绕过接管直接连接。

最终验收应保留三项记录:当前内核与配置来源、两个解析端点对应的出站标签、独立测试入口的查询日志。这样才能把问题定位到解析器选择、查询传输或目标连接阶段,而不是反复更换公共 DNS 地址。

下载客户端