Clash DNS的运行特点
本篇文章着重记录Clash.meta/mihomo的DNS运行特点(如DNS缓存状况、fallback机制等),作为备忘录使用,后面提到的Clash均代表Clash.meta/mihomo。
乐观缓存
- Clash的DNS拥有乐观缓存机制,测试时Clash提供了一个过期了24个小时的记录,其TTL为1(1秒),并且在提供过期记录之后触发了DNS解析,在下次解析时Clash返回了新获取的记录。
- 根据配置文件,Clash应该没有持久化保存DNS缓存的机制,即在Clash重启或关闭后缓存就会丢失。
- 乐观缓存目前是无法关闭的。
缓存算法 cache-algorithm
从名字可以看出cache-algorithm
这个字段作用于DNS缓存中,不知道会不会和乐观缓存有关系。其可选值是lru
和arc
,默认是lru
。
lru
应该是指Least Recently Used(最近最少使用)作用大概是:在有限的缓存空间内尽可能的储存常用条目。arc
则是Adaptive Replacement Cache(自适应替换缓存)arc结合了lrc以及另一种lfu算法(Least Frequently Used,最近最不常用),arc能根据当前使用情况动态调整缓存空间大小,在判断常用条目上更智能和准确。
如果没出现什么问题个人建议使用arc算法。
Fallback
DNS的fallback组和nameserver组通常是并发解析的,即同时使用这两个组解析域名,这是为了防止DNS污染,这也是使用Clash时有DNS泄露的原因,并不是BUG或漏洞,这是正常现象。
1 | dns: |
fallback-filter
- 两组解析时,根据
nameserver
返回的结果以及fallback-filter
的过滤规则决定选择哪一个组的结果。
比如:在geoip-code
为CN时,检查nameserver
结果的IP地址是否属于CN,如果不属于则采用fallback
组的结果。
同理nameserver
的结果如果在ipcidr
字段中也会采用fallback
组的结果。 - 与
ipcidr
和geoip-code
不同,domain
和geosite
不会等到两个组都解析出结果时才起作用,而是直接交给fallback
组解析,完全不使用nameserver
。 - 要注意这里的
geosite
字段已经被弃用,弃用的警告会在Clash启动时输出到日志中并且建议用户改用nameserver-policy
。
flowchart LR
domain("域名")-->a{它的IP属于CN吗}
a-->|属于|c("采用nameserver组的结果")
a-->|不属于|b("采用fallback组的结果")
关于DNS增强模式(enhanced-mode)
文档中只提到了fake-ip与redir-host两种模式,但是在源码中除了这两种模式以外还有hosts以及normal,具体作用还不是很清楚。相关代码
Clash记录网络连接时会有一个dnsMode
字段,它表明了此连接使用的DNS模式。根据OpenClash的issue#1819来看,normal模式则可能代表着使用了远程解析?而hosts模式可能在启用并匹配到hosts时才会显示。在启用了fake-ip时大部分连接为fake-ip,而在redir-host下大部分是normal,只有少部分是redir-host。另外即使用fake-ip-filter
让某些连接不使用fake-ip后在连接的dnsMode中仍然是fake-ip,也许是一个小bug?
建议目前使用时只在fake-ip与redir-host之间二选一,毕竟文档中没有提到其他模式。
Fake-ip
- 使用Fake-ip响应DNS解析时Clash不会在日志中显示解析记录。
- 有些互联网连接不支持使用Fake-ip,所以需要配置fake-ip-filter将这些连接切换为普通的真ip模式(redir-host)。
fake-ip-filter和fake-ip-filter-mode
fake-ip-filter
用于指定哪些域名需要使用fake-ip,它根据fake-ip-filter-mode
的值来决定使用白名单还是黑名单模式,默认是黑名单模式。
- 白名单模式下(whitelist),在
fake-ip-filter
中的域名使用fake-ip。 - 黑名单模式下(blacklist),在
fake-ip-filter
中的域名使用redir-host。
1 | dns: |
Clash DNS解析顺序
flowchart TB
subgraph "Clash DNS"
a("fake-ip")-->b("缓存")
b-->c("nameserver-policy")
c-->d("nameserver+fallback")
end
client("客户端")-->a
如图
- 如果启用了fake-ip,则根据
fake-ip-filter
判断是否需要使用fake-ip
- 是,返回fake-ip给客户端,结束后续步骤
- 否,继续下一步……
- 检查缓存中是否有当前域名的结果
- 如果有就直接返回给客户端,结束后续步骤。
- 如果没有记录或者已经过期(过期的记录先返回给客户端),继续下一步……
- 匹配
nameserver-policy
- 如果匹配到了当前的域名就按对应的DNS服务器解析,取得结果后返回给客户端并将结果写入缓存,结束后续步骤。
- 如果未能匹配,继续下一步……
- 通过
nameserver
和fallback
两组并发解析,并通过fallback-filter
过滤结果,取得结果后返回给客户端并将结果写入缓存,结束。
在连接页面中所有的连接目标都是IP,而不是域名
Clash通过DNS解析记录推测用户访问的网站。如果DNS配置有误,客户端的DNS请求绕过了Clash的DNS就会导致这个问题。可以通过开启域名嗅探解决。或者是尝试解决ClashDNS被绕过的问题(比如有其他的软件/插件开启了DNS劫持、重定向等功能)
1 | sniffer: |