查询dns泄露:https://ipleak.net

视频教程

视频地址:https://youtu.be/aKlH6KRt9Jc

上期我们讲过了DNS的执行流程
以及常见的客户端解决DNS泄露的方法
由于时间关系
只给大家演示了设置步骤
并没有说明为什么要那样设置
导致很多使用其他客户端的朋友
不知道该如何设置
我也不可能所有的客户端都演示一遍
主要是有很多我也没用过
其实这么多不同的客户端逻辑都是一样的
安卓的clash for andorid
电脑的clash for windows
软路由的openclash
其实都是调用clash的内核
只是操作界面不太一样
所以本期就来接着上期的话题
展开讲讲 让很多人难以理解的DNS分流
看完之后 如果你理解了
就不会因为软件的界面不同而不知道该如何设置了
并且也能做出符合自己需求的分流配置
先来回顾上节的内容
创建一个最常见的家庭网络环境
你在运营商拉了一条宽带
它会给你分配一个光猫
一般来讲你会单独在购买
一个路由器连接光猫
路由器通过PPPOE拨号
获取运营商分配的公网IP
同时路由器作为局域网的网关
会有自己的内网IP地址
假设为 192.168.0.1
家里的所有网络设备都会连接到这台路由器
路由器通过 DHCP 为每一台网络设备
分配一个内网 IP 以及默认网关 DNS 等信息
一般情况下 默认网关和 DNS 服务器都是路由器
这是最常见的家庭网络拓扑
先以第一节介绍过的Clash系统代理为例
当我们在电脑上运行Clash for Windows时
其实 它是调用了clash的内核
并且加载了yaml配置文件
配置文件可能是机场提供的订阅地址
或者是你通过订阅转换获取的
总之 配置文件的内容大概长这样
监听端口7890
配置了两个节点
以及两个节点组
第一个节点组包含两个节点
默认选中了香港节点
第二个节点组包含两个节点
默认选择了美国节点
下面是一些分流规则
此时浏览器访问www.google.com
由于设置了系统代理
访问谷歌的请求会被浏览器
转发到系统代理监听的端口7890
clash从7890端口收到数据后
会解析数据报的内容
知道浏览器想要访问谷歌
clash有全局、规则、直连、脚本 四种分流模式
大家一般用的都是规则模式
于是进入规则匹配
从上到下一条条匹配规则
语法建议看官方文档
我这里简要给大家说明一下
第一条匹配域名规则
如果访问的是google.com
则交给节点组1
默认选中的节点是香港节点
所以会将请求交给香港节点
但我们访问的是www.google.com
而不是google.com
所以不匹配进入下一条
下一条规则是后缀匹配youtube.com
很明显也不匹配
再下一条规则是关键字匹配 youtube
很明显也不匹配
下一条又是域名匹配
如果是ad.com
直接reject掉
相当于丢弃 主要用于广告屏蔽
再下一条匹配源IP段
如果源IP段是192.168.1.201
那么就走direct,也就是直连
主要用于局域网其他设备的分流
由于这个请求是本机浏览器直接发送给clash的
所以原IP为127.0.0.1
因此这条规则也不匹配
下一条匹配目标IP段
如果访问的目标是127.0.0.0/8这个网段
就走direct直连
但是我们用来匹配的是www.google.com这个域名
很明显IP和域名是没办法进行对比的
所以需要先通过上集讲的
DNS解析获取谷歌的IP地址
但是
这条匹配规则后面加上no-resolve
表示不进行DNS解析
相当于直接跳过了这条基于IP的匹配规则
下一条是IPv6的匹配规则
同样加了no-resolve
也直接跳过了
再下一条匹配GEOIP
GEOIP是一个数据库
里面包含了常见的IP归属地分类
如果是国内的IP
就走直连 由于后面没有加no-resolve
所以需要将谷歌的域名解析为IP进行匹配
由于clash没有配置DNS模块
所以会交给电脑配置的本地DNS服务器进行解析
clash会构建一条查询谷歌域名的DNS请求
发送给电脑配置的本地DNS服务器
也就是路由器
由于DNS请求是明文的
此时就产生了DNS泄露
后面的解析步骤就是上期讲过的内容了
这里要注意的是
请求被墙的域名
大概率你会收到一条被污染的DNS响应
假设谷歌的真实IP是4.4.4.4
但是你收到的谷歌IP却是5.5.5.5
这就是DNS污染
clash拿到这个被污染的DNS响应
以为谷歌的IP就是5.5.5.5
于是会用这个IP和GEOIP的规则进行匹配
发现这个IP的归属地不是国内
所以这条规则也是不匹配的
有的朋友可能有疑问 你怎么知道他不是国内的
我也不知道 猜的
因为一般情况下不会污染成国内的IP
但也不能保证
大家可以思考一下如果是国内的IP会导致什么情况
接着匹配源端口和目标端口以及进程名称
如果是curl这个进程发起的请求
则交给节点组2
节点组2默认选中了美国的节点
很明显以上规则都无法匹配www.google.com
clash还有一个兜底
叫做MATCH
所有没有匹配的规则全都交给MATCH处理
也就是节点组1
所以这条访问谷歌的请求
交给了节点组1的香港节点
将会使用香港ss节点的配置信息
对数据进行加密
这里要注意的是
刚才DNS获取到的IP
只是用来进行IP规则的分流匹配
你发给香港节点还是域名
所以节点收到数据后
会在他的网络环境中再次进行
DNS解析 获取了正确的谷歌IP
本地的DNS污染并不会影响
但是存在DNS泄露
解决这个问题有两个方法
一种是上期给大家提供的解决方案
给所有基于IP分流的匹配规则
都加上no-resolve
这样就不会触发DNS请求
但是会有一个问题
假如此时我想访问百度
clash说到请求后会一条条进行匹配
当来到GEOIP这条规则时
如果没有加no-resolve
会发起DNS请求 获取百度的IP
返回的肯定是一个国内的IP
也就匹配上了这条规则
将会走直连
但是为了防止DNS泄露
我加上了no-resolve
这样就不会发起DNS请求
百度的域名也就无法和IP归属地进行匹配
这条规则直接跳过了
最终将会交给MATCH走代理出去
这肯定不是我们所希望看到的
所以我给大家提供的配置文件中
不仅所有IP规则都加上了no-resolve
同时加上了国内域名走直连的分流规则
这样百度等国内网站通过域名匹配也可以走直连
但是一些小众的国内网站并不在规则列表里
所以会出现走代理的情况
这其实就是v2rayN的绕过大陆模式
这样的匹配效率最高
不会为了分流而发起DNS请求
所有国外网站都会走代理
缺点是一些小众的国内网站也会走代理
你可能需要单独为这些网站添加走直连的规则
如果你平时主要访问国外网站
这种模式比较适合你
另一种方式类似v2rayN的黑名单模式
就是在IP规则前
先把所有的黑名单网站的匹配规则先加上
比如google youtube
facebook twitter等等
这样就可以优先匹配到域名规则
直接交给节点处理
不会再往下匹配
也就不会触发IP规则的DNS请求了
需要注意的是 有些机场的clash订阅
会把没将no-resolve的IP规则放在前面
导致优先发起了DNS请求
造成DNS泄露
如果用这个配置访问上期演示过的DNS泄露网站
由于没有匹配到上面的任何规则
会来到GEOIP这条没有加no-resolve的IP规则
于是使用本地DNS发起了DNS请求
之前也讲过 这个网站会记录你的上游DNS服器的IP地址
很显然列表中将会显示国内的DNS提供商
clash得到IP后 发现归属地不是国内
于是会继续向下匹配
最终还是走了代理
节点收到域名后会再次进行DNS获取IP
所以列表中的香港DNS是
节点服务器使用的DNS提供商
上期我开头说
如果列表中有国内的DNS提供商
说明 肯定泄露了
那你觉得这种情况算DNS泄露吗
虽然检测到了国内的DNS提供商
但是如果你只在意google
youtube等网站有没有泄露
这样的配置确实是没有泄露

