Intro
DNS劫持、污染在国内相当常见。除了用来屏蔽一些国外的网站,最常见的是劫持百度统计的域名。因为国内大多数网站都使用百度统计,而使用百度统计需要从百度的网站加载一段JavaScript。部分运营商通过DNS劫持,重定向该请求到自己的服务器,并返回一段包含有广告代码的JavaScript,用于弹窗、推广等广告活动。印象最深的是前几年某银行的行长在使用自家的App时弹出了一段红包广告,因此暴怒。而我个人则是因为有次被劫持了live.com,而心有余悸。
所以我一直使用USTC的DNS进行域名解析,虽然无法防止记录和中间人工具,但大多数常用网站的解析结果还算权威。然而,最近半年发现USTC的DNS也被污染了:
C:\Users λ Resolve-DnsName -Server 202.141.162.123 www.google.com Name Type TTL Section IPAddress ---- ---- --- ------- --------- www.google.com A 157 Answer 74.86.228.110 C:\Users λ Resolve-DnsName -Server 202.141.178.13 www.google.com Name Type TTL Section IPAddress ---- ---- --- ------- --------- www.google.com A 154 Answer 74.86.228.110
于是转向DNSCrypt,DNSCrypt是一种加密DNS请求的网络协议,可以有效的阻止重放攻击、观察攻击、时序攻击、中间人攻击和解析伪造攻击。DNSCrypt相关的技术包括:
- DNS over HTTPS:使用HTTPS进行DNS查询,利用HTTPS进行DNS查询的加密。
- DNS over TLS:使用TLS进行DNS查询。
- DNSSEC:依靠数字签名保证DNS应答报文的真实性和完整性。
以下是这半年多使用DNSCrypt的一些经验。
DoH Resolver选择
根据使用经验和个人需求,选择DNS服务器主要有以下指标:
- 解析准确性
- 响应时间
- ECS(EDNS Client Subnet)支持情况
ECS是Google提交的一份DNS扩展协议,CDN的DNS如果支持该协议,就可以根据用户的真实IP地址,返回最佳的CDN服务器地址。 ECS对于国内的用户来说还是比较重要的,比如dl.google.com、fonts.googleapis.com等在国内由服务器,如果解析到国外访问网站的速度会比较慢。
为此,我写了个简单的脚本,解析dnscrypt-proxy中public-resolvers的DoH查询连接(目前只做了IPv4),并使用dl.google.com进行测试,检测响应时间和ECS的支持情况。效果如下:
可以看到,在国内使用DoH的话,GeekDNS、Rubyfish、dns.sb是最佳的选择。其中,GeekDNS的国内服务器最多,不同地区的解析速度都可以得到保证。Rubyfish也是个不错的选择,只是ECS的支持不是特别稳定。此外,还可以选择dns.sb,虽然服务器在国外,但速度尚可,而且ECS支持不错。
除了GeekDNS和Rubyfish外,目前已知的另外一家提供DoH服务的是USTC Neat DNS,查询接口为: https://neatdns.ustclug.org/resolve。通过测试,存在被污染的情况:
$ http https://neatdns.ustclug.org/resolve?name=www.google.com HTTP/1.1 200 OK Cache-Control: private, max-age=220 Connection: keep-alive Content-Length: 235 Content-Type: application/json; charset=UTF-8 Date: Sun, 09 Jun 2019 06:14:29 GMT Expires: Sun, 09 Jun 2019 06:18:09 GMT Last-Modified: Sun, 09 Jun 2019 06:14:29 GMT Server: nginx X-Powered-By: DNS-over-HTTPS/1.3.6 (+https://github.com/m13253/dns-over-https) { "AD": false, "Answer": [ { "Expires": "Sun, 09 Jun 2019 06:18:09 UTC", "TTL": 220, "data": "69.63.186.30", "name": "www.google.com.", "type": 1 } ], "CD": false, "Question": [ { "name": "www.google.com.", "type": 1 } ], "RA": true, "RD": true, "Status": 0, "TC": false }
客户端支持情况
Windows
目前Windows上体验最佳的DNSCrypt客户端当属Simple DNSCrypt。Simple DNSCrypt是一个dnscrypt-proxy的GUI。
Android
Android Pie(9.0)之后,可以通过设置页面开启DNSCrypt,不过仅支持DoT:
iOS
目前iOS只能通过VPN软件或越狱插件解决。
Firefox
较新版本的Firefox中,可以直接在网络连接设置里开启DoH,并能够自行选择DoH Resolver:
开启后,可以通过about:networking#dns查看解析情况。详细配置参考这里。
一些问题
使用过程中,DNSCrypt会遇到如下问题:
网络连接认证
部分公共网络(机场、酒店、咖啡厅)和公司网络在连接的时候需要进行认证,少部分认证方案通过DNS劫持实现,通过劫持HTTP的请求,重定向到认证页面。因此,在这种情况下,DNSCrypt会导致页面无法弹出,需要临时关闭DNSCrypt完成认证。目前还没发现更好的解决方案。
更新记录
- 2019.6.9:增加USTC Resolve地址
DoHVerifier有使用说明吗? 我装的是PYTHON 3.7版本,下载了GeoLite2-Country.mmdb和public-resolvers.md,py doh_verifier.py,没有任何输出显示。
完整可参考.travis.yml