一、什么是 DNS Link to heading

DNS 全称 Domain Name System, 简而言之就是一个域名映射系统, 那么为什么需要 “映射” 呢?

因为对于常规程序比如浏览器来说, 浏览器访问 bing.com 时, 它只知道如何与一个 “IP 地址” 建立链接, 但并不清楚 bing.com 对应的 IP 地址是多少. 此时浏览器就会先向 DNS 查询一下:

  • 1、浏览器: “DNS 你快告诉我 bing.com 对应的 IP 地址是多少!”
  • 2、DNS: “bing.com 对应的 IP 地址是 204.79.197.200.”
  • 3、浏览器: “收到! 准备向 204.79.197.200 发起链接请求…”

二、fake DNS 是什么 Link to heading

既然叫 fake DNS 了, 很明显这是一个 “假的 DNS”, 为什么 Clash 需要一个假的 DNS 呢?

因为 Clash 需要通过内置的规则来处理你的流量, 比如你有以下规则:

rules:
  - DOMAIN,steamcommunity.com,GAME_PROXY

这个规则中定义了 访问 steamcommunity.com 时需要使用 GAME_PROXY 这个代理服务器, 那么这个时候问题就来了:

2.1、不使用 fake DNS 会怎样 Link to heading

  • 1、你的 DNS 请求发给 Clash, Clash 直接进行解析(查上游 DNS, 比如 114), 那么很可能你这个域名是一个被污染的域名
  • 2、Clash 把一个被污染的结果(steamcommunity.com --> 127.0.0.1)返回给你
  • 3、你的浏览器开始与被污染的结果(127.0.0.1)建立连接
  • 4、你的电脑认为这个 IP 就是自己, 不需要路由到 Clash 网关
  • 5、网站打不开, 你认为 “垃圾 Clash 毁我青春😡”

2.2、使用 fake DNS 的好处 Link to heading

有了 fake DNS 之后, 你向 Clash 发送任何 DNS 查询时:

  • 1、Clash 先在本地记录一下这个域名(steamcommunity.com)
  • 2、Clash 从 fake-ip-range 这个地址池中随机拿出一个 “假 IP(198.18.0.5)” 对应到这个域名, 同样也会记录好
  • 3、Clash 把这个假 DNS 结果(steamcommunity.com --> 198.18.0.5)返回给你
  • 4、你的浏览器开始与 198.18.0.5 建立连接
  • 5、你的电脑认为 198.18.0.5 不是自己, 需要把流量发送到网关(Clash) 处理
  • 6、Clash 收到了向 198.18.0.5 建立连接的请求
  • 7、Clash 从本地记录中知道 198.18.0.5 对应的是 steamcommunity.com
  • 8、Clash 通过查询规则得知需要把流量发送到 GAME_PROXY 服务器做处理
  • 9、你正常打开了网站, 并且说了一句 “Clash 真香 YYDS😏”

三、fake DNS 应该怎么使用 Link to heading

3.1、推荐配置 Link to heading

目前推荐使用以下配置开启 fake DNS:

dns:
  enable: true
  listen: 0.0.0.0:1053
  ipv6: false
  default-nameserver:
    - 223.5.5.5
    - 119.29.29.29
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  nameserver:
    - 223.5.5.5
    - 119.29.29.29
tun:
  enable: true
  stack: system
  dns-hijack:
    - any:53

3.2、如何提供服务 Link to heading

目前 Clash fake DNS 默认在两种模式下提供服务:

  • 1、流经 Clash 机器的所有 UDP 目标端口为 53 的流量自动被 fake DNS 接管(auto-route 或 ebpf)
  • 2、直接向 fake DNS 监听端口发起的 DNS 查询会被 fake DNS 接管

3.3、正确姿势 Link to heading

从上面的介绍中可以看到, Clash 分流的成功与否与 fake DNS 至关重要, 如果 fake DNS 配置不正确可能导致无法正确分流.

可能很多人会好奇为什么样例配置中使用 0.0.0.0:1053 这个监听地址, 而不使用 0.0.0.0:53? 这其实和 Clash 机制有关:

官方文档: https://dreamacro.github.io/clash/premium/tun-device.html#technical-limitations

英文原文: DNS hijacking might result in a failure, if the system DNS is at a private IP address (since auto-route does not capture private network traffic).

Google 翻译: 如果系统 DNS 位于专用 IP 地址 (因为自动路由不会捕获专用网络流量), 则 DNS 劫持可能会导致失败。

很明显作者已经说明了, 如果你的被代理机器设置的 DNS 为内网地址, auto-route 是不工作的.

这时候你把 Clash fake DNS 设置为 0.0.0.0:53, 那么你下一步要干什么? 是不是理所应当的把被代理机器的网关和 DNS 都指向了 Clash 这台机器?

问题在于 Clash 这台机器 99.99% 也是在内网. 这就导致了 auto-route 不工作, 那么会不会还有其他问题只有 Clash 作者知道; 所以我是强烈不建议这么干的.

还有一个重要问题是很多系统服务例如 systemd-resloved 也会占用 53 端口, 他们有一些特殊行为可能与系统耦合, 不了解的情况下强行占用 53 并不是一个明智的选择.

四、总结一下 Link to heading

最后这里总结一下:

  • 1、Clash 不要监听 :53:5353, 尽量使用 :1053 之类的非标准端口, 剩下的交给 Clash 的 auto-route 或者 ebpf 去劫持
  • 2、被代理机器设置一个公网的 DNS 比如 223.5.5.5, 防止 Clash 认为是内网地址跳过劫持(瞎写一个 1.2.3.4 都行)
  • 3、Clash 本机如果有 systemd-resloved 推荐参考 flatcar.butane.yaml 调整一下配置, 因为 systemd-resloved 默认 raw socket 发送 DNS 不走路由, 可能造成 Clash 本机的流量劫持失败