如何彻底解决 VPS 的 DNS 泄露问题(含系统修复 + Clash 节点配置)
起因与背景:DNS 泄露的真实危害
近期在部署多个 VPS 时,我们通过 dnsleaktest.org
、browserleaks.com
等网站进行安全检查,发现即便系统已启用 Clash 全局代理或加密隧道,仍然存在 DNS 请求泄露的问题。
可以在下面网站检查 https://browserleaks.com/dns
https://dnsleaktest.com/results.html
如果出现中国的DNS 就可以被视作DNS泄露了。
在检测结果中,常见的泄露 DNS 地址包括:
100.100.2.136
(阿里云内网 DNS)114.114.114.114
(运营商公共 DNS)
这些情况说明系统中某些请求绕过了代理通道,仍走了默认网卡的 DNS 设置。此类泄露带来的隐患包括:
- 真实服务器可能被运营商、云厂商识别并记录
- CDN、ChatGPT、奈飞等服务识别失败
- 代理被污染、解析劫持、加速失效
如何检查 DNS 是否泄露
下面是几种通用且实用的检查方式,建议在修复前后都跑一次:
方法一:使用 dig 命令测试
dig +short whoami.cloudflare @1.1.1.1
dig +short whoami.cloudflare
对比两者结果,如果后者返回的 IP 来自 100.100 段或运营商 DNS,说明默认查询未走加密 DNS。
方法二:浏览器访问 DNS 泄露检测网站
比如:
- dnsleaktest.org
- browserleaks.com/dns
结果中若出现“Aliyun”,“China Telecom”,“ChinaNet”等信息,说明存在泄露。
方法三:查看 Clash 日志
在 Clash 的控制面板(如 Dashboard 或 web UI)中查看是否能捕捉到域名查询记录。
如果 DNS 请求未出现在 Clash 的日志中,就说明这些请求没有走代理。
DNS 泄露的技术成因
了解泄露的本质,才能彻底解决。以下是几种常见成因:
- DHCP 自动注入 DNS:云服务商在通过 DHCP 分配 IP 时,会附带指定 DNS(如阿里云注入
100.100.2.136
)。 - 系统未正确配置 DNS:即使配置了 Clash,如果系统默认 DNS 未更改,也会优先使用泄露的地址。
- /etc/resolv.conf 被重写:很多 Linux 系统会在每次开机时通过网络管理器自动重置该文件。
- Clash 未开启 DNS 拦截:Clash 没有设置
enhanced-mode: fake-ip
或监听 53 端口,导致系统 DNS 请求绕过代理。
系统级修复:屏蔽 DHCP 注入 DNS
本步骤以 Debian / Ubuntu(使用 systemd-networkd + resolved)为例:
1)确认当前系统 DNS 情况
resolvectl status
如看到如下输出说明存在泄露:
DNS Servers: 100.100.2.136
Link 2 (eth0)
2)配置 systemd-networkd 拒绝 DHCP DNS
编辑网络配置文件(路径通常是 /etc/systemd/network/10-eth0.network
):
[Match]
Name=eth0
[Network]
DHCP=yes
[DHCP]
UseDNS=no
解释:这条 UseDNS=no
表示即使通过 DHCP 获取到 IP,也不接受其附带的 DNS。
你看到的内容:
nameserver 1.1.1.1
nameserver 8.8.8.8
nameserver 100.100.2.136
# Too many DNS servers configured, the following entries may be ignored.
nameserver 100.100.2.138
说明你已经配置了 4 个 DNS 服务器,但系统最多只会使用前 3 个(有的系统甚至只用前 2 个)。超出部分就会被忽略。
✅ 怎么理解这些内容?
- 1.1.1.1 → Cloudflare DNS
- 8.8.8.8 → Google DNS
- 100.100.2.136 / 138 → 阿里云的内部 DNS(可能是默认的 DHCP 提供的)
系统会从上往下依次尝试,前面的优先。如果前两个(1.1.1.1 和 8.8.8.8)工作正常,后面的其实不会用到。
如何只保留你想要的 DNS?
你可以根据你使用的网络配置方式,永久移除多余的 DNS。以下以使用 systemd-resolved
为例:
编辑配置文件:
sudo nano /etc/systemd/resolved.conf
内容如下:
[Resolve]
DNS=1.1.1.1 8.8.8.8
FallbackDNS=9.9.9.9
保存退出后,重启服务:
sudo systemctl restart systemd-resolved
再强制用这个配置:
sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
最后确认配置是否生效
cat /etc/resolv.conf
如果看到只有这几项:
nameserver 1.1.1.1
nameserver 8.8.8.8
或者再加个 fallback:
nameserver 9.9.9.9
说明配置已经完全生效。
可选:防止其他程序修改 resolv.conf
:
sudo chattr +i /etc/resolv.conf
Clash 层配置:确保所有查询走代理
如果你在 VPS 本机运行 Clash 并转发代理流量,建议打开 DNS 拦截功能:
Clash 配置文件关键字段(config.yaml):
mixed-port: 7892
socks-port: 7891
port: 7890
allow-lan: true
mode: rule
log-level: info
external-controller: 0.0.0.0:9090
dns:
enable: true
listen: 127.0.0.1:53
ipv6: false
enhanced-mode: fake-ip
nameserver:
- tls://1.1.1.1
- tls://8.8.8.8
fallback:
- https://1.0.0.1/dns-query
- https://9.9.9.9/dns-query
fake-ip-filter:
- '*.lan'
- 'localhost'
参数说明:
- enable:启用 Clash 的 DNS 拦截功能
- enhanced-mode: fake-ip:生成虚拟 IP 响应,避免真实请求绕过
- nameserver:使用加密协议如 DoT(DNS over TLS)保护查询隐私
- fallback:在主服务器失效时备用(DoH 格式)
如果你使用的是 Clash.Meta,也支持更高级的 DNS 分流策略。
验证效果:三重方法确认彻底解决
操作完成后,再次验证效果:
方式一:查看系统 DNS 状态
resolvectl status
应只显示你配置的 DNS:
DNS Servers: 1.1.1.1, 8.8.8.8
方式二:dig 验证请求路径
dig google.com
dig +short whoami.cloudflare
返回的 IP 应位于 Cloudflare POP 节点(非阿里云)
方式三:浏览器 DNS 检测站点
再次访问检测网站,结果应仅显示公共 DNS 运营商如 Cloudflare、Google。
常见问题解答与建议
Q1:为什么 resolv.conf 里还是有 100.100.2.136?
说明你没有禁用 DHCP DNS 注入,或者系统使用 NetworkManager 覆盖了配置。
Q2:Clash 的 fake-ip 会不会导致问题?
某些特殊服务(如 Docker、K8S、某些内网服务)可能无法识别 fake-ip,建议添加白名单或改用 redir-host。
Q3:VPS 每次重启都还原了配置怎么办?
建议将 DNS 配置写入 cloud-init 或封装成启动脚本自动执行。
Q4:有没有必要用 DNS over HTTPS(DoH)?
在重度匿名或防审查场景中,DoH 可以更好隐藏查询内容,但对性能略有影响。一般场景下 DoT 即可。