传统的 DNS 是明文传输的。那么我们在使用代理时,中间人是否可能看到我们的 DNS 请求从而分析出我们在访问什么网站呢?这个问题从最开始就被考虑过了。例如较为古老的代理客户端通过将 DNS 请求通过代理传输就可以轻松解决。需要注意的是,当我们在无代理的环境下下载配置文件时,中间人是可以知道我们在询问哪个网址的。所以可以通过确保在代理环境下下载或者更新配置文件来避免风险。SagerNet 和 CFW 等常见工具都提供了这个选项。
现代化的 Clash 一般不会去直接转发 DNS 请求,而是使用 Fake IP 的思路。一个重要的原因在于,Clash 支持按照域名的分流规则,如果我们先经过 DNS 而不是先经过 Clash,那么 Clash 可能就不知道在访问哪个域名,进而无法保证分流正确了。Fake IP 的原理是修改系统 DNS,让 DNS 请求被路由到伪装成 DNS 服务器的 Clash,然后 Clash 并不返回域名对应的 DNS 记录,而是返回一个被它监听的假 IP 地址。当浏览器向该地址发送请求时,Clash 截获请求,将其转发到代理服务器。
NOTE
注意运行 Clash 前后 DNS 响应的 IP。
但是 Clash 为什么不止步于劫持 DNS 请求,而是非要返回 Fake IP 呢?这是因为,同一个 IP 地址可能部署了多个网站,这些网站通过 HOST 字段区分用户想访问谁。假如 Clash 在通过代理得到真实的 DNS 响应后就直接把真实的 IP 返回给浏览器,那么随后浏览器发送的请求中,Clash 就只能看到 IP 了,而并不知道实际的域名是什么。而如果 Clash 在处理 DNS 请求时建立一个域名到 Fake IP 的映射关系,它就可以根据浏览器是向哪个 IP 发起请求来区分不同的域名。
需要注意的是,就算代理客户端可以避免 DNS 泄漏,也最好使用加密的 DNS 请求,因为否则代理服务器还是能看到你访问的网站,进而甚至记录在日志中。这也就是一些基于域名的审计规则的原理。如果使用了 DoH 等方法,就基本可以不被确定在访问什么了。但这也不是绝对的,比如通过 IP 地址有时也可以粗略至精确地得知访问的网站。抑或是本机装了一些恶意软件,窃取浏览数据。