2016.4.1日,Google正式启用了 DNS-Over-HTTPS 域名安全查询服务


传统的DNS请求和响应基本上还是基于明文的UDP(绝大多数使用UDP)或TCP传输,非常容易被劫持,尤其是最终用户和本地DNS(i.e运营商的recursive resolver)解析之间这段,相比从本地DNS解析到权威域名服务之间的安全性要差很多。虽然已经有很多技术手段尝试通过验证和加密来增强最终用户到本地DNS解析之间的安全性,但是没有一项是被广泛部署应用的。


要真正解决DNS的劫持问题要靠全面部署DNSSEC,但是统计显示全球DNS流量只有不到14%是启用了DNSSEC保护的。为了在这个过渡阶段提供更好的安全和隐私保护,Google在2016年4月1日(估计是故意选在这个时间点)推出了DNS Over HTTPS查询服务作为DNSSEC的有力补充,提供DNS请求的端到端验证。


Google的DNS Over HTTPS使用起来很简单,提供的是基于HTTP GET请求的查询方式,返回结果是JSON格式,可以很容易的被各种开发工具集成(Python/PHP/JavaScript 等)。


该服务支持以下参数:

name

唯一的一个必选string参数,就是你要查询的域名地址。长度在1-255,字符在[0-9a-zA-Z-.],不支持非ASCII字符。

type

可选string, 默认是1。RR type可以用[1, 65535]之间的数字表示,或者canonical string表示(A, AAAA等)。目前支持:A, AAAA,CNAME, MX,ANY,PTR

cd

布尔型,默认是false。CD(Checking Disabled)字段,设置为true时禁用DNSSEC validation。可用格式:cd, cd=0, cd=1, cd=false, cd=true

edns_client_subnet

可选string,默认为空。这个是edns0-client-subnet选项。格式是:IP/Mask。比如:1.2.3.4/24,2001:700:300::/48。


反向域名的解析,以查询taobao.com为例,反向解析可以查询:110.75.115.70或者70.115.75.110.in-addr.arpa

Google的Public DNS一般会发送经过粗略anonymize的网络掩码到权威域名服务器,从而能够得到根据客户IP确定的最优服务器IP。

Google的考虑非常周到,如果你出于隐私原因使用DNS Over HTTPS,不想让你的任何网络信息发送到权威域名服务器,可以设置edns_client_subnet=0.0.0.0/0。(真是良心服务啊!)


DNS响应格式为JSON


一个成功的响应

{
  "Status": 0, // DNS status. standard DNS response code 
  "TC": false, // Whether response is truncated
  "RD": true, // Always true for Google Public DNS
  "RA": true, // Always true to Google Public DNS
  "AD": false, // Whether all data in response has been cryptographically verified
  "CD": false, // Whether the client asked to disable DNSSEC
  "Question": [
    {
      "name": "taobao.com.", // FQDN with training dot.
      "type": 1              // Standard DNS RR type
    }
  ],
  "Answer": [
    {
      "name": "taobao.com.", // Must match name in question
      "type": 1,             // Standard DNS RR type 
      "TTL": 20,             // In seconds
      "data": "110.75.115.70"// IP address in text
    },
    {
      "name": "taobao.com.",
      "type": 1,
      "TTL": 20,
      "data": "140.205.220.96"
    }
  ],
  "Additional": [],
  "edns_client_subnet": "119.29.29.29/0" // IP address with network mask
}


如果请求失败则会返回诊断信息

{
  "Status": 2,
  "TC": false,
  "RD": true,
  "RA": true,
  "AD": false,
  "CD": false,
  "Question": [
    {
      "name": "dnssec-failed.org.",
      "type": 1
    }
  ],
  "Additional": [],
  "edns_client_subnet": "119.29.29.29/0",
  "Comment": "DNSSEC validation failure. Please check http://dnsviz.net/d/dnssec-failed.org/dnssec/."
}


虽然HTTP不存在截断的问题,但是权威服务器返回的响应可能会是截断的,所以需要TC字段来标记。另外,由于HTTP消息没有大小限制,所以这里的EDNS实现和普通的EDNS实现机制不同,在请求里是一个参数,在响应里是一个字段。


该服务尚处于Beta阶段,参数和返回的JSON格式可能会发生改变,但是以Google做事的风格,应该会提供向后兼容的平滑升级方法。

想要尝试的朋友请移步:https://dns.google.com。墙内的同学请自备×××,话说墙内访问谷歌的DNS都难,估计这个服务在国内又是不可用状态。


wKioL1cBYNzjK-1UAAB4BrwsH70580.png

命令行解析方法:

$ curl 'https://dns.google.com/resolve?name=www.126.com'
{"Status": 0,"TC": false,"RD": true,"RA": true,"AD": false,"CD": false,"Question":[ {"name": "www.126.com.","type": 1}],"Answer":[ {"name": "www.126.com.","type": 5,"TTL": 11215,"data": "mcache.mail.163.com."},{"name": "mcache.mail.163.com.","type": 5,"TTL": 16975,"data": "email.163.com.lxdns.com."},{"name": "email.163.com.lxdns.com.","type": 1,"TTL": 116,"data": "176.34.63.150"}]}


目前该功能还处于beta阶段

https://developers.google.com/speed/public-dns/docs/dns-over-https  Google Developer说明页面


有同学会说,国内不少公司都已经有类似的产品了:

  • 腾讯有httpdns,是作为一个能够更好的调度自家流量的工具,仅仅用来解析自家域名的,基于HTTP,不是作为一个公共服务提供给用户使用的。

  • dnspod提供DNS Over HTTP,叫做D+。功能简陋(基于HTTP,不支持EDNS)不说,想要加密功能居然还要收钱!要是国内dns.google.com访问的了,此DNS Over HTTPS一出,dnspod的D+立马就被拍死了。


Google的DNS Over HTTPS为用户免费提供:

  • 高可用的查询

  • 支持EDNS选项

  • 用户隐私保护

  • 支持DNSSEC Validation

  • 支持常见的Record Types

  • 可作为一个调试工具,返回查询失败原因


服务虽好,但是也有一点不足,就是不支持批量域名,希望将来可以支持。不过支持批量域名查询需要支持POST请求方式,因为URL的长度限制问题。


备注

前面提到全球DNS请求只有不到14%是启用了DNSSEC,是通过下面的统计网站查询的。

  • http://stats.labs.apnic.net

该网站不仅可以查询DNSSEC的流量,还能查询Google Public DNS的流量,目前Google Public DNS流量占全球DNS查询总量的12+%!


之前也有过一种方法实现DNS解析加密,参见我的另一篇文章:

http://professor.blog.51cto.com/996189/1601753  bind + DNSCrypt 实现安全加密转发,避免DNS污染