排错和解决 Clash 上网需要等待 5 秒的问题: DNS

之前猫猫找我说用我的代理很卡,体验贼糟糕,每个请求都得五秒钟才能得到相应,并且在不同的网络环境和设备上都出现过这种问题,但我这里从来没出现,而且节点延迟测试很正常。百思不得其解。

后来跑他家试了一下,诶,还真是这样,而且也并不是 Tun 的问题。这体验差到我都受不了。 

于是老样子,本地编辑配置文件 log-level: debug + 手动运行内核看日志。
看了半天有眉目了,是在 DNS 请求的时候发生的问题。我配置的 fallback 内的 DNS 服务器总是返回了结果,然后超时时间大概就是五秒钟。 

那是怎么解决的呢,让我慢慢说: 

Clash 是怎么处理 DNS 的呢?也挺简单的。 

就是向着配置文件里配置的 nameserverfallback 条目中的 DNS 服务器进行并发查询,然后再判断返回的 IP。如果返回的 IP 是国外的话,就使用 failback 条目中的解析地址。
也可以简单的理解为 nameserver 配置国内 DNS 或是国内网站使用的 DNS, fallback 来配置国外网站的 DNS。 

但这时候就有一个问题了,你说 fallback 得配置国外的 DNS,但如各位所知,向国外的 DNS 服务器查询 53 或者 TCP 53 都早已经被污染或是干扰了,那么怎么办呢?我之前是配置了使用 DoT(853) 或者 DoH(443) 来解决这个问题。 

那为什么问题又出现了呢?

原因是前一阵墙对 Google 和 CF 的 DoH/DoT 查询进行了干扰,而 Clash 是一直都没有办法经过代理查询 DNS 的,这个时候就出现了一个问题。会导致访问网站的时候 Clash 一直挂起你的连接,来等待 fallback 部分配置的 DNS 服务器超时(应该是 5s 左右)。 
总而言之就是 Clash DNS 配置没法走代理,但现在直连又被干了。

那么,是怎么解决的呢? 
Clash-Meta 这个内核我也在用了,他们的思路很好,直接支持了 DNS 经过代理查询,只需要稍微修改配置文件就可以了。

但是,官方内核呢?嗯....得用有点 Hack 的做法
先用 Clash 内核的 Tunnel 功能,将国外 DNS 的 443/853 端口在本地(127.0.0.1)开一个端口转发,然后在 Clash 的 DNS 配置里去将 fallback 的部分修改为 127.0.0.1 + 本地的映射端口。 

看上去解决了,一开还是不行,为什么呢? 
因为使用 DoH 也好,DoT 也好,都得校验证书,而 fallback 那边的配置是 127.0.0.1, 显然是没法被校验通过的。 

那之前说的有点 Hack 的做法就得上场了,Clash 一开始就支持 hosts 功能,在 hosts 里配置 mozilla.cloudflare-dns.com 和 dns.google = 127.0.0.1 ,也就是你所使用的 DNS 服务器的地址,都将其解析到 127.0.0.1, 然后在 fallback 里直接配域名,这样的话问题就算就解决了。

好!修改,生成,推送!

评论

此博客中的热门博文

获取 ASN 下的所有 IP 段