Windows 域名内外网解析排查

公司网络 + 零信任 VPN + v2rayN 代理并存时,一个域名到底由谁解析、为什么内网能通走代理就不通:按应用层代理、hosts、缓存、NRPT、网卡 DNS、逐个服务器对比的顺序逐层排查,附实测输出与结果判读表。

实测环境(2026-09-23):公司 Wi-Fi + 深信服 SSL VPN(零信任)+ v2rayN 系统代理

所有命令在 PowerShell 中执行

一、解析链路

一个程序访问域名时,按顺序经过:

应用层:程序是否走代理?走代理时本机可能根本不解析,由代理端解析;

hosts 文件:优先级最高,直接覆盖 DNS

DNS 缓存

NRPT(名称解析策略表,按域名后缀指定 DNS 服务器)

网卡 DNS 服务器:按网卡优先级(metric)+ 服务器顺序查询,失败会回退到下一个

拿到 IP 后的路由:走哪张网卡、能否连通

⚠️ nslookup 不走系统解析器:只问第一个 DNS 服务器,不读 hosts/缓存/NRPT,失败不回退。用它的结果判断”程序能否解析”会误判。以 Resolve-DnsName / ping 为准。

二、排查步骤

先设变量:

powershell
$name = "mastergo.iflytek.com"

1. 应用层代理

powershell
# 读取系统代理(WinINet):浏览器及多数桌面应用使用
Get-ItemProperty 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' |
  Select ProxyEnable, ProxyServer, ProxyOverride, AutoConfigURL
