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 over TLS (DoT) 和 DoH 共用的其他功能。

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

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

HTTP 方法

GET
使用 GET 方法可以减少延迟,因为它可以被更有效地缓存。RFC 8484 GET 请求必须具有 ?dns= 查询参数,该参数带有采用 Base64Url 编码的 DNS 消息。GET 方法是 JSON API 支持的唯一方法。
POST
只有 RFC 8484 API 支持 POST 方法,该方法使用包含 Content-Type application/dns-message(在请求正文和 DoH HTTP 响应中)的二进制 DNS 消息。
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 Found、307 临时重定向或 308 永久重定向,DoH 客户端应处理所有这四个代码。

包含永久 301 和 308 代码的响应应无限期缓存,如果可行,系统可能会提示用户使用新网址更新其原始配置。

收到 307 或 308 响应的 POST 请求应始终使用 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 请求过多
客户端在给定时间内发送的请求过多。客户端应停止发送请求,直到 重试后 标头中指定的时间(以秒为单位的相对时间)。
500 内部服务器错误
Google 公共 DNS 内部 DoH 错误。
501 未实施
仅实现 GET 和 POST 方法,其他方法会收到此错误。
502 Bad Gateway
DoH 服务无法联系 Google 公共 DNS 解析器。

对于 502 响应,虽然通过备用 Google 公共 DNS 地址重试可能会有所帮助,但更有效的后备响应是尝试其他 DoH 服务,或者切换到传统的 UDP 或 TCP DNS 8.8.8.8。

DoH 的优势

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

  • HTTPS API 广泛可用且受到良好支持,可简化 Google 公共 DNS 本身和潜在客户的实现过程。
  • HTTPS 服务可让 Web 应用访问所有 DNS 记录类型,避免了现有浏览器和操作系统 DNS API(通常仅支持主机到地址查找)的限制。
  • 实现基于 QUIC UDP 的 HTTPS 支持的客户端可以避免使用 TCP 传输时可能发生的队头阻塞等问题。

DoH 的隐私保护最佳实践

DoH 应用的开发者应考虑 RFC 8484 中概述并扩展的隐私权最佳实践:

  • 限制 HTTP 标头的使用

    HTTP 标头会显示有关客户端 DoH 实现的信息,并可用于对客户端进行去匿名化处理。Cookie、User-Agent 和 Accept-Language 等标头是最严重的违规因素,但即使是发送的这组标头也会暴露。为了最大限度地降低这种风险,请仅发送 DoH 所需的 HTTP 标头:Host、Content-Type(适用于 POST),必要时还应发送 Accept。任何开发或测试版本中都应包含用户代理。

  • 使用 EDNS 填充选项

    请遵循 RFC 8467 中的指南,了解如何使用 EDNS 填充选项将 DoH 查询填充为一些常见长度的填充,以防止流量分析。您也可以使用 HTTP/2 填充,但与 EDNS 填充不同,它不会在来自 DoH 服务器的响应中产生填充。

  • 仅限对隐私敏感的应用或浏览器模式使用 RFC 8484 POST

    对 DoH 查询使用 POST 会降低响应的可缓存性,并可能增加 DNS 延迟时间,因此通常不建议这样做。不过,对于隐私敏感型应用,减少缓存可能是需要的,并且可以防范 Web 应用试图确定用户最近访问过哪些网域的定时攻击。

问题

如要报告 bug 或请求新功能,请创建与 DoH 相关的问题