使用DNSCrypt以及选择最佳的DoH Resolver

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是Google提交的一份DNS扩展协议,CDN的DNS如果支持该协议,就可以根据用户的真实IP地址,返回最佳的CDN服务器地址。 ECS对于国内的用户来说还是比较重要的,比如dl.google.comfonts.googleapis.com等在国内由服务器,如果解析到国外访问网站的速度会比较慢。

为此,我写了个简单的脚本,解析dnscrypt-proxy中public-resolvers的DoH查询连接(目前只做了IPv4),并使用dl.google.com进行测试,检测响应时间和ECS的支持情况。效果如下:

DoHVerifier测试结果

可以看到,在国内使用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。

Simple DNSCrypt

Android

Android Pie(9.0)之后,可以通过设置页面开启DNSCrypt,不过仅支持DoT:

Xiaomi 5s with LineageOS

iOS

目前iOS只能通过VPN软件或越狱插件解决。

Firefox

较新版本的Firefox中,可以直接在网络连接设置里开启DoH,并能够自行选择DoH Resolver:

开启后,可以通过about:networking#dns查看解析情况。详细配置参考这里

一些问题

使用过程中,DNSCrypt会遇到如下问题:

网络连接认证

部分公共网络(机场、酒店、咖啡厅)和公司网络在连接的时候需要进行认证,少部分认证方案通过DNS劫持实现,通过劫持HTTP的请求,重定向到认证页面。因此,在这种情况下,DNSCrypt会导致页面无法弹出,需要临时关闭DNSCrypt完成认证。目前还没发现更好的解决方案。

更新记录

  • 2019.6.9:增加USTC Resolve地址

使用DNSCrypt以及选择最佳的DoH Resolver》有2个想法

  1. baodl

    DoHVerifier有使用说明吗? 我装的是PYTHON 3.7版本,下载了GeoLite2-Country.mmdb和public-resolvers.md,py doh_verifier.py,没有任何输出显示。

    回复

thecjw进行回复取消回复