使用 clash 上网时应对 dns 泄露的心得

2024 年 4 月 21 日
 RageBubble

** 本人使用的是 clash verge rev 客户端,内核为 clash-meta ( mihomo ),windows 系统。

一、

最近我对上网隐私有些关注,虽然 vpn 可以有效保护隐私,但根据大家都知道的原因,vpn 上网在国内非常不方便,一个是无法根据域名和 ip 分流,另一个是 vpn 协议太容易被检测。所以我就在想,使用 clash 这类更符合国情的代理软件,怎么才能保证基本的隐私和信息安全呢?

当然我只是追求基本的隐私保护,对于更高的安全需求,当然可以使用 tor 网络和虚拟机等,这些不在此次讨论范围,我主要以 ipleak.net 这类网站的结果作为判断标准。

ipleak.net 这类网站对泄露的检测可以分为三类:dns 泄露,ip 泄露,webrtc 泄露。

只要使用 clash 上网,ip 泄露和 webrtc 泄露检测的结果都是代理服务器的 ip ,这两个没什么问题。但是对于 dns 泄露,我总是发现检测到的服务器列表里,除了国外的服务器,竟然还有很多是国内的 dns 服务器(包括本地 isp 运营商的),而在我的 clash 中(系统代理+规则模式),dns 字段里 nameserver 设置的是 8.8.8.8 ,fallback 设置的是国外加密 dns 。这有些不对劲,因国内的 dns 服务器不应该出现。

这里说明一下,clash 的 dns 字段里,nameserver 就是主要使用的 dns 服务器,default-nameserver 是用来解析 nameserver 中的加密 dns (如果有加密 dns 的话),fallback 是备用的 dns 服务器,当 clash 要发出 dns 请求时,如果 fallback-filter 没有特别设置,会并发的向 nameserver 和 fallback 中的 dns 服务器发出解析请求,使用最早响应的那个结果。

言归正传,为了搞清楚这背后的原理,我做了很多测试,用到了 wireshark 抓包 53 端口的 dns 请求。发现 wireshark 中,电脑是按照 clash 配置正确地,并发地向 nameserver 和 fallback 中的 dns 服务器发出了域名解析请求( ipleak 提供的测试域名),也收到了发回的响应,所以不太可能是 clash 或者 windows 系统的问题。

我推测会不会是因为 nameserver 使用了明文 dns ,导致 dns 泄露,使得 isp 运营商的 dns 服务器也向测试域名发出了解析请求。于是我把配置里 nameserver 中的 dns 服务器全部替换成加密 dns ( DOH ),果然,再次检测后就再也没有中国 dns 服务器的踪迹了。

需要说明的是,当 clash 使用系统代理+全局模式时,dns 请求会被 clash 加密并全部发往代理服务器,是让代理服务器的 dns 去解析域名,所以也不会出现国内 dns 服务器的踪迹。

二、

在解决了上面的 dns 泄露问题后,我又有了新的疑惑。

clash 系统代理下的规则模式打开,通过 ipleak 网站测试,我发现明明 clash 日志中这些 ipleak 的测试域名最后都是命中了我规则中最后一行的 final ( final 的作用是兜底,当前面的所有规则都没有命中时,域名最后会命中 final 规则,我设置的是命中 final 规则后使用代理服务器).本应该是通过代理服务器去解析域名,但得到的结果和全局模式下检测到的 dns 服务器不同,而且 wireshark 中会发现 clash 在通过 nameserver 和 fallback 发送域名解析请求.

因为根据那张流程图,域名命中代理规则后应该直接让代理服务器去解析域名,电脑上的 clash 是不该发出这些请求的。这是为什么呢?原因只能是这些测试域名既通过了代理服务器解析域名,又通过 clash 的 dns 去解析域名。

我又折腾了一下,到处上网查阅,仔细查看那张 dns 解析流程图,我注意到了“匹配到基于 ip 的规则”这几个字,瞬间恍然大悟。原来这是因为 clash 通过从上往下的方式一条条匹配规则,直到命中规则停止。这些测试域名的确命中了 final 规则,通过代理服务器的 dns 解析了域名。

但是,在此之前,由于我的配置中有基于 ip 的规则存在,位置比 final 规则更靠前,并且没有加上 no- resolve 这个参数( no-resolve 告诉 clash 在遇到基于 ip 的规则时,不要去单独解析域名),导致在遇到这些靠前的 ip 规则时,clash 会先通过 nameserver 和 fallback 中的服务器并发请求,以查看该域名是否符合该 ip 规则,不符合则继续往下匹配规则,最后命中了 final 规则。

所以这就是为什么在我的电脑上,这些 ipleak 的测试域名既会先被 clash 上的 dns 解析,还会被代理服务器上的 dns 解析。而在全局模式下,因为不需要判断规则,这些自定义测试域名只会被代理服务器解析。