真有这么简单的话 就不会难倒这么多人了
如果使用系统代理这种侵入性较小的方式
确实这样的分流配置就能解决DNS泄露
真正让人难以理解的是在软路由
手机端和TUN模式这种透明代理的情况下的DNS流程
前面讲的这么多
主要是让大家熟悉clash的执行流程
接下来才是本期的重点
先来改变一下当前的网络结构
clash不再设置为系统代理
而是开启了TUN模式
或者不在电脑中运行
直接运行在路由器里
路由器会将局网其他设备访问
互联网的数据转交给clash
这样更容易理解一点
配置文件跟系统代理主要的区别
是添加了DNS模块
此时浏览器访问谷歌
根据上期讲的内容
浏览器将首先发起DNS请求
获取谷歌的IP
数据包会来到路由器
路由器会将DNS请求劫持到clash中
clash收到浏览器的DNS请求
他也不知道谷歌的IP是多少
再看看自己的DNS配置是redir-host的模式
这个模式必须给浏览器返回一个真实的IP
所以 clash需要先获取谷歌的IP地址
于是向这三个上游DNS服务器同时发起DNS请求
谁第一个返回就用谁的结果
假设114最先返回了谷歌的IP为5.5.5.5
记住这个是被污染的结果
clash有个映射表
用于保存查询的结果
并将结果返回给浏览器
浏览器拿到谷歌的IP
向这个IP发起访问谷歌的http请求
请求来到路由器的clash
clash查看映射表中IP对应的域名
用域名进行规则匹配
匹配了第一条规则
于是将请求交给节点组1的香港节点处理
这里要注意
交给节点处理的还是谷歌的域名
由远程的节点服务器再次进行DNS解析
获取正确的谷歌IP
所以本地即使是污染的IP也并没有关系
但由于redir-host必须给浏览器返回一个真实的IP
所以clash必然要发起DNS请求
去获取谷歌的IP
这样就必然存在DNS泄露
还有一个更大的问题
假如浏览器接下来访问youtube
还是先发起DNS请求获取youtube的IP
由于使用redir-host的模式
clash会向三个上游DNS服务器
同时发起查询youtube IP的DNS请求
假设114最先返回youtube的IP为5.5.5.5
和刚才谷歌的IP一样
他们搭建在同一个服务器上
或者说被污染到同一个地址
浏览器拿到IP后发起访问youtube的http请求
请求来到clash
这时查看映射表就出了问题
IP是一样的
clash不知道要访问哪个域名
大家可能会想
http请求中不是有youtube的域名吗
直接看http的域名不就行了
但是clash并没有类似v2ray的流量探测功能
所以无法探测http请求的域名
为了解决这个问题
clash的redir-host模式不再进行远程DNS
也就是节点服务器收到的
直接就是5.5.5.5这个IP地址
这样就不需要查看映射表了
但是又会造成另一个问题
5.5.5.5是被污染的IP
节点服务器拿到这个IP肯定无法正确的访问youtube
如果被污染的这个IP确实搭建了网站
还会出现访问youtube却进入
其他网站的奇特现象
由于证书和域名不匹配
浏览器会发出报警
并且有时会污染到一个保留IP
会出现其他意料之外的情况
此时可以加上fallback解决DNS污染的问题
里面主要放不会被污染的DNS服务器
比如经过加密的dot或者doh
当发起DNS请求的时候
会同时向上游的三个DNS服务器
以及fallback中的DNS服务器发起DNS请求
如果上游DNS服务器返回的IP不是国内的
就使用fallback中DNS返回的IP
以确保国外IP没有被污染
节点服务器可以拿到正确的IP进行访问
但是这样又会引起其他的问题
原本我以为clash的doh域名会匹配规则走代理
但经过测试发现是走直连
我不知道是不是bug
按正常逻辑应该要走代理
所以doh是通过本机IP直接发起的
获取到的IP地址是和本机地理位置相近的CDN服务器
这个结果对节点服务器而言
可能位置比较远
无法获得cdn优化
甚至可能导致速度变慢
关于cdn的原理 我在节点搭建系列介绍过
另外国内直联国外doh体验极差
间歇性被墙
而且加密DNS需要先握手建立连接
延迟也比较高
所以国外加密DNS提供商基本提供不了服务
还有一些机场提供DNS解锁流媒体的服务
如果直接传IP给节点
节点就无法发起DNS请求
导致解锁无效
关于DNS解锁原理 我在奈飞解锁那期也讲过
眼看redir-host的问题越修越多
就在上个月
官方直接把redir-host的模式砍了
是的没错 直接就砍了
果然解决提出问题的人才能彻底的解决问题
其实这个问题clash meta通过加入流量探测功能解决了
后面有机会再说
目前clash做透明代理 主要使用fakeip模式
ios端的小火箭 QuantumultX surge都是用fakeip
v2ray也有fakeip功能
叫做fakeDNS或者虚拟DNS
说的都是同一个东西
当我们把DNS配置为fakeip之后
此时浏览器访问谷歌浏览器
首先发起DNS请求 获取谷歌的IP
请求会来到路由器
路由器会将DNS请求劫持到clash中
clash收到浏览器的DNS请求
他也不知道谷歌的IP是多少
再看看自己的DNS配置是fakeip
fakeip并不需要给浏览器返回一个真实的IP
clash会心一笑
直接从配置的私有IP段中选择一个假的IP
生成DNS响应
返回给浏览器
并且记录了IP和域名的映射关系
浏览器拿到这个假的IP之后
向这个IP发起访问谷歌的dns请求
请求来到路由器的clash
clash查看映射表中IP对应的域名
用域名进行规则匹配
匹配到了第一条规则
于是将请求交给节点组1的香港节点处理
交给节点处理的还是谷歌的域名
由远程的节点服务器进行DNS解析
获取谷歌的正确IP
可以看到本地 并不需要进行DNS解析
也就不存在DNS泄露了
延迟也会降低
并且解决了多域名指向同一个IP的情况
因为返回的都是假的IP
clash可以控制每个IP只对应一个域名
如果此时再访问DNS泄露网站
首先会返回一个假IP给浏览器
浏览器在发起http请求
clash拿到映射的域名进行匹配
由于没有匹配到上面任何规则
会来到GEOIP这条没加no-resolve的IP规则
此时clash也不知道这个域名的IP
于是同时向上游的三个DNS服务器
和fallback中的DNS服务器发起DNS请求
clash得到IP后 发现归属地不是国内
于是会继续向下匹配
最终匹配MATCH走了代理
由于同时向多个DNS发起请求
泄露测试列表中会返回好几家DNS提供商
这种情况算不算泄露就仁者见仁了
如果你认为谷歌这种黑名单网站没漏
就不算泄露的话 也并没有什么不妥
fakeip这种侵入式的解决方案也并不完美
虽然能少一次DNS请求 降低延迟
但毕竟是假的IP
在某些情况下会出现不可预料的问题
比如访问百度获取到了假的IP
一段时间后 clash意外退出了
而电脑中缓存了百度的假IP
再次访问百度的时候就会访问假IP
此时就会无法访问
虽然clash将DNS响应中的缓存ttl值设置为一秒
但上期也说了
应用程序并不一定会遵守ttl值的规定
为了防止频繁发起DNS请求
可能会延长缓存时间
还有一些程序会开启DNS重绑保护
当DNS获取到一个私有IP
则认为出现了非法DNS劫持而被丢弃
典型的是windows系统使用fakeip
会出现联网图标显示没网的情况
解决方法是加入fake-ip-filter
放在里面的域名不会返回假的IP
会发起DNS请求 获取真实的IP地址
相当于回退到redir-host的模式
如果你对redir-host情有独钟
可以通过添加
"+.*"通配符
来回退所有域名
这样fakeip模式就会完全变成redir-host模式
不过并不建议大家这么做
另外由于UDP在有些场景下必须使用真实的IP
所以 目前clash处理udp流量的域名
即使是使用fakeip模式
也一定会发起DNS请求
比如基于UDP的QUIC协议
也就是浏览器用的HTTP3
启用了QUIC的浏览器访问
youtube这种支持QUIC的网站
就会发起DNS请求
导致DNS泄露
解决办法是禁用浏览器的QUIC功能
至于其他fakeip客户端对UDP
是不是同样的处理方式我不清楚
反正clash目前是这样子的
虽然有这些小问题 但是瑕不掩瑜
clash还是非常强大好用的
如果你平时使用并没有感觉到这些问题的存在
那么fakeip就是不错的选择
fakeip可能不是最优的解决方案
但是延迟最低这是毋庸置疑的
毕竟在透明代理的情况下
不发起DNS请求 只有fakeip能做到
但是也不能否认fakeip存在的问题
如果觉得fakeip不好用
可以使用v2ray系或者sing-box
通过真实的DNS请求配合流量嗅探
解决fakeip存在的问题
这又是另一个比较大的篇幅了 下期再说

最后修改:2023 年 03 月 11 日 04 : 34 PM