NDS泄露
开始之前先用 https://ipleak.net/ 这个网站查看一下你的DNS请求是否有泄露。
如果列表中有国内的DNS服务器,那肯定泄露了。即使没有国内的 DNS
,如果同一个节点使用全局模式和分流模式的检测结果不同,出现了新的 DNS
提供商,也大概率泄露了。并且直接把 DNS
泄露检测的网站添加到分流规则中来绕过 DNS
泄露,是一种掩耳盗铃的做法。

DNS
的泄露会导致运营商或者防火墙知道你在访问 Google
、YouTube
、Facebook
等网站,说白了就是知道你在科学上网。另外,像 Netflix
这种对地区敏感的应用,会通过 DNS
来判断你的实际所在地。如果存在泄露,将会被判定为使用了代理工具,可能无法使用他们的服务。
这篇主要讲讲为什么 DNS
会泄露,以及移动端和 PC
如何解决 DNS
泄露,顺便能解决有时无法访问部分网站的情况。
但是开始之前还有一个名词叫DNS污染:
DNS 污染的原理
- 正常 DNS 查询流程:
- 你的设备向 DNS 服务器发送查询请求(如
facebook.com
)。 - DNS 服务器返回正确的 IP 地址(如
31.13.71.36
)。
- 你的设备向 DNS 服务器发送查询请求(如
- DNS 污染的流程:
- 攻击者或干扰者伪造 DNS 响应,返回一个错误的 IP 地址(如
1.2.3.4
)。 - 你的设备接收到伪造的响应,并尝试连接错误的 IP 地址。
- 结果可能是无法访问目标网站,或者被重定向到钓鱼网站。
- 攻击者或干扰者伪造 DNS 响应,返回一个错误的 IP 地址(如
DNS 污染的实现方式
- 中间人攻击(MITM):
- 攻击者在你的设备和 DNS 服务器之间拦截并篡改 DNS 响应。
- 伪造 DNS 服务器:
- 攻击者运行一个恶意 DNS 服务器,返回虚假的 IP 地址。
- 网络运营商或政府干扰:
- 某些国家或地区通过 DNS 污染技术屏蔽特定网站(如 Google、Facebook)。
如何防止 DNS 污染?
- 使用加密 DNS:
- 启用 DNS-over-HTTPS(DoH)或 DNS-over-TLS(DoT),加密 DNS 查询,防止被篡改。
- 例如:在浏览器中启用 DoH(如 Firefox 的加密 DNS 功能)。
- 更换可靠的 DNS 服务器:
- 使用受信任的公共 DNS 服务器,如:
- Google DNS:
8.8.8.8
和8.8.4.4
- Cloudflare DNS:
1.1.1.1
和1.0.0.1
- Google DNS:
- 使用受信任的公共 DNS 服务器,如:
- 使用 VPN:
- VPN 可以加密所有网络流量,包括 DNS 查询,防止 DNS 污染。
- 手动修改 hosts 文件:
- 对于经常访问的网站,可以在本地 hosts 文件中直接绑定域名和正确的 IP 地址。
接下来讲解DNS泄露!
DNS泄露(DNS Leak)是指在使用虚拟专用网络(VPN)时,设备的DNS请求并没有通过VPN隧道加密发送,而是通过用户的默认DNS服务器(通常由本地互联网服务提供商提供)发送。这样就暴露了用户正在使用VPN访问的内容,使用VPN的意义就大打折扣,甚至可能有攻击者通过伪造DNS记录,窃取到本该通过VPN通道发送的内容,
DNS
原本是一个非常简洁明了的协议,就是负责将域名解析成 IP
。
但是为了实现分流,让这个原本简单的协议在代理中应用变得异常复杂。有些不正确的配置以为自己没漏,实际上早已露出了鸡脚。
要解释清楚 DNS
泄露是怎么产生的,就需要先来了解 DNS
的工作流程。先来创建一个最常见的家庭网络环境。你在运营商拉了一条宽带,它会给你分配一个光猫。一般来讲,你会单独再买一台路由器连着光猫,路由器通过 PPPoE
拨号,获取运营商分配的公网 IP
和 DNS
服务器。假设公网 IP
为 2.2.2.2
,DNS
服务器一般会分配两个,假设其中一个的 IP
为 3.3.3.3
。同时,路由器作为局域网的网关,会有自己的内网 IP
地址,假设为 192.168.0.1
。家里的所有网络设备都会连接到这台路由器,路由器通过 DHCP
为每一台网络设备分配一个内网 IP
以及默认网关、DNS
等信息。一般情况下,默认网关和 DNS
服务器都是路由器。这是最常见的家庭网络拓扑。
首先,浏览器会检查浏览器 DNS
缓存里是否有百度的 IP
,发现缓存列表中并没有。除去浏览器的 DNS
缓存,操作系统本身也有 DNS
的缓存列表,可以通过 ipconfig /displaydns
查询,其中包含我们在系统 hosts
文件中手动添加的绑定记录。
如果在操作系统 DNS
缓存中也没有找到,浏览器会构建一条 DNS
查询的应用层数据包,内容是百度的 IP
地址是多少。 DNS
服务的默认端口是 53
,默认传输方式是 UDP
,所以传输层会以 UDP
的方式进行封装,并且目标端口是 53
。网络层会封装源 IP
和目标 IP
,源 IP
是本机电脑的 IP
,目标 IP
是本机电脑配置的 DNS
服务器,也就是路由器的 IP
192.168.0.1
。接着封装 MAC
地址,并从网口发出数据,会来到路由器。

路由器一看目标 IP
是自己,于是会一层层地解封装,得到电脑的 DNS
请求。
路由器同样首先检查自己的 DNS
缓存列表中是否有百度的 IP
地址,发现并没有。

于是会构建一条 DNS
查询的应用层数据包,内容同样是 baidu.com
的 IP
地址是多少,目标 IP
为路由器配置的上游 DNS
服务器 3.3.3.3
,并将其发送到互联网。

数据包会来到运营商给我们分配的 DNS
服务器 3.3.3.3
,收到数据后,得知了路由器想要百度的 IP
,同样先检查自己的缓存列表,没有的话,再询问其他上游 DNS
服务器。运营商的 DNS
一般会配置多个上游 DNS
服务器,具体发给哪一台,会根据自己的负载均衡策略选择。
假设发给了 IP
为 6.6.6.6
的服务器,并且假设这台服务器没有配置 DNS
转发,所以不会将请求转发给其他 DNS
服务器,而是负责帮我们查询百度的 IP
。这里查询过程不详细描述。
我们只需要知道,最终这台 DNS
服务器会找到解析 baidu.com
这个域名的权威 DNS
服务器,并把这条请求交给他。


记住红色部分是我们当前两台服务器通信的 IP
。百度的权威服务器收到请求后,他这里会有 baidu.com
这个域名绑定的 IP
,于是将 IP
和 TTL
返回给这台 DNS
服务器。
TTL
在 DNS
中表示缓存时间,假设为十分钟。
这台 DNS
收到数据后会缓存下来,并将结果告诉了运营商的 DNS
。运营商的 DNS
同样也会将结果缓存,并发回给我们的路由器。路由器也是同样的操作,缓存下来,并将结果发回给我们的电脑。
但是家用路由器的性能有限,可能为了节省内存,会将 TTL
值设置得相对较小,比如 30
秒。
当浏览器获取到 IP
之后,才正式地开始发起访问百度的请求。
如果 TTL
值到期了,则会将记录从缓存中移除,又得重新发起 DNS
请求,获取百度的 IP
了。
为什么需要 DNS
,以及 DNS
的执行流程相信大家都清楚了。接下来就是我们今天的主题,为什么会存在 DNS
泄露。DNS
泄露的说法只有在我们使用代理之后才存在。
假设我们当前没有使用代理的情况下查询 DNS
泄露,列表中返回了国内的 DNS
服务器,这只能说明这些 DNS
服务器负责帮我们进行了 DNS
查询,并不代表 DNS
泄露了。如果此时我将电脑的本地 DNS
服务器改成 1.1.1.1
,意思是让 1.1.1.1
负责 DNS
解析,列表中返回了美国的 DNS
服务器,这也不能说明 DNS
没有泄露。
只有当我们通过代理访问目标网站时,电脑给互联网发送了请求目标网站 IP
地址的明文 DNS
请求,这种情况就是 DNS
泄露。
要讲清楚这个问题,就必须先来了解这个网站是如何进行 DNS
检测的。按 F12
调出浏览器的开发者面板,来到网络面板,可以看到网站在不停地发送请求,并且每个请求访问的域名都不一样,目的是为了确保我们的 DNS
缓存以及所有上游 DNS
缓存中都没有这条记录。



根据之前的讲解,当浏览器中没有找到缓存,会构建查询域名 IP
的 DNS
请求。
由于域名完全随机,上游 DNS
也不可能会有缓存,请求将被转发到运营商的 DNS
。由于运营商配置了多个上游 DNS
服务器,可能会交给不同的上游。
假设交给了第二台,这台 DNS
负责去寻找这个域名的 IP
,最终会找到这个域名的权威 DNS
服务器。
由于设置了泛解析,查询任何子域名都能获取到 IP
。权威服务器在返回结果给你的时候,偷偷做了一个动作,记录下了 DNS
服务器的 IP
地址,并且告诉了查询 DNS
泄露的网站。
由于每个访问者使用网站进行查询时,域名是完全随机的,也就是说,每个人发起 DNS
查询的域名都不一样,所以网站根据这条查询记录就能知道是你在使用这个 DNS
服务器,再根据 IP
归属地得知这个服务器的地理位置。
由于网站在不停地发送新的域名进行探测,运营商的 DNS
可能会使用不同的上游 DNS
,所以可以探测到多个不同的 DNS
服务器 IP
地址。

另外,虽然 1.1.1.1
是任播 DNS
,但我们国内使用的话会被反向优化到美国,用美国的 DNS
服务器,那么它的上游 DNS
也肯定是美国的 IP
。
所以当我将本地的 DNS
改成 1.1.1.1
之后,DNS
泄露查询到的都是美国的 DNS
服务器。
所以 DNS
泄露的并不是你的电脑 IP
,而是你上上上上上上游的 DNS
服务器 IP
。
这里可能松了一口气,觉得并没有什么大不了。但那么再来看一下使用代理之后是一个什么情况。
首先,浏览器要访问谷歌,由于配置了系统代理,浏览器不再进行 DNS
查询,而是直接将访问网站的请求交给我们的代理客户端。
代理客户端拿到请求之后,此时会有两种情况:
一种是不发起
DNS
请求就能判断它是走直连还是走代理,这种情况基本不存在DNS
泄露;另一种情况是发起
DNS
请求,获取到IP
之后,再来根据IP
判断是走直连还是走代理,这种情况大概率存在DNS
泄露。即使你配的DNS
是1.1.1.1
或者8.8.8.8
这种国外的DNS
提供商,只要发起了DNS
请求,那就泄露了,还会迷惑你,因为查不到国内DNS
,还以为没有泄露。
假设 Clash
使用了 IP
规则进行分流,所以需要先得到谷歌的 IP
地址,于是会发起 DNS
请求,内容是谷歌的 IP
地址是多少。
当这条请求发给互联网的 DNS
服务器之后,问题就发生了。DNS
请求是完全明文的,除非你使用 DoT
或者 DoH
进行加密,或者有些客户端默认会将 DNS
请求通过节点加密进行远程 DNS
,这两种情况都会增加延迟,不算是好的方案。
大部分用户都不会进行加密和远程 DNS
,也就是说,运营商或者中间任何一台路由器都可以看到你的意图是访问谷歌。后面的情况也就不用我细说了。当你要完谷歌的 IP
之后,马上给其他服务器发送一堆加密数据,鬼都知道你在干啥,甚至可能根据这个行为来封禁节点服务器。
再假设 Netflix
这种对地区要求高的网站,偷偷地发送了一个 DNS
请求,如果存在 DNS
泄露,负责跟 Netflix
的权威 DNS
服务器对话的这台 DNS
服务器的 IP
归属地就会和当前访问 Netflix
网站的代理 IP
不是同一个地区,那就判定你在使用 VPN
工具,禁止观看。
当然这是我的假设,实际上 Netflix
有没有这样做,我并不清楚,猜的。从技术角度来讲这是可以实现的,并且是一个非常强的代理特征。这就是 DNS
泄露以及 DNS
泄露所导致的问题。
问题已经提出来了,那要怎么解决呢?
DNS
泄露的原因就是在代理的情况下,本地发送了 DNS
请求,那只要让本地不发送 DNS
请求,直接将数据加密后发给节点服务器,就能避免了。因为加密的数据中已经包含了域名,节点服务器会负责 DNS
并帮我们访问网站。
本地进行 DNS
请求获取 IP
的行为只是为了匹配分流规则,所以只要我们的分流规则配置合理,就可以避免发起 DNS
,从而降低延迟,解决 DNS
泄露。
v2rayN
的用户比较简单,直接使用客户端提供的绕过大陆路由方式,就能解决 DNS
泄露的问题。更进一步,可以进入路由设置,将域名策略改成 AsIs
。如果你以前手动修改过绕过大陆的路由规则,可以双击进入修改,将配置恢复成官方规则即可。
Clash
麻烦一点,因为分流规则都写在订阅文件中。
解决这个问题的话要通过订阅转换,可以使用你信得过的订阅转换地址。在订阅链接中填入你的订阅地址或者节点,远程配置随便选择一个,点击生成订阅,会自动复制到剪贴板。
[custom]
;解决DNS泄露,无分流群组
ruleset=🚀 节点选择,[]DOMAIN-SUFFIX,xn--ngstr-lra8j.com
ruleset=🚀 节点选择,[]DOMAIN-SUFFIX,services.googleapis.cn
ruleset=🚀 节点选择,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/Ruleset/GoogleCNProxyIP.list
ruleset=DIRECT,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/LocalAreaNetwork.list
ruleset=DIRECT,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/UnBan.list
ruleset=DIRECT,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/ChinaDomain.list
ruleset=DIRECT,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/ChinaMedia.list
ruleset=REJECT,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/BanAD.list
ruleset=REJECT,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/BanProgramAD.list
ruleset=DIRECT,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/ChinaCompanyIp.list
ruleset=DIRECT,https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/ChinaIp.list
ruleset=DIRECT,[]GEOIP,CN,no-resolve
ruleset=🚀 节点选择,[]FINAL
custom_proxy_group=🚀 节点选择`select`[]♻️ 自动选择`[]DIRECT`.*
custom_proxy_group=♻️ 自动选择`url-test`.*`http://www.gstatic.com/generate_204`300,,50
enable_rule_generator=true
overwrite_original_rules=true
然后 将 config
远程配置文件的网址删除,把https://cf.buliang0.cf/clash-rules/nodnsleak.ini复制过去,将其粘贴到 Clash for Windows
中进行订阅下载。
如果下载失败,可以尝试将远程配置网址进行 URL
编码,或者换一个订阅转换后端。这条就是防 DNS
泄露的订阅地址,使用 Clash
内核的客户端都可以使用这个配置文件。这样设置后,使用系统代理就不会出现 DNS
泄露了。
如果使用 TUN
模式,则还需要进一步设置。
内置 DNS
要使用 fake-ip
模式,不要使用 Clash
已经弃用的 redir-host
模式。默认就是 fake-ip
,不要去改它。
还没有完,和系统代理不一样,由于 TUN
模式是操作网络层,对于 DNS
的处理会更复杂。即使规则已经走全局,也还是会发起 DNS
请求。正常情况下,Clash
的虚拟网卡会进行拦截,但由于 Windows
系统默认会将 DNS
请求发给所有网卡上配置的 DNS
服务器,微软美其名曰把它叫做智能 DNS
优化,实际上会造成 DNS
泄露,因为 Clash
拦截不了物理网卡的 DNS
请求。
解决这个问题需要进行简单的设置。在开始菜单中搜索组策略,找到禁用智能多宿主名称解析,双击打开,选择“已启用”,点击应用。这样就可以禁用多网卡的 DNS
请求了。

如果你的电脑是win家庭版,可以通过运行以下方式开启策略组:
@echo off
pushd "%~dp0"
dir /b C:\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~3*.mum >List.txt
dir /b C:\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientTools-Package~3*.mum >>List.txt
for /f %%i in ('findstr /i . List.txt 2^>nul') do dism /online /norestart /add-package:"C:\Windows\servicing\Packages\%%i"
pause
然后用管理员身份运行

- 安卓的
v2rayNG
是勾选“启动本地DNS
”,启用虚拟DNS
,其实就是fake-ip
。将域名策略改成AsIs
,预定义规则设置绕过局域网以及大陆地址。其他配置按安装时默认的选项即可。记得要断开VPN
重连,规则才会生效。 Clash
除了要使用刚才的那个远程配置文件进行订阅转换之外,还需要其他设置。进入覆写,将DNS
策略改成“强制启用”,增强模式改成fake-ip
。点击nameserver
,添加DNS
服务器,填国内的即可,比如114
。你可以添加多个,这样就算是配置好了。- 最后是
iOS
小火箭。小火箭的默认配置可以避免DNS
泄露,但是分流不是很完善。可以使用 https://cf.buliang0.cf/shadowrocket-rules/nodnsleak-pk.ini 这个配置文件。点击添加配置,将地址粘贴上去,点击下载,选中刚才的这个地址,点击使用配置。最后只需要将全局路由设置为配置模式即可。
这样操作之后就能解决大部分 DNS
泄露的问题了。你可以重新检测 DNS
泄露的情况,只要全局模式和分流模式都是同样的 DNS
提供商,则大概率没有泄露。
没泄漏的情况下,如果看到了多个国家的 DNS
服务器,是你节点配置的上游 DNS
问题。如果是自建的节点,可以修改节点服务器的上游 DNS
解决这个问题。不过也可能是这个网站的 IP
归属地数据库更新不及时导致的。
另外,由于本地基本不再发起 DNS
请求,速度也会有一定的提升,也能解决 DNS
污染导致有些网站无法访问的情况。至于这样做为什么能阻止 DNS
请求,有没有缺点,下节讲 DNS
分流再来细说。
最后再来说一下浏览器的 WebRTC
泄露,会绕过代理直接泄露本机的真实 IP
。访问这个网址可以进行查询。如果存在泄露,安装这款浏览器插件,禁用浏览器的 WebRTC
功能,可以防止 IP
地址泄露。