DNS 是网络请求的第一个环节,也是代理场景中最容易出问题的地方。Clash 内置了一套完整的 DNS 处理系统,理解它的工作原理,是排查「明明开了代理但某些网站还是慢」「DNS 泄露」「节点能 ping 通但连不上」等问题的根本。本文从原理层面对比 redir-host 与 fake-ip 两种模式,并给出生产可用的配置模板。
为什么代理场景中 DNS 如此特殊
普通上网时,浏览器发起请求的流程是:DNS 查询域名 → 获取真实 IP → 建立 TCP 连接。代理场景下,这个流程变得复杂:如果 DNS 查询走本地(不经代理),国内 DNS 服务器会对境外域名返回被污染的 IP 或错误结果;如果全部走代理服务器解析,又会带来额外延迟,而且国内域名走代理解析也毫无必要。
Clash 需要在「拿到真实 IP 之前」就判断这条流量应该走代理还是直连,这就是 DNS 模式设计的核心矛盾。
redir-host 模式:真实 IP 优先
redir-host 是 Clash 早期默认的 DNS 模式。其工作流程如下:
- 应用发起 DNS 查询(如解析
openai.com) - Clash 同时向多个 DNS 上游并发查询,取最快返回的结果
- 将真实 IP 返回给应用
- 应用用该 IP 建立连接,Clash 此时再根据 IP-CIDR 或 GEOIP 规则判断路由
redir-host 的缺点是:规则匹配依赖真实 IP,而获取 IP 的过程本身就可能受到 DNS 污染,导致规则误判。此外,每次连接都需要先完成 DNS 解析,增加了首次连接延迟。
fake-ip 模式:假 IP 先行
fake-ip 是 Mihomo(原 Clash.Meta)推荐的现代方案,也是 TUN 模式的最佳拍档。其核心思路是:不等待真实 IP,立刻返回一个虚假的私有 IP,将真实的 DNS 解析推迟到代理侧完成。
- 应用发起 DNS 查询
- Clash 立刻从
fake-ip-range(默认198.18.0.0/15)中分配一个假 IP 返回给应用,同时在内部记录「假 IP ↔ 域名」的映射 - 应用用假 IP 建立连接请求
- Clash 拦截连接,通过映射表还原出真实域名,再按域名规则判断走代理或直连
- 若走代理,由代理服务器在出口端完成 DNS 解析;若直连,Clash 在本地发起真实 DNS 查询后直接转发
fake-ip-filter:哪些域名不能用假 IP
并非所有请求都适合 fake-ip。部分应用(如微信、QQ、国内游戏客户端)依赖真实 IP 进行服务发现或 P2P 连接,给它们返回假 IP 会导致连接失败。fake-ip-filter 字段用于将这些域名排除在 fake-ip 之外,对它们仍使用真实 IP。
dns: enable: true listen: 0.0.0.0:53 enhanced-mode: fake-ip fake-ip-range: 198.18.0.1/16 # 以下域名排除在 fake-ip 之外,使用真实 IP fake-ip-filter: - '*.lan' - '*.local' - localhost.ptlogin2.qq.com - +.stun.*.* - +.stun.*.*.* nameserver: - 223.5.5.5 # 阿里 DNS,用于直连域名 - 119.29.29.29 # 腾讯 DNS fallback: - tls://8.8.8.8:853 # Google DNS over TLS,用于代理域名 - tls://1.1.1.1:853 # Cloudflare DoT fallback-filter: geoip: true geoip-code: CN ipcidr: - 240.0.0.0/4
nameserver 与 fallback 的分工
nameserver 是主要 DNS 服务器,负责解析所有域名的初次查询。fallback 是备用服务器,当 fallback-filter 条件满足时(如 IP 归属为非中国),Clash 会用 fallback 结果替换 nameserver 的结果。这样的分组设计保证了:国内域名用国内 DNS(快速准确),境外域名用加密 DNS(防止污染)。
fallback,所有 DNS 查询都走 nameserver。境外域名可能被国内 DNS 污染,导致 GEOIP 规则误判,部分网站即使走了代理也无法访问。如何验证 DNS 是否泄露
访问 dnsleaktest.com,点击「Extended Test」。若测试结果中出现中国大陆的 DNS 服务器,说明存在 DNS 泄露。正确配置 fake-ip + fallback 后,结果应只显示代理服务器所在地区的 DNS 服务器(或 Cloudflare/Google)。
另一个验证方法是在 Clash 日志中观察 DNS 查询记录。将 log-level: debug 后重启,连接某个境外网站时日志中应显示该域名的查询走了 fallback DNS。