代理网络故障排查指南:从 DNS、Fake-IP、TUN 到节点连接
适用系统:macOS、Ubuntu、Windows
适用工具:Shadowrocket、v2rayN、Clash、sing-box、Xray、Hysteria2 等
典型现象:IP 节点正常、域名节点超时;延迟显示-1;开代理后 DNS 异常;手机正常但电脑不正常
脱敏说明:本文中的
example.com/.net/.org均为文档示例域名;192.0.2.0/24、198.51.100.0/24、203.0.113.0/24均为文档示例地址段。接口名、端口和局域网地址也经过泛化,实际操作时请替换为本机信息。
一、先建立正确的排障思路
代理软件出现“节点超时”时,问题不一定在代理服务器。一次完整的代理连接至少经过以下几层:
应用程序
↓
系统 DNS / 代理 DNS
↓
域名解析为服务器 IP
↓
本机路由、系统代理或 TUN 虚拟网卡
↓
TCP 或 UDP 到达代理服务器端口
↓
TLS / Reality / Hysteria2 等协议握手
↓
代理服务器访问目标网站
任何一层失败,都可能在客户端里表现为:
延迟 -1
超时
测速跳过
连接失败
no servers could be reached
因此不要一开始就反复修改节点参数。正确顺序是:
- 确认域名能否解析。
- 确认解析结果是否正确。
- 确认服务器端口能否到达。
- 确认流量实际走了哪个接口和路由。
- 最后再检查代理协议、TLS、UUID、密码等配置。
二、先用现象快速分类
1. IP 节点正常,域名节点全部失败
这是非常有价值的特征:
IP 节点不需要 DNS → 正常
域名节点需要 DNS → 失败
优先检查:
- 系统配置了失效 DNS;
- DNS 查询回退时间过长;
- 存在错误的 AAAA/IPv6 记录;
- TUN 接管 DNS 后形成循环;
- Fake-IP 被错误用于代理服务器自身域名;
- DoH 必须经过尚未建立的代理才能访问。
2. 域名能解析,但端口连接失败
优先检查:
- 域名是否指向旧 IP;
- 防火墙是否开放端口;
- 服务是否监听正确的 TCP/UDP 端口;
- Cloudflare 小橙云是否代理了不支持的端口;
- 当前网络是否限制 UDP 或特定端口。
3. 域名和端口都正常,但客户端仍失败
继续检查:
- VLESS UUID、Reality 公钥、Short ID;
- TLS SNI、证书域名;
- WebSocket Path、Host;
- Hysteria2 密码和 TLS 配置;
- 客户端 Core 类型及版本;
- 系统时间是否准确。
三、DNS、TUN、Fake-IP 到底是什么关系
1. 普通 DNS
DNS 把域名转换成真实 IP:
node-a.example.com → 203.0.113.10
如果 DNS 不可用,使用域名的代理节点连第一步都无法完成。
2. TUN 模式
TUN 模式会创建虚拟网卡并接管系统流量。它比“系统 HTTP 代理”覆盖范围更广,可以处理许多不遵循系统代理设置的应用和 UDP 流量。
但 TUN 也更容易产生循环:
解析代理节点域名
↓
DNS 请求被 TUN 接管
↓
DNS 被配置为通过代理访问
↓
代理节点尚未完成域名解析
↓
互相等待,最终超时
3. Fake-IP
Shadowrocket、Clash 等工具可能给应用返回一个保留地址,例如:
node-a.example.com → 198.18.0.18
198.18.0.0/15 是保留测试网段,常被代理软件作为 Fake-IP 地址池。它的工作方式是:
应用查询域名
↓
代理 DNS 返回 198.18.x.x
↓
应用连接这个 Fake-IP
↓
TUN 根据内部映射还原原始域名
↓
按代理规则建立真实连接
Fake-IP 本身不是 DNS 污染。对普通网站来说,这种机制很正常。
但代理服务器自身的域名通常要能够在代理建立前解析。如果代理软件没处理好启动域名,可能出现:
连接代理需要解析节点域名
解析节点域名又依赖代理
这时可把节点域名加入 Shadowrocket 的“总是真实 IP(Always Real IP)”。
4. DoH 的启动依赖
DoH 是通过 HTTPS 查询 DNS,例如:
https://cloudflare-dns.com/dns-query
https://dns.google/dns-query
它可以提高 DNS 查询的完整性和隐私性,但它自身也需要网络连接。如果 DoH 被设置为通过代理访问,就可能发生:
要解析代理节点域名
↓
需要访问 DoH
↓
DoH 需要经过代理
↓
代理尚未建立
↓
超时
解决方法是在备用 DNS 中保留能够直连的普通 DNS,例如:
路由器 DNS
223.5.5.5
119.29.29.29
普通 DNS 先完成代理节点的启动解析,代理建立后再使用 DoH。
四、通用排查流程
无论使用哪个系统,都可以按下面的顺序进行。
第一步:记录节点信息
至少确认:
服务器地址:域名还是 IP
端口:例如 30443、31443
协议:VLESS / Hysteria2 / VMess 等
传输层:TCP / UDP / WebSocket / gRPC
TLS 类型:TLS / Reality
第二步:比较域名与 IP
如果同一台服务器:
- 填写 IP 时正常;
- 填写域名时失败;
优先排查 DNS,而不是服务器性能。
第三步:分别测试系统 DNS 和指定 DNS
例如:
dig example.com
dig @223.5.5.5 example.com
如果指定 DNS 很快,而普通 dig 超时,问题在系统当前 DNS 路径。
第四步:测试端口
TCP 节点可以使用 nc、Test-NetConnection 等工具。
注意:Hysteria2 主要使用 UDP,普通 TCP 端口测试不能证明 Hysteria2 一定可用,也不能因为 TCP 测试失败就断定 UDP 服务失败。
第五步:关闭 TUN 做对照实验
临时关闭:
- TUN/VPN 模式;
- 系统代理;
- 代理软件 DNS 接管。
重新测试域名。如果关闭 TUN 后恢复,重点检查代理 DNS、Fake-IP 和路由循环。
五、Ubuntu 排查方法
1. 检查系统解析结果
getent ahosts node-a.example.com
示例:
203.0.113.10 STREAM node-a.example.com
203.0.113.10 DGRAM
203.0.113.10 RAW
getent 使用系统名称解析路径,结果比只查看某个 DNS 文件更接近普通程序的行为。
2. 查看 systemd-resolved 状态
resolvectl query node-a.example.com
resolvectl status
resolvectl status enpXs0
重点观察:
- 当前使用哪个网络接口;
Current DNS Server;DNS Servers;- 查询耗时是否异常。
例如:
Current DNS Server: 192.168.1.1
DNS Servers: 192.168.1.1 223.5.5.5
3. 使用 dig 检查实际 DNS
dig A node-a.example.com
dig AAAA node-a.example.com
dig @192.168.1.1 node-a.example.com
dig @223.5.5.5 node-a.example.com
判断:
A:IPv4 地址;AAAA:IPv6 地址;SERVER:实际回答查询的 DNS;Query time:最后一次成功查询的耗时。
注意,dig 前面如果出现多个超时,最后的 Query time: 5 msec 只代表最后一个 DNS 的耗时,不包含此前等待失效 DNS 的总时间。建议加上:
time dig node-a.example.com
查看整个命令真实耗时。
4. 实际案例:失效 DNS 导致 v2rayN 域名节点显示 -1
故障时 /etc/resolv.conf 内容为:
nameserver 192.168.10.99
nameserver 192.168.10.100
nameserver 192.168.1.1
nameserver 8.8.8.8
nameserver 8.8.4.4
其中 192.168.10.99 和 192.168.10.100 已经不可达。每次查询都会先等待它们超时,最后才使用 192.168.1.1。
表现为:
communications error to 192.168.10.99#53: timed out
communications error to 192.168.10.100#53: timed out
系统最终能得到正确结果,但总耗时超过 v2rayN 节点测试的等待时间,于是:
域名节点 → -1
IP 节点 → 正常
修复 NetworkManager DNS
在 Ubuntu 网络设置中:
IPv4:Automatic (DHCP)
DNS Automatic:关闭
DNS:192.168.1.1, 223.5.5.5
Routes Automatic:开启
也可以使用命令。先查看连接名称:
nmcli connection show --active
假设连接名为“有线连接 1”:
sudo nmcli connection modify "有线连接 1" ipv4.ignore-auto-dns yes
sudo nmcli connection modify "有线连接 1" ipv4.dns "192.168.1.1 223.5.5.5"
sudo nmcli connection down "有线连接 1"
sudo nmcli connection up "有线连接 1"
检查 /etc/resolv.conf
ls -l /etc/resolv.conf
cat /etc/resolv.conf
Ubuntu 使用 systemd-resolved 时,标准结构通常是:
/etc/resolv.conf -> /run/systemd/resolve/stub-resolv.conf
内容为:
nameserver 127.0.0.53
options edns0 trust-ad
search .
如果 /etc/resolv.conf 被改成普通静态文件,可以先备份,再恢复符号链接:
sudo cp -a /etc/resolv.conf /etc/resolv.conf.backup
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
sudo systemctl restart systemd-resolved
sudo resolvectl flush-caches
验证:
ls -l /etc/resolv.conf
time dig node-a.example.com
不要轻易对 /etc/resolv.conf 使用 chattr +i。这可能阻止 NetworkManager、VPN 和系统 DNS 正常切换。
5. 检查是谁修改了 resolv.conf
搜索永久配置:
sudo grep -RIn "192\.168\.1\.99\|192\.168\.1\.100" \
/etc/NetworkManager \
/etc/netplan \
/etc/systemd \
/etc/dhcp \
/etc/openvpn \
2>/dev/null
搜索命令历史:
history | grep -E "resolv.conf|192.168.10.99|192.168.10.100"
sudo grep -E "resolv.conf|192.168.10.99|192.168.10.100" \
/root/.bash_history 2>/dev/null
如果问题会再次出现,可以使用 auditd 记录修改者:
sudo apt install auditd
sudo auditctl -w /etc/resolv.conf -p wa -k resolv_conf_change
sudo ausearch -k resolv_conf_change -i
重点查看:
exe=
comm=
pid=
6. 测试 TCP 端口
nc -vz node-a.example.com 30443
nc -vz node-b.example.net 31443
再与 IP 对比:
nc -vz 203.0.113.10 30443
nc -vz 198.51.100.20 31443
如果域名失败、IP 成功,仍然优先检查 DNS 或 IPv6。
7. 检查 IPv4/IPv6
dig A example.com
dig AAAA example.com
nc -4 -vz example.com 443
nc -6 -vz example.com 443
如果 IPv4 成功而 IPv6 失败:
- 检查错误 AAAA 记录;
- 检查本机 IPv6 默认路由;
- 将代理 Core 的查询策略临时设为 IPv4 Only/UseIPv4。
8. 检查路由和代理环境变量
ip address
ip route
ip rule
env | grep -i proxy
检查某个目标实际走哪个接口:
ip route get 203.0.113.10
使用 curl 查看连接过程:
curl -v --connect-timeout 5 https://example.com/
curl -4 -v --connect-timeout 5 https://example.com/
curl -6 -v --connect-timeout 5 https://example.com/
六、macOS 排查方法
1. 查看 macOS 实际 DNS
macOS 不应只看 /etc/resolv.conf。最重要的命令是:
scutil --dns
提取 DNS 地址:
scutil --dns | grep 'nameserver\[[0-9]*\]'
输出可能同时包含:
198.18.0.2 # Shadowrocket/TUN DNS
192.0.2.53 # Wi-Fi DHCP 下发 DNS
192.0.2.54
查看 Wi-Fi 是否手动配置 DNS:
networksetup -getdnsservers Wi-Fi
如果显示:
There aren't any DNS Servers set on Wi-Fi.
意思是没有手动配置,正在使用 DHCP 自动下发的 DNS,并不是没有 DNS。
列出网络服务:
networksetup -listallnetworkservices
然后使用输出中的准确名称,例如:
networksetup -getdnsservers "USB 10/100 LAN"
2. 测试系统 DNS 与指定 DNS
time dig node-a.example.com
dig @192.168.1.1 node-a.example.com
dig @223.5.5.5 node-a.example.com
dscacheutil -q host -a name node-a.example.com
如果普通查询返回:
198.18.0.18
而指定 DNS 返回:
203.0.113.10
说明代理软件正在使用 Fake-IP。这在 TUN 模式下通常是正常现象。
3. 清理 macOS DNS 缓存
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
成功后通常没有输出。
4. 修改和恢复 Wi-Fi DNS
手动设置:
sudo networksetup -setdnsservers Wi-Fi 192.168.1.1 223.5.5.5
恢复 DHCP 自动 DNS:
sudo networksetup -setdnsservers Wi-Fi Empty
5. 实际案例:Shadowrocket 的 Fake-IP 与 Always Real IP
Shadowrocket 开启时:
resolver #1
nameserver[0] : 198.18.0.2
if_index : utunN
普通查询得到:
node-a.example.com → 198.18.0.18
node-b.example.net → 198.18.0.19
直接查询路由器或公共 DNS 得到真实地址:
node-a.example.com → 203.0.113.10
node-b.example.net → 198.51.100.20
这证明权威 DNS 记录没有问题,198.18.x.x 是 Shadowrocket 的 Fake-IP。
如果域名被用作代理节点服务器地址,可在 Shadowrocket 当前配置的“总是真实 IP”中加入:
*.example.com
*.example.net
*.example.org
对应配置语义类似:
[General]
always-real-ip = *.example.com, *.example.net, *.example.org
修改后验证 Shadowrocket 内部 DNS:
dig @198.18.0.2 node-a.example.com +time=2 +tries=1
dig @198.18.0.2 node-b.example.net +time=2 +tries=1
SERVER 仍然可以是:
198.18.0.2
关键是 ANSWER 应返回真实 IP,而不是 Fake-IP。
6. 实际案例:只有 DoH 导致代理启动循环
原 DNS 覆写只有:
https://cloudflare-dns.com/dns-query
https://dns.google/dns-query
加入 Always Real IP 后,Shadowrocket 必须向上游查询节点真实 IP。但 DoH 连接可能被设置为经过代理,于是:
解析节点域名
↓
需要访问 DoH
↓
DoH 需要代理
↓
代理节点尚未解析
↓
超时
解决方法是在“备用 DNS”中加入能够在代理建立前直接使用的普通 DNS:
192.168.1.1
223.5.5.5
119.29.29.29
建议结构:
DNS 覆写:
https://cloudflare-dns.com/dns-query
https://dns.google/dns-query
备用 DNS:
192.168.1.1
223.5.5.5
119.29.29.29
其中:
192.168.1.1是当前路由器 DNS,换网络后可能不可用;223.5.5.5和119.29.29.29可用于其他网络下的启动解析;- DoH 在代理建立后继续提供加密 DNS;
- 普通备用 DNS 负责打破代理启动阶段的循环依赖。
如果服务器 IP 长期固定,也可以在 [Host] 中为节点入口指定真实 IP:
[Host]
node-a.example.com = 203.0.113.10
node-b.example.net = 198.51.100.20
但如果服务器 IP 会变化,固定 Host 会造成新的旧 IP 问题,因此优先解决上游 DNS 路径。
7. 检查 macOS 路由
netstat -rn
route -n get 203.0.113.10
ifconfig
关注:
- 默认路由是
en0还是utun; - 是否存在
0.0.0.0/1、128.0.0.0/1等 TUN 分流路由; - 节点服务器 IP 是否被错误送回 TUN;
- 到节点服务器的启动连接是否应该从物理网卡直出。
测试连接:
nc -vz node-a.example.com 30443
curl -v --connect-timeout 5 https://example.com/
七、Windows 排查方法
1. 查看 DNS 配置
传统命令:
ipconfig /all
PowerShell:
Get-DnsClientServerAddress
Get-DnsClientServerAddress -AddressFamily IPv4
重点检查:
- 当前正在使用的物理网卡;
- 是否残留旧路由器、公司内网或 VPN DNS;
- TUN 虚拟网卡是否配置了单独 DNS;
- 同时存在多个网卡时,哪个网卡优先。
2. 查询域名
Resolve-DnsName node-a.example.com
Resolve-DnsName node-b.example.net
分别查询 IPv4 和 IPv6:
Resolve-DnsName node-a.example.com -Type A
Resolve-DnsName node-a.example.com -Type AAAA
传统工具:
nslookup node-a.example.com
nslookup node-a.example.com 223.5.5.5
判断逻辑:
- 系统查询失败,指定 DNS 成功:系统 DNS 配置有问题;
- A 正常,AAAA 指向不可用 IPv6:检查 IPv6;
- 域名解析到旧 IP:检查 DNS 缓存和记录 TTL;
- 域名解析正常但 v2rayN 显示
-1:继续检查端口、TUN 和 Core 日志。
3. 测试 TCP 端口
Test-NetConnection node-a.example.com -Port 30443
Test-NetConnection node-b.example.net -Port 31443
结果:
TcpTestSucceeded : True
说明 DNS 解析及 TCP 三次握手成功。
再与 IP 对比:
Test-NetConnection 203.0.113.10 -Port 30443
Test-NetConnection 198.51.100.20 -Port 31443
同样注意,Hysteria2 使用 UDP,Test-NetConnection 的 TCP 结果不能完整验证 Hysteria2。
4. 查看 Windows 系统代理
WinHTTP 代理:
netsh winhttp show proxy
查看当前用户 Internet 代理:
Get-ItemProperty \
'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings' |
Select-Object ProxyEnable, ProxyServer, AutoConfigURL
如果代理软件已经退出,但 ProxyEnable 仍开启,浏览器可能继续访问一个已经不存在的本地代理端口。
5. 查看路由和网卡
route print
Get-NetAdapter
Get-NetIPConfiguration
Get-NetRoute -AddressFamily IPv4 |
Sort-Object RouteMetric, InterfaceMetric
检查:
- 默认路由
0.0.0.0/0; - 是否存在 TUN 添加的
0.0.0.0/1和128.0.0.0/1; - 代理服务器 IP 是否错误走入 TUN;
- VPN 断开后是否留下静态路由。
查看去往某个地址的路径:
tracert 203.0.113.10
6. 清除 DNS 和网络栈
先执行影响较小的 DNS 清理:
ipconfig /flushdns
如果确认 Winsock 异常,再执行:
netsh winsock reset
winsock reset 通常需要重启电脑,不应把它作为每次故障的第一步。
7. 修改 Windows DNS
图形界面可以给当前网卡设置:
首选 DNS:223.5.5.5
备用 DNS:119.29.29.29
PowerShell 示例,先确认接口名称:
Get-NetAdapter
假设接口为 Ethernet:
Set-DnsClientServerAddress `
-InterfaceAlias "Ethernet" `
-ServerAddresses ("223.5.5.5","119.29.29.29")
恢复 DHCP 自动 DNS:
Set-DnsClientServerAddress `
-InterfaceAlias "Ethernet" `
-ResetServerAddresses
8. v2rayN 的针对性检查
如果 v2rayN 中:
IP 节点有延迟
域名节点全部 -1
按顺序执行:
Resolve-DnsName检查域名;Test-NetConnection测试 TCP 节点端口;- 关闭 v2rayN TUN/VPN 模式重新测速;
- 暂时关闭系统代理重新测试;
- 将 Core DNS 查询策略设为
UseIPv4或IPv4 Only; - 查看 Core 日志。
日志中重点搜索:
failed to lookup
no such host
DNS
timeout
network is unreachable
connection refused
context deadline exceeded
如果关闭 TUN 后域名立即恢复,通常不是节点配置错误,而是 TUN DNS 接管、路由或解析循环。
八、常用判断表
| 测试结果 | 最可能原因 | 下一步 |
|---|---|---|
| IP 节点正常,域名节点失败 | DNS、Fake-IP、TUN 循环 | 比较系统 DNS 和指定 DNS |
| 系统 DNS 失败,指定 DNS 成功 | 当前 DNS 配置异常 | 修改网卡 DNS、清缓存 |
| A 正常,AAAA 存在且 IPv6 不通 | IPv6 路由或错误 AAAA | 强制 IPv4 对照测试 |
| 域名和 IP 端口都失败 | 防火墙、服务、网络路径 | 检查监听端口和安全组 |
| TCP 端口成功,客户端仍失败 | 协议握手或客户端配置 | 检查 TLS、Reality、UUID |
| 关闭 TUN 后恢复 | TUN 路由或 DNS 循环 | 检查虚拟网卡、Fake-IP、DNS |
| Fake-IP 查询立即返回 198.18.x.x | 代理 DNS 正常接管 | 普通网站一般无需处理 |
| Always Real IP 域名查询超时 | 上游真实 DNS 无法启动 | 添加可直连备用 DNS |
| 手机正常、电脑失败 | 电脑本机 DNS/路由/客户端 | 不要先改服务器配置 |
九、建议保存的最小命令集
Ubuntu
getent ahosts example.com
resolvectl status
resolvectl query example.com
time dig example.com
dig @223.5.5.5 example.com
nc -vz example.com 443
ip route
ip route get 1.1.1.1
macOS
scutil --dns
networksetup -getdnsservers Wi-Fi
time dig example.com
dig @223.5.5.5 example.com
dscacheutil -q host -a name example.com
netstat -rn
route -n get 1.1.1.1
Windows
ipconfig /all
Get-DnsClientServerAddress
Resolve-DnsName example.com
nslookup example.com 223.5.5.5
Test-NetConnection example.com -Port 443
netsh winhttp show proxy
route print
十、结语
代理故障最容易让人误判的地方,是所有问题最终都可能只显示一个“超时”。
真正高效的排查方法不是不断更换节点和参数,而是把连接拆成独立层次:
DNS 是否得到正确 IP?
端口是否能够到达?
路由是否走对接口?
TUN 是否形成循环?
Fake-IP 是否只用于普通流量?
DoH 是否依赖尚未建立的代理?
最后才是协议握手是否正确。
本次两个实际案例很好地说明了这一点:
- Ubuntu 中失效的
192.168.10.99/100DNS 让查询先等待多次超时,最终虽然能解析成功,但超过 v2rayN 测速时限,因此域名节点全部显示-1。 - macOS 中 Shadowrocket 的 Fake-IP 本身正常,但节点域名切换为 Always Real IP 后,需要真正访问上游 DNS。只有 DoH 时形成代理启动循环,加入普通备用 DNS 后,节点域名可以在代理建立前完成解析,连接随即恢复。
只要坚持“解析—端口—路由—代理—协议”的顺序,大部分看似复杂的代理网络故障都能迅速缩小范围。