三、

说了这么多,我总结出来的经验是,要想避免 dns 泄漏,一个方法是在 nameserver 中使用加密 dns ,另一个是给配置中的 ip 规则后面加上 no- resolve ,告诉 clash 直接跳过,不要去解析域名。最后是 fallback-filter 中设置 geosite 为“!CN”等,这样在遇到国外的网站域名时,clash 不会再并发请求,只会使用 fallback 的 dns 服务器而不会使用 nameserver 中的服务器。可以看出,最后两个方法的思路都是不让 clash 向 nameserver 发送国外网站的 dns 请求。为了防止 dns 泄露,这三个方法我建议最好同时使用。

上面就是最近这段时间我自己折腾后整理出来的心得,希望能帮助知道如何处理出现的 dns 泄露。不知道文中有没有什么错误,欢迎大家反馈。另外,我到现在也不太清楚图片中的 fake-ip 未命中和 fakeip-Direct 未命中是什么意思,该如何理解,希望有大佬解释一下。

50283 次点击
所在节点    宽带症候群
99 条回复
superht
2024 年 4 月 22 日
按道理,nameserver 设为非加密 dns ,并不会导致 dns 泄露,可能是有其他地方导致的泄露。而且建议 namesever 设为国内 dns ,同时用尽量完善的规则覆盖国外访问,这样你才能获得最佳体验,避免访问国内网站不顺畅、且无法获得 cnd 优势。

fallback 的作用是对比,当出现和 nameserver 不同时,采用 fallback 的结果。如果你用 fakeip 模式的话,建议删掉 fallback 。因为 fakeip 模式下,不需要拿到真实 ip 才能发起访问,且域名发到代理服务器进行 dns 解析了,本地的 fallback 解析对比失去了意义。

fakeip-direct 是指未命中缓存、且规则为“直连”的域名或 ip 。

要保障 dns 不泄露,应该完善规则----把经常访问的域名或 ip 放到规则中( ip 加上 no-resolve )----尽量实现远程 dns 解析。官方文档中有一套推荐配置,防漏效果已经很不错了,可以参考一下。
xwhxbg
2024 年 4 月 22 日
@RageBubble 并不会,tun 模式下是会自动把 53 端口的流量导入 clash 的 dns ,这个是通过软路由实现的( windows ),如果 enable 了的话,但是 http 和 https 代理下并不会做这个,之所以你用 doh+全局就让 dns 能走 clash 单纯是因为 doh=https ,https 会走 http 和 https 代理
isukkaw
2024 年 4 月 22 日
@sapphire #58 整篇文章其实就下面一段话和这个问题有关,我直接 quote 出来好了:

> **避免 DNS 污染和 DNS 泄漏最有效的办法就是(让这个域名)永远不在本地进行 DNS 解析**,而 Surge 和 Clash **能且只能通过 Fake IP 和域名规则匹配**的方式 可以实现非直连域名 **一定不在本地本机进行任何 DNS 解析**。在 Surge 和 Clash 中,规则自上而下匹配,**只有当遇到 IP 类规则(如 IP-CIDR 、IP-CIDR6 、GEOIP 和 IP-ASN )时才会发起 DNS 解析**。因此,在 Surge 中,**将会触发 DNS 解析的规则放在域名和 URL 匹配规则后面非常重要**。
>
> ---------------------
> 本文著作权归作者 Sukka 所有。本文采用 CC BY-NC-SA 4.0 许可协议,商业转载请联系作者获得授权,非商业转载请注明出处。
> 作者:Sukka
> 来源:我有特别的 Surge 配置和使用技巧
> 链接: https://blog.skk.moe/post/i-have-my-unique-surge-setup/
sapphire
2024 年 4 月 22 日
@isukkaw Sukka 之前写过几篇来解释 DNS 相关问题,这也是我为何要把文章链接发出来,原文开头就 DNS 说明如下:

如果没有相关的知识储备,你在阅读本文时可能会难以理解分流规则和配置。你可以阅读我之前写过的 数篇关于 DNS 的文章,本文不会再做详细赘述。
sapphire
2024 年 4 月 22 日
@isukkaw 抱歉,原来 Sukka 本尊
heganyuliang
2024 年 4 月 22 日
@Puteulanus #53 诈骗网站确实需要另当别论,所以我最开始也说了单纯隐藏翻墙的话检查 dns 泄露意义不大
RageBubble
2024 年 4 月 22 日
@isukkaw 哈哈,今天正好在都你网站上写的“浅谈在代理环境中的 DNS 解析行为”
RageBubble
2024 年 4 月 22 日
@isukkaw 我刚好有个问题想请教一下您。在 tun 模式下,wireshark 捕获 tun 网卡可以直接看到发起的 dns 请求与返回的 fakeip ( 198.18.0.1/16 ),但是在系统代理下,为什么我在 loopback traffic capture 接口上却看不到发起的 dns 请求或者任何返回的 fakeip 呢,是因为 clash 的 fakeip 只会在 tun 模式下生效吗还是因为某种原因不经过 loopback 接口?
Knights
2024 年 4 月 22 日
我这样配置后上 V2EX 就没有本地 dns 查询了:
nameserver:
- "tls://8.8.8.8:853#yun"
- "tls://1.1.1.1:853#yun"
nameserver-policy:
geosite:cn,private:
- 192.168.1.1 //本地的 adguard home
rules:
- GEOSITE,CN,DIRECT
- GEOIP,CN,DIRECT
- MATCH,yun

