本文适合已经能通过 v2rayN 或 Xray 正常连接、但检测页面仍显示本地运营商 DNS 的用户。内容从流量路径、基线检测、Xray 配置到故障定位依次展开,完成后可以区分系统 DNS、浏览器加密 DNS 与代理内核解析,并验证端口 53 的查询是否确实进入代理出站。
DNS 泄漏发生在哪一段
业务连接
访问域名时,应用通常先把域名交给系统解析器,再连接解析得到的 IP。系统代理只接管支持代理设置的 HTTP 或 SOCKS 连接,不会自动改写操作系统发往 UDP 53、TCP 53 的 DNS 查询。因此,即使网页流量已经由 VMess 或 VLESS 节点转发,域名查询仍可能直接发给网卡中配置的运营商解析器。
解析请求
泄漏并不等同于节点失效。更准确的判断是:业务连接经过代理,而解析请求走了另一条不符合预期的路径。检测页面看到本地网络提供商、路由器地址或企业内网解析器时,才需要结合系统设置判断。公共 DNS 的名称出现在结果里,也不能单独证明查询是否经由代理,因为同一个公共解析器既可以直连,也可以通过远端节点访问。
Xray 配置中的顶层 dns 模块主要负责内核自身的域名解析与匹配需求,例如解析节点服务器域名、为路由规则取得目标 IP。它不会仅凭存在于配置文件中,就接管操作系统的全部查询。要处理应用提交给系统的 DNS,还需要监听入口、系统 DNS 指向以及对应出站三部分同时成立。
浏览器自带的加密 DNS 是另一条路径。它通常通过 HTTPS 连接解析服务,不再访问本机端口 53。若浏览器流量受系统代理接管,这条连接可能经过代理;若应用绕过系统代理,它也可能直接出站。因此排查时应先暂时关闭浏览器的安全 DNS,再检测系统解析路径,最后单独恢复并验证浏览器设置。
结论:先区分解析来源,再修改配置
看到陌生 DNS 地址时不要立即更换节点。先确认查询来自系统端口 53、浏览器加密 DNS 还是 Xray 内核解析;三条路径的修复位置不同,混在一起测试会产生相互矛盾的结果。
建立可重复的 DNS 泄漏检测基线
检测原则
记录网卡 DNS
打开 PowerShell,执行
Get-DnsClientServerAddress -AddressFamily IPv4。记录正在使用的网卡名称与 ServerAddresses;家庭网络常见结果是路由器地址,公共网络也可能直接下发两个解析器地址。关闭测试干扰
暂时关闭浏览器安全 DNS,退出其他会修改网络栈的程序。随后执行
ipconfig /flushdns清除 Windows DNS 缓存,并关闭已经打开的检测页面。记录直连结果
断开 v2rayN 系统代理,重新进入 DNS 检测页面并连续测试两次。记录解析器数量、网络归属和地区,这组数据是本地路径基线,不要只保存页面上的国家或地区名称。
连接后复测
连接目标节点,确认 v2rayN 本地 SOCKS 端口 10808 与 HTTP 端口 10809 正在监听,再次清除缓存并测试。若结果与直连基线完全一致,系统 DNS 大概率没有被接管。
验证指定入口
配置本地 DNS 入口后运行
nslookup example.com 127.0.0.1。返回地址且 Xray 日志出现dns-in、dns-out,才说明查询进入了预定链路。
示例基线
用 dns 入口与出站收进代理链路
下面的配置片段采用本机 127.0.0.1:53 作为 DNS 入口,把 TCP 与 UDP 查询交给标签为 dns-out 的出站,再通过已有的 proxy 出站转发。应用前应先在当前有效配置中确认选中节点的出站标签;如果实际标签不是 proxy,需要把 proxySettings.tag 改成现有标签。
端口提示
127.0.0.1。{
"dns": {
"servers": [
{
"address": "1.1.1.1",
"domains": [
"geosite:geolocation-!cn"
]
},
{
"address": "223.5.5.5",
"domains": [
"geosite:cn"
]
}
],
"queryStrategy": "UseIPv4",
"disableCache": false
},
"inbounds": [
{
"tag": "dns-in",
"listen": "127.0.0.1",
"port": 53,
"protocol": "dokodemo-door",
"settings": {
"address": "1.1.1.1",
"port": 53,
"network": "tcp,udp"
}
}
],
"outbounds": [
{
"tag": "dns-out",
"protocol": "dns",
"settings": {
"address": "1.1.1.1",
"port": 53,
"network": "tcp",
"nonIPQuery": "drop"
},
"proxySettings": {
"tag": "proxy"
}
}
],
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"inboundTag": [
"dns-in"
],
"outboundTag": "dns-out"
}
]
}
}
IPv4 策略
queryStrategy: UseIPv4 让内置 DNS 优先返回 IPv4 结果,适合当前节点或本地网络没有稳定 IPv6 出站的情况。如果线路完整支持 IPv6,可以根据实际目标改为 UseIP,但应同步检查代理节点、系统路由与远端解析器,避免只取得 AAAA 记录却没有可用的 IPv6 出站。查询类型
nonIPQuery: drop 会丢弃 DNS 出站中非 A、AAAA 类型的查询。它适合只需要普通网页解析的精简场景,但可能影响依赖 TXT、SRV 等记录的企业服务。若出现邮件验证、服务发现或内部应用解析异常,应移除此项后重新测试,而不是把问题归因于 VMess 或 VLESS 协议。结论:入口、路由与系统指向缺一不可
只有顶层 dns 配置时,系统查询仍可能直连;只有本地入口却没有把网卡 DNS 指向 127.0.0.1,也不会收到真实请求。判断是否完成接管,应以端口监听、日志命中和复测结果三项同时成立为准。
domainStrategy 不是 DNS 防泄漏开关
路由解析
routing.domainStrategy 决定路由模块在匹配规则时是否把目标域名解析为 IP。它处理的是“路由规则要不要额外解析”,不是“操作系统 DNS 应该从哪里发出”。把它从 AsIs 改成 IPIfNonMatch,可能让 IP 规则获得匹配机会,但不会自动拦截网卡发出的 UDP 53 请求。| 取值 | 解析行为 | 适用判断 |
|---|---|---|
AsIs |
按原始域名执行域名规则,不为 IP 规则主动解析 | 规则主要由 domain、geosite 构成,减少额外解析 |
IPIfNonMatch |
域名规则未命中时解析目标,再尝试 IP 类规则 | 同时使用 geosite 与 geoip,兼顾匹配范围与查询量 |
IPOnDemand |
遇到可能需要目标 IP 的规则时提前解析 | IP 规则优先且确实需要早期解析的配置 |
常见配置选择是 IPIfNonMatch:域名规则先工作,未命中时再为 geoip 或明确 IP 规则解析。这样可以避免所有请求都提前触发解析,同时保留 IP 分流能力。若路由列表把 IP 规则放在很靠前的位置,IPOnDemand 可能显著增加内核 DNS 查询数量,应配合日志观察,而不是只根据名称选择。
顶层 dns.servers 的域名分流与 routing.rules 是两套逻辑。前者决定某类域名交给哪个解析器,后者决定连接走 direct、proxy 或 block。若让 geosite:cn 使用近端解析器,同时又要求所有 DNS 查询必须经远端节点转发,需要明确这两个目标是否冲突;解析器地址与传输路径应分别设计。
- 只想让域名规则优先工作,可使用
AsIs,并单独处理系统 DNS。 - 域名未命中后还要使用 geoip 分流,可使用
IPIfNonMatch。 - 不要把修改
domainStrategy当作检测完成的证据,仍要检查端口 53 与日志。 - 节点服务器地址本身是域名时,应保证启动阶段存在可用的引导解析路径,否则代理尚未建立就无法解析节点。
在 v2rayN 中应用配置并避免被覆盖
配置持久化
确认内核类型
进入「设置」→「参数设置」→「Core 类型」,确认当前服务器使用 Xray 内核。保存后重启内核,避免配置语法由另一内核解释。
检查出站标签
打开当前运行配置,找到所选节点对应的
outbounds.tag。本文示例使用proxy,实际文件若为其他名称,DNS 出站的代理标签必须保持一致。添加自定义配置
在「服务器」→「添加自定义配置服务器」中选择准备好的 JSON 文件。先保留本地 DNS 入口端口 1053 做启动测试,确认语法和路由日志正常。
释放端口 53
执行
Get-NetUDPEndpoint -LocalPort 53与Get-NetTCPConnection -LocalPort 53检查占用。处理冲突后,把配置端口改回 53,并以管理员权限重启 v2rayN。修改活动网卡
把当前活动网卡的 IPv4 DNS 服务器设为
127.0.0.1。不要同时保留本地运营商 DNS 作为备用项,否则本地服务暂时无响应时,系统可能自动转向备用解析器。清缓存再验证
执行
ipconfig /flushdns,用nslookup example.com 127.0.0.1验证入口,再运行三轮检测。完成后检查日志是否由dns-in命中dns-out。
接管边界
常见报错与定位顺序
排错顺序
info,定位完成后再恢复日常设置,避免长期生成大量访问记录。报错:failed to listen TCP on 127.0.0.1:53
原因与解法:端口 53 已被其他进程占用,或当前进程没有足够权限。先用 PowerShell 查询 TCP 与 UDP 端点,关闭冲突服务,再以管理员权限重启内核。
报错:failed to find an available destination
原因与解法:节点服务器域名或 DNS 目标无法完成引导解析。检查服务器地址拼写,临时提供可直达的引导解析器,确认节点建立后再恢复目标链路。
报错:outbound proxy not found
原因与解法:proxySettings.tag 引用了不存在的出站标签。打开实际运行配置,复制所选节点的准确 tag,并同步修改 DNS 出站引用。
现象:nslookup 超时但内核没有报错
原因与解法:网卡可能没有指向 127.0.0.1,或防火墙阻止本地 UDP 53。先显式执行 nslookup example.com 127.0.0.1,再分别检查网卡设置与本地规则。
现象:检测仍显示两个解析服务
原因与解法:浏览器安全 DNS、IPv6 DNS 或备用网卡仍在独立解析。逐项关闭浏览器加密 DNS,检查 IPv6 DNS 地址,并停用未使用的虚拟网卡后复测。
日志判断
dns-in 但没有进入 dns-out,应检查路由规则顺序。Xray 路由从上到下匹配,较早的通用入站规则可能先把请求送往 direct。把针对 dns-in 的规则放到通用规则之前,并确认没有重复 tag。浏览器判断
安全边界
127.0.0.1,不要为了省事改成 0.0.0.0。后者会让服务监听全部网卡,局域网设备可能访问该端口,也会扩大防火墙配置范围。只有明确要为其他设备提供解析服务时,才应绑定局域网地址并设置访问控制。最终判断:用四项结果闭环
网卡 DNS 指向 127.0.0.1、本地端口 53 正常监听、日志显示 dns-in 到 dns-out、检测结果不再出现直连基线解析器,这四项同时成立,才可以确认系统 DNS 已进入预定代理链路。