使用 Clash DNS 分流解析与加密 DNS 防止 DNS 劫持

众所周知,现在各地的民用宽带运营商都开始将部分网站流量劫持到国家反诈中心的拦截页。目前各地的实现方式都是 DNS 劫持,包括但不限于抢答未加密 DNS。而要想预防这种情况,最好的方式当然是使用加密 DNS 技术,如 DoH, DoT 和方兴未艾的 DoQ. 但就存在两个问题:服务可用性,以及操作系统兼容性。中国对于海外的加密 DNS 服务一律阻断,而国内的服务总是存在一定的污染,且不同的操作系统对加密 DNS 服务的兼容性也不尽相同。网上也有使用 Dnsmasq 等服务自建本地 DNS,根据域名分流 DNS 解析的方法,但对我而言,我并没有能够不间断运转的电脑,这种方式显然不适合我。后来我在翻 Clash 项目的 GitHub Wiki 时发现,Clash 本身就提供和 Dnsmasq 类似的功能,用于分流解析。配置的过程还是一如既往地踩了很多坑,所以还是写一篇文章记录一下。

首先,打开你的 Clash 配置文件(如果你使用 Clash for Windows 或 Clash for Android, 可以使用软件自带的“覆写/Mixin”功能),添加以下段落:

dns:
  enable: true
  listen: 0.0.0.0:53

这一段的意思是启用 Clash 的 DNS 服务并让其在 53 端口(这是绝大多数操作系统将 DNS 解析报文发送到的端口)监听来自任意网络界面的 DNS 请求。如果你的设备并不需要向其他设备提供解析服务,或你的设备常常需要接入不安全的网络(如手机,笔记本电脑),应当将第三行的 0.0.0.0:53 改为 127.0.0.1:53 让 Clash 仅监听本机的 DNS 解析报文。

(Clash 默认会同时监听 IPv4 和 IPv6 界面,如果你不需要后者,可以添加一行 ipv6: false

由于连接到加密 DNS 服务时,需要解析服务器本身的域名,因此需要指定一些相对干净的国内 明文 DNS 服务器地址。继续添加以下部分(注意缩进):

#--omitted--
default-nameserver:
   - 119.29.29.29
   - 223.5.5.5

当收到 DNS 解析请求时,Clash 会使用以上 DNS 服务器解析加密 DNS 服务器地址并建立连接。

接下来,指定解析国内域名时使用的加密 DNS 服务器地址:

#--omitted--
nameserver:
   - https://doh.pub/dns-query
   - https://dns.alidns.com/dns-query

Clash 支持 DoH(https://domain.tld/dns-query 形式) 和 DoT(tls://domain.tld 形式)两种加密 DNS 协议,不支持 DoQ.(当然也支持在此指定备用的明文 DNS)

然后,指定解析国外域名时使用的加密 DNS 服务器地址,并设置分流规则:

#--omitted--
fallback:
   - https://1.1.1.1/dns-query
   - https://dns.google/dns-query
fallback-filter:
   geoip: true
   geoip-code: CN
   ipcidr:
     - 240.0.0.0/4

“fallback” 字段指定的 DNS 服务器将被用于解析非国外域名,而 “fallback-filter” 字段则实现我们想要的分流规则——当请求解析的域名在 GeoIP 数据库内的国家代码不是 CN 时,或是域名在前文设置的 DNS 服务器内的解析结果位于 240.0.0.0/4 这一 IP 段内时(被屏蔽的域名解析常常会被污染到这一段),使用 “fallback” 字段指定的 DNS 服务器解析域名。

最后,修改系统 DNS 服务器为 127.0.0.1 即可。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,重用本文章时请遵守该协议。