Firefox 里设置 socks5 代理 dns 查询
BadFox
2024 年 4 月 22 日
谢谢楼主分享,另外请问一下这个图是用什么画的呀?
RageBubble
2024 年 4 月 22 日
@BadFox 这是 mihomo 官方 wiki 中的图片,不是我画的
Nobin
2024 年 4 月 22 日
另外提一嘴,Windows 有个“智能多宿主名称解析”功能,这个功能很坑,**务必关闭**。

"智能多宿主名称解析"( LLMNR ,Link-Local Multicast Name Resolution )是微软引入 Windows 的加快 DNS 解析速度的功能,通过在所有可用的网络适配器上发送 DNS 请求来实现,并自动选择返回速度最快的信息。

尽管从性能角度来看,这个功能是有道理的,但它在隐私方面引入了一个问题。

例如,在 Windows 机器上连接到代理网络时,智能多地址名字解析可能导致 DNS 泄漏。因为请求会同时发送到所有网络适配器,所有配置的 DNS 服务器都会收到这些请求,从而获取你访问的网站信息。
stone9527
2024 年 4 月 22 日
@sapphire Sukka 的配置我用了,对我来说不怎么好用
Holodusk
2024 年 4 月 22 日
好多人都忽略了 Clash 有个特点:域名 UDP 流量一定会触发 DNS 解析。
除了把国外网站都加到 nameserver-policy 里没有很好的解决办法
RageBubble
2024 年 4 月 23 日
@superht 那张图中的 fakeip 未命中又该怎么理解呢?
RageBubble
2024 年 4 月 23 日
@RageBubble #50 泄露是因为没有在 clash verge rev 上的 tun 设置中开启“严格路由”,导致 windows 使用了智能多宿主名称解析,让系统 dns 也去解析域名。要避免这一点,一个是开启“严格路由”,另一个就是手动关闭 windows 上的智能多宿主名称解析服务。直接去修改系统 dns 也是一种办法,但没有前两种方法更直接。
RageBubble
2024 年 4 月 23 日
@xwhxbg #62 以浏览器举例,系统代理下,浏览器发出域名请求,只需要把域名封装到 http 或者 socks5 代理中交给 clash 处理,和 udp 什么的没关系。
RageBubble
2024 年 4 月 23 日
@isukkaw 我在自己的电脑上测试了一下:

fakeip 似乎只会在 tun 模式开启后才使用

tun 规则模式下:
如果最后是代理连接,clash 中的 fallback 查询 dns (以太网接口),程序用 fakeip 发起 tcp 连接( tun 接口),使用代理服务器发起 tcp 连接(以太网接口)。

如果是直连,clash 中的 nameserver 查询 dns (以太网接口),程序用 fakeip 发起 tcp 连接( tun 接口),本机对真实 ip 发起的 tcp 请求(以太网接口)。

代理软件 clash 在 fakeip 模式下还是会进行 DNS 解析,这点和你文章中说的有些不同

系统代理下:
程序会直接通过 http 代理与 clash 建立 tcp 连接,然后 clash 去处理域名解析(程序发送 client hello 后到服务器返回 server hello 之间有明显的时间间隔,就是用来处理域名解析的时间)
superht
2024 年 4 月 23 日
@RageBubble #75 “FakeIP 未命中,代理域名”这类应该属于既不是直连、又未匹配到规则,也就是最终匹配到 match 或 IP 规则了,这类会通过 nameserver dns 进行解析,解析到国内 ip 就直连,解析到国外 ip 就把 ip 发给代理,要求代理进行连接。如果 clash 有开启域名嗅探功能,解析到国外 ip 情况下,仍然会将域名传递给代理服务器,进行远程 dns 解析,优化连接
RageBubble
2024 年 4 月 23 日
clash verge rev 未来会移除 fallback-filter 的 geosite ,建议直接使用 nameserver-policy 中的 geosite, nameserver-policy 优先于 nameserver/fallback 查询

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://study.congcong.us/t/1034325

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX