Chrome 浏览器中的远程 DNS 解析

由于伟大的X火长城的存在,在境内进行 DNS 解析请求返回的报文不一定是靠谱的,有必要使用远程的服务器进行DNS 解析来缓解这个问题。根据 Google 的文档如果设置了 socks5 代理,URL 中的 hostname 将由代理服务器解析。

1
2
The --proxy-server="socks5://myproxy:8080" flag tells Chrome to send all http:// and https:// URL requests through the SOCKS proxy server "myproxy:8080",
using version 5 of the SOCKS protocol. The hostname for these URLs will be resolved by the proxy server, and not locally by Chrome.

但是由于 chrome 浏览器的 DNS prefetching 特性,即使设置了 socks5 代理 DNS prefetching 特性也会使用本地网络进行 DNS 解析。

1
2
3
4
The --proxy-server flag applies to URL loads only. 
There are other components of Chrome which may issue DNS resolves directly and hence bypass this proxy server.
The most notable such component is the "DNS prefetcher".
Hence if DNS prefetching is not disabled in Chrome then you will still see local DNS requests being issued by Chrome despite having specified a SOCKS v5 proxy server.

下面是禁用 DNS prefetching 的方法,新版本的 chrome 已经取消了直接针对 DNS prefetching 设置的选项,有一个预加载网页的选项,需要把这个选项关闭,具体设置方法为:

1
设置 -> 隐私设置和安全性 -> Cookie 及其他网站数据 -> 预加载网页,以便实现更快速的浏览和搜索

禁用 DNS prefetching 的方案是脆弱的,Chrome 可能在其他的地方使用 raw dns requsts ( Chrome 发送 DNS 请求报文), 绕过代理服务器直接使用本地网络进行 DNS 解析。

1
2
Disabling DNS prefetching would solve this problem, 
however it is a fragile solution since once needs to be aware of all the areas in Chrome which issue raw DNS requests.

所以最终的解决方案是使用 Google 文档中的命令行参数 --host-resolver-rules= ,经过测试可以使用下面的命令行来解决 DNS 远程解析

1
google-chrome --proxy-server="socks5://127.0.0.1:9999" --host-resolver-rules="MAP * 0.0.0.0, EXClUDE 127.0.0.1"

–host-resolver-rules 将阻止Chrome 使用本地网络发起 DNS 请求,具体的方式是将 DNS 请求转向一个不存在的地址,注意需要排除 sock5 代理的地址。

在实际使用过程中发现,如果不指定 –host-resolver-rules 命令行参数,有少量 DNS 请求会使用本地网络,比如 safebrowsing.googleapis.com

参考资料

https://www.chromium.org/developers/design-documents/network-stack/socks-proxy/


Chrome 浏览器中的远程 DNS 解析
https://usmacd.com/cn/dns_via_socks_proxy_in_chrome/
作者
henices
发布于
2023年2月23日
许可协议