# 把代理例外按分号拆开逐行显示(上条输出会被截断)
(Get-ItemProperty 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings').ProxyOverride -split ';'
# WinHTTP 代理(系统服务用)
netsh winhttp show proxy
# 环境变量代理(命令行工具用)
Get-ChildItem env:*proxy*

浏览器:chrome://settings/security(安全 DNS)、chrome://net-internals/#dns(内部解析 / 清缓存)

实测输出:

ProxyEnable ProxyServer     ProxyOverride
          1 127.0.0.1:10808 localhost;127.*;10.*;172.16.*;...

localhost / 127.* / 10.* / 172.16.*~172.31.* / 192.168.* / 127.0.0.1 / <local>

当前的 WinHTTP 代理服务器设置: 直接访问(没有代理服务器)。

(env 无输出)

解读:

ProxyEnable=1,ProxyServer=127.0.0.1:10808:系统代理开启,浏览器流量交给 v2rayN,域名由 v2rayN 解析

AutoConfigURL 为空:没有 PAC

ProxyOverride是例外列表,针对这些 IP 会绕过系统代理

提示

按 URL 里的主机名字符串匹配,不会先解析再匹配

10.* 只对 http://10.x.x.x 这种直接写 IP 的访问生效

要让公司域名绕过代理,需显式加 *.iflytek.com

<local>:匹配不带点的主机名(如 http://gitlab)

WinHTTP 直连、环境变量为空:系统服务和命令行工具都直连、本机解析

备注

WinHTTP 是 Windows 自带的另一套 HTTP 客户端库,它有自己独立的代理设置,所以排查时需要单独检查。

Windows 里有两套 HTTP 库:

WinINetWinHTTP
设计给谁用有用户交互的桌面程序后台服务、非交互程序
代理配置位置当前用户(HKCU),每个用户可以不同整台机器共用一份
在哪里设置「设置 → 网络 → 代理」,v2rayN 修改的就是这里只能用 netsh winhttp 命令设置
典型使用者Chrome、Edge 等浏览器,以及大多数桌面应用Windows 更新、BITS 后台传输、Defender 更新、部分系统服务

之所以要分成两套,是因为系统服务通常以 SYSTEM 账户运行,没有登录用户,也就读不到 HKCU 里「当前用户」的代理设置,只能使用一份整机统一的配置。

常用命令(设置和重置需要管理员权限):

powershell
netsh winhttp show proxy                                              # 查看
netsh winhttp set proxy 127.0.0.1:10808 "<local>;*.iflytek.com"       # 手动设置,第二个参数是例外列表
netsh winhttp import proxy source=ie                                  # 从 WinINet(系统代理)复制一份过来
netsh winhttp reset proxy                                             # 恢复直连

要注意,import 只是把当时的设置复制一份,之后 v2rayN 关闭或修改系统代理时,WinHTTP 不会跟着同步。如果 v2rayN 退出了而 WinHTTP 里还指向 10808,后台服务就会连不上网。所以一般不建议手动设置,有需要时用 Tun 模式更省心

2. hosts

powershell
Get-Content C:\Windows\System32\drivers\etc\hosts | Select-String -NotMatch '^\s*(#|$)'
PS C:\Users\maluyao> Get-Content C:\Windows\System32\drivers\etc\hosts | Select-String -NotMatch '^\s*(#|$)'

127.0.0.1     localhost
216.239.32.40 translate.google.com
104.29.124.128       cloudflare.com

注意 hosts 只对本机解析的程序生效;走 v2rayN 的浏览器由 xray 解析,xray 默认不读系统 hosts。

3. DNS 缓存

命令查 hosts查缓存向 DNS 服务器查询回答的问题
Resolve-DnsName $name✓✓缓存里没有时才查程序现在会拿到什么
Resolve-DnsName $name -CacheOnly✓(hosts 条目会被预加载进缓存)✓✗缓存里现在有什么
Resolve-DnsName $name -Server x.x.x.x✗✗只问指定的这一台这台 DNS 服务器会怎么回答
powershell
$name = "baidu.com"

# 只读缓存,不发起任何查询(缓存里没有就报错)
Resolve-DnsName $name -CacheOnly

# 跳过缓存:直接问本机配置的每个 DNS 服务器(拿到已连接的网卡)
$up  = (Get-NetIPInterface -AddressFamily IPv4 | Where-Object ConnectionState -eq Connected).InterfaceIndex
$dns = (Get-DnsClientServerAddress -AddressFamily IPv4 | Where-Object InterfaceIndex -in $up).ServerAddresses | Select-Object -Unique
$dns
foreach ($s in $dns) {
  Resolve-DnsName $name -Type A -Server $s -DnsOnly -QuickTimeout -ErrorAction SilentlyContinue |
    Where-Object Type -eq 'A' | Select-Object @{n='Server';e={$s}}, IPAddress, TTL
}

# 清空缓存(= ipconfig /flushdns)
Clear-DnsClientCache
powershell
Server          IPAddress       TTL
------          ---------       ---
8.8.8.8         111.63.65.247   498
8.8.8.8         110.242.74.102  498
8.8.8.8         111.63.65.103   498
8.8.8.8         124.237.177.164 498
114.114.114.114 111.63.65.247   358
114.114.114.114 111.63.65.103   358
114.114.114.114 110.242.74.102  358

一个域名对应多个 IP,是为了负载均衡:客户端挑其中一个连接,访问量就分散到了多台服务器上。

还有两份缓存不在系统里,需要分别清理:浏览器缓存(chrome://net-internals/#dns → Clear host cache)和代理核心的缓存(重启 v2rayN)

4. NRPT

NRPT 全称 Name Resolution Policy Table(名称解析策略表),是 Windows 从 Win7 开始提供的功能。它的作用是按域名指定用哪个 DNS 服务器。平时基本碰不到,只有企业 VPN 或组策略场景才会用,很少见。

规则存在注册表中,组策略下发的比本地规则优先级更高

解析时,系统先查 hosts 和缓存,然后看域名是否匹配 NRPT 规则:匹配的话,只问规则里指定的 DNS,完全忽略网卡上配置的 DNS;不匹配的话,按正常的网卡 DNS 顺序查询。

powershell
Get-DnsClientNrptPolicy   # 生效中的
Get-DnsClientNrptRule     # 已配置的

谁在用: 微软自家的 DirectAccess、Always On VPN,以及 Windows 内置 VPN 的「按域名分流 DNS」功能;第三方软件里,Tailscale 在 Windows 上就是靠添加 NRPT 规则来实现 MagicDNS 的。

5. 网卡优先级与 DNS

查询网卡优先级,metric 越小越优先:

powershell
Get-NetIPInterface -AddressFamily IPv4 | Where ConnectionState -eq Connected |
  Sort InterfaceMetric | Format-Table InterfaceAlias, InterfaceMetric

输出:

powershell
InterfaceAlias                InterfaceMetric
--------------                ---------------
WLAN                                       35
VMware Network Adapter VMnet8              35
Loopback Pseudo-Interface 1                75

查询各网卡 DNS(数组顺序即查询顺序)

powershell
Get-DnsClientServerAddress -AddressFamily IPv4 | Where ServerAddresses

输出:

powershell
InterfaceAlias               Interface Address ServerAddresses
                             Index     Family
--------------               --------- ------- ---------------
outline-tap0                        20 IPv4    {1.1.1.1, 9.9.9.9}
WLAN                                12 IPv4    {8.8.8.8, 114.114.114.114}

短名称补全后缀(仅排查 http://nas 这类短名称时需要)

powershell
Get-DnsClientGlobalSetting | Select-Object SuffixSearchList

输出:

powershell
SuffixSearchList
----------------
{iflytek.com}

表示这台电脑解析任何不带点的短名称时,都会自动在后面补上 .iflytek.com 再去查询。这种全局后缀列表一般是公司通过组策略统一下发的,用来让员工可以用短名称访问内网服务。

你看这个解析出来了:

powershell
PS C:\Users\lyma7> Resolve-DnsName mastergo
Name                                           Type   TTL   Section    IPAddress
----                                           ----   ---   -------    ---------
mastergo.iflytek.com                           A      42949 Answer     10.104.49.43

DoH

powershell
# DoH:该命令只是内置对照表,是否启用要看"设置 → WLAN → 硬件属性 → DNS 服务器分配"是否标注"已加密"
Get-DnsClientDohServerAddress

6. 本地 DNS 与虚拟网卡归属

powershell
# 所有网卡:名称、索引、驱动描述、状态(用索引对应前几步)
Get-NetAdapter | Format-Table Name, InterfaceIndex, InterfaceDescription, Status

输出:

image-20260924011719342

当网卡的 DNS 被设置成 127.0.0.1 这类本机地址时,找出到底是哪个程序在充当这台 DNS 服务器。

powershell
# 谁在 UDP 53 端口提供 DNS
Get-NetUDPEndpoint -LocalPort 53 | ForEach-Object {
  Get-Process -Id $_.OwningProcess | Select Id, ProcessName, Path }
# 同一程序是否也监听 TCP 53
Get-NetTCPConnection -LocalPort 53 -State Listen -ErrorAction SilentlyContinue | ForEach-Object {
  Get-Process -Id $_.OwningProcess | Select Id, ProcessName, Path }

提示

为什么 UDP 和 TCP 都要查: DNS 查询主要走 UDP;但当响应数据太大,UDP 包装不下时,服务器会在响应里设置「截断」标记,客户端会改用 TCP 重新查询。一个完整的 DNS 服务应该两种协议都支持。

7. 系统解析器最终结果(= 浏览器/ping 实际拿到的)

powershell
# 走完整系统解析流程(默认查 A + AAAA)
Resolve-DnsName $name
# 只查 CNAME,看是否是别名
Resolve-DnsName in.iflytek.com -Type CNAME
# 调用 getaddrinfo,与浏览器/普通程序拿到的完全一致(走系统代理的浏览器不在本机解析,不适用)
[System.Net.Dns]::GetHostAddresses($name) | Select IPAddressToString, AddressFamily

8. 逐个 DNS 服务器对比(定位内外网差异的关键)

1、列出已连接网卡上的 DNS 服务器

powershell
$up = (Get-NetIPInterface -AddressFamily IPv4 | Where-Object ConnectionState -eq Connected).InterfaceIndex
(Get-DnsClientServerAddress -AddressFamily IPv4 | Where-Object InterfaceIndex -in $up).ServerAddresses | Select-Object -Unique

输出:

powershell
127.0.0.1
192.168.75.14
172.16.100.13

提示

后面两个是WIFI设置分配的DNS服务器

第一个是深信服 SSL VPN创建的网卡接管的DNS,可以查询53 UDP端口发现他在本地确实起了一个DNS服务器

2、对上一步列出的每个服务器各执行一次(替换 IP 即可)

powershell
Resolve-DnsName $name -Server 8.8.8.8 -Type A -DnsOnly -QuickTimeout
Resolve-DnsName $name -Server 114.114.114.114 -Type A -DnsOnly -QuickTimeout
powershell
PS C:\Users\lyma7> Resolve-DnsName $name -Server 192.168.75.14 -Type A -DnsOnly -QuickTimeout

Name                                           Type   TTL   Section    IPAddress
----                                           ----   ---   -------    ---------
mastergo.iflytek.com                           A      3600  Answer     10.104.49.43


PS C:\Users\lyma7> Resolve-DnsName $name -Server 233.5.5.5 -Type A -DnsOnly -QuickTimeout
Resolve-DnsName : mastergo.iflytek.com : 由于超时时间已过,该操作返回。
所在位置 行:1 字符: 1
+ Resolve-DnsName $name -Server 233.5.5.5 -Type A -DnsOnly -QuickTimeou ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationTimeout: (mastergo.iflytek.com:String) [Resolve-DnsName], Win32Exception
    + FullyQualifiedErrorId : ERROR_TIMEOUT,Microsoft.DnsClient.Commands.ResolveDnsName

PS C:\Users\lyma7>

可以看出来这个域名只在内网的DNS能够解析

三、结果判读

内网 DNS公网 DNS类型走代理(代理用公网 DNS)时
有NXDOMAIN纯内网必然失败
IP-AIP-B(公网入口)内外网分别解析解析到公网入口,可能不通
私网 IP同一私网 IP私网 IP 直接写在公网 DNS 里解析正常,只要流量能到达该 IP
同公网 IP同公网 IP公网域名无影响

结论原则:内网系统的域名必须由公司 DNS(或会回退到公司 DNS 的系统解析器)解析。

四、常见坑

本地 DNS 对网关域名返回 SERVFAIL:零信任客户端对自身网关域名(如 in.iflytek.com)故意不解析,防止回环,由后续 DNS 兜底。

代理工具的 direct ≠ 不走代理:v2rayN 等规则命中 direct 后,域名由核心自带 DNS(常为公网 DNS)解析,而非系统 DNS。

系统代理模式:把内网域名加入系统代理例外(如 *.iflytek.com),浏览器完全绕开代理。

Tun 模式:系统代理例外失效,需在核心 DNS 中把内网域名指向 localhost(= 系统解析器,保留回退链)。单写 127.0.0.1 会在网关域名上 SERVFAIL;单写公司 DNS IP 则离开公司网络就失效。

SSH 反向动态转发(ssh -R port)做 SOCKS:不支持 UDP,经它的 UDP DNS 查询全部失败 → 客户端用 FakeDNS 并关闭 routeOnly,把域名交给远端解析。

五、实例

WLAN 的 DNS 顺序:127.0.0.1(零信任客户端)→ 192.168.75.14(HFDNS1.iflytek.com)→ 172.16.100.13

域名内网解析公网解析(223.5.5.5)类型
mastergo.iflytek.com10.104.49.43NXDOMAIN纯内网
soft.iflytek.com10.0.25.21636.7.68.99 / .100内外网分别解析
in.iflytek.com192.168.75.58(127.0.0.1 返回 SERVFAIL,回退到 HFDNS1)CNAME bgp-sdp.iflytek.com → 117.48.148.120内外网分别解析(零信任网关)
test.zhixue.com192.168.57.91192.168.57.91私网 IP 直接写在公网 DNS 里

评论

评论加载中……

登录后再评论

注册要用邮箱收个验证码,只为确认邮箱能收信,不会拿去做别的。账号设置