DNS-over-HTTPS (DoH)

Google 公共 DNS 在这两个端点上提供两种不同的 DoH API:

  • https://dns.google/dns-query - RFC 8484(GET 和 POST)
  • https://dns.google/Resolve?– JSON API (GET)

安全传输概览页面提供了有关同时使用这两个 API 的 curl 命令行示例,以及 TLS 和 DNS-TLS (DoT) 和 DoH 通用的其他功能的详细信息。

仅支持 IPv6 的 Google 公共 DNS64 服务也支持 DoH。

Google 公共 DNS 不支持不安全的 http: 网址进行 API 调用。

HTTP 方法

获取
使用 GET 方法可以缩短延迟时间,因为它可以更高效地缓存。 RFC 8484 GET 请求必须具有包含 Base64Url 编码的 DNS 消息的 ?dns= 查询参数。GET 方法是 JSON API 支持的唯一方法。
POST
POST 方法仅受 RFC 8484 API 支持,并且使用二进制 DNS 消息,并在请求正文和 DoH HTTP 响应中显示 Content-Type application/dns-message。
HEAD
HEAD 目前不受支持,并返回 400 Bad Request 错误

其他方法会返回 501 Not Implemented 错误。

HTTP 状态代码

Google 公共 DNS DoH 会返回以下 HTTP 状态代码:

成功

200 OK
HTTP 解析以及与 DNS 解析器的通信成功,响应正文内容是二进制或 JSON 编码的 DNS 响应,具体取决于查询端点、Accept 标头和 GET 参数。

重定向

301 已永久移动
客户端应通过 Location: 标头中提供的网址重试。如果原始查询是 POST 请求,则只有在新网址指定了 dns GET 参数时,客户端才应使用 GET 重试;否则客户端应通过 POST 重试。

将来可能会使用“已找到 302”、“307 临时重定向”或“308 永久重定向”等其他代码,并且 DoH 客户端应处理所有这 4 个代码。

包含永久 301 和 308 代码的响应应该无限期地缓存,并且在实际情况下,系统可能会提示用户使用新网址更新其原始配置。

应始终通过 POST 重试收到 307 或 308 响应的 POST 请求。

错误

错误响应将使用 HTML 或纯文本来说明正文中的 HTTP 状态。

400 请求错误
解析 GET 参数方面的问题或 DNS 请求消息无效。 对于错误的 GET 参数,HTTP 正文应说明错误。大多数无效的 DNS 消息都会收到一条带有 FORMERR 的 200 OK 消息;没有问号的问题区块消息、表示回复的二维码或包含二进制 DNS 解析错误的其他无意义标志组合都会返回 HTTP 错误。
413 载荷过大
RFC 8484 POST 请求正文超出了 512 字节的消息大小上限。
414 URI 过长
GET 查询标头过大,或 dns 参数的 Base64Url 编码的 DNS 消息超出了消息大小上限(512 字节)。
415 媒体类型不受支持
POST 正文没有 application/dns-message Content-Type 标头。
429 请求过多
客户在给定时间内发送的请求过多。客户端应停止发送请求,直到 Retry-After 标头中指定的时间(以秒为单位的相对时间)。
500 内部服务器错误
Google 公共 DNS 内部 DoH 错误。
501 未实施
仅实现了 GET 和 POST 方法,其他方法会遇到此错误。
502 Bad Gateway
DoH 服务无法连接到 Google 公共 DNS 解析器。

如果收到 502 响应,虽然使用备用 Google 公共 DNS 地址重试可能会有所帮助,但更有效的回退响应是尝试其他 DoH 服务,或改用 8.8.8.8 上的传统 UDP 或 TCP DNS。

DoH 的优势

HTTPS(而不仅仅是 TLS 加密)具有一些实际优势:

  • 全面支持和支持的 HTTPS API 简化了 Google 公共 DNS 本身和潜在客户的实现。
  • HTTPS 服务可为 Web 应用提供访问所有 DNS 记录类型的权限,从而避免对现有浏览器和操作系统 DNS API 施加限制,这些 API 通常仅支持主机到地址查找。
  • 实现基于 UDP 的 HTTPS 支持的客户端可以避免在使用 TCP 传输时可能出现的队头阻塞之类的问题。

卫生部的隐私权最佳做法

DoH 应用的开发者应考虑 RFC 8484 中概述的隐私权最佳做法(如下所述):

  • 限制 HTTP 标头的使用

    HTTP 标头会提供有关客户端的 DoH 实现的信息,并可用于对客户端进行去匿名化处理。Cookie、User-Agent 和 Accept-Language 等标头是最严重的违规内容,但即便是发送的标头集也可能会泄露。为了尽量降低这种风险,请仅发送 DoH 所需的 HTTP 标头:主机、内容类型(对于 POST),如有必要,请接受。任何开发或测试版本都应包含用户代理。

  • 使用 EDNS 填充选项

    按照 RFC 8467 中的指南,使用 EDNS 填充选项将 DoH 查询填充为几种常见的长度,以防止流量分析。还可以使用 HTTP/2 填充,但与 EDNS 填充不同,在来自 DoH 服务器的响应时不会引入填充。

  • RFC 8484 POST 方法仅适用于隐私敏感应用或浏览器模式

    对 DoH 查询使用 POST 会降低响应的可缓存性,并且可能增加 DNS 延迟时间,因此通常不建议这样做。但是,降低对隐私敏感应用的缓存可取的做法,或许可以防止 Web 应用尝试确定用户最近访问过哪些网域的时间计时攻击。

问题

如需报告 bug 或请求新功能,请打开 DoH 问题