跳到主要内容

5. HTTP 集成

本协议 MUST 与 https URI scheme [RFC7230] 一起使用.

第 8 节和第 9 节讨论与 HTTP 集成时的其他注意事项.

5.1. 缓存交互​

DoH 交换可以经过一个缓存层次结构, 其中既包括 HTTP 专用缓存, 也包括 DNS 专用缓存. 这些缓存可能存在于 DoH 服务器和客户端之间, 也可能存在于 DoH 客户端自身上. HTTP 缓存按设计是通用的, 也就是说, 它们不了解本协议. 即使 DoH 客户端已经修改其缓存实现以感知 DoH 语义, 也不能推断所有上游缓存 (例如 inline proxies, server-side gateways 和 content delivery networks) 都会如此.

因此, DoH 服务器需要仔细考虑它们在响应 GET 请求时发送的 HTTP 缓存元数据 (除非发送特定的响应头字段, 否则 POST 请求的响应不可缓存; 这并未被广泛实现, 也不建议用于 DoH).

特别是, DoH 服务器 SHOULD 分配显式的 HTTP freshness lifetime (见 [RFC7234] 第 4.2 节), 以便 DoH 客户端更可能使用新鲜的 DNS 数据. 这一要求的原因是 HTTP 缓存可以分配自己的启发式新鲜度 (例如 [RFC7234] 第 4.2.2 节中描述的机制), 这会使缓存内容脱离 DoH 服务器的控制.

DoH HTTP 响应所分配的 freshness lifetime MUST 小于或等于 DNS 响应 Answer 节中最小的 TTL. RECOMMENDED 使用等于 Answer 节中最小 TTL 的 freshness lifetime. 例如, 如果 HTTP 响应携带三个 RRset, 其 TTL 分别为 30, 600 和 300, 则 HTTP freshness lifetime 应为 30 秒 (可指定为 "Cache-Control: max-age=30"). 这一要求有助于防止 HTTP 缓存中消息里的过期 RRset 被无意提供.

如果 DNS 响应的 Answer 节中没有记录, 并且 DNS 响应的 Authority 节中有 SOA 记录, 则响应 freshness lifetime MUST NOT 大于该 SOA 记录中的 MINIMUM 字段 (见 [RFC2308]).

在服务器策略允许时, stale-while-revalidate 和 stale-if-error Cache-Control 指令 [RFC5861] 可能非常适合 DoH 实现. 这些机制允许客户端按服务器的裁量, 重用不再新鲜的 HTTP 缓存条目. 在这种情况下, 客户端要么重用缓存条目的全部内容, 要么完全不重用.

DoH 服务器在生成并非全局有效的响应时, 也需要考虑 HTTP 缓存. 例如, 如果 DoH 服务器基于客户端身份定制响应, 它就不会希望允许该响应被全局重用. 这可以通过多种 HTTP 技术实现, 例如使用 Cache-Control max-age 0, 或使用 Vary 响应头字段 (见 [RFC7231] 第 7.1.4 节) 来建立二级缓存键 (见 [RFC7234] 第 4.1 节).

DoH 客户端在计算响应的 DNS TTL 时 MUST 考虑 Age 响应头字段的值 [RFC7234]. 例如, 如果收到一个 DNS TTL 为 600 的 RRset, 但 Age 头字段指示该响应已经被缓存 250 秒, 则该 RRset 的剩余生命周期为 350 秒. 这一要求同时适用于 DoH 客户端 HTTP 缓存和 DoH 客户端 DNS 缓存.

DoH 客户端可以使用 "no-cache" 请求 Cache-Control 指令 (见 [RFC7234] 第 5.2.1.4 节) 以及类似控制, 请求 HTTP 响应的未缓存副本. 注意, 某些缓存可能不会遵循这些指令, 原因可能是配置, 也可能是与没有此类机制的传统 DNS 缓存交互.

HTTP conditional requests [RFC7232] 对 DoH 的价值可能有限, 因为重新验证只带来带宽收益, 而 DNS 事务通常受延迟约束. 此外, 支持重新验证的 HTTP 响应头字段 (例如 "Last-Modified" 和 "Etag") 与 DNS 响应的整体大小相比通常相当大, 并且其可变性质会持续给 HTTP/2 压缩字典 [RFC7541] 造成压力. 其他类型的 DNS 数据, 例如区域传送, 可能更大, 并且能从重新验证中获得更多收益.

5.2. HTTP/2​

HTTP/2 [RFC7540] 是与 DoH 一起使用时最低 RECOMMENDED 的 HTTP 版本.

经典基于 UDP 的 DNS [RFC1035] 中的消息天然无序且开销很低. 具有竞争力的 HTTP 传输需要支持重新排序, 并行性, 优先级和头部压缩, 才能实现类似性能. 这些特性是在 HTTP/2 [RFC7540] 中引入 HTTP 的. 较早版本的 HTTP 能够传达 DoH 的语义要求, 但可能导致非常差的性能.

5.3. 服务器推送​

在使用 DoH 响应数据进行 DNS 解析之前, 客户端 MUST 确认 HTTP 请求 URI 可用于该 DoH 查询. 对于由 DoH 客户端发起的 HTTP 请求, 这一点隐含在 URI 的选择中. 对于 HTTP server push (见 [RFC7540] 第 8.2 节), 必须格外小心, 以确保被推送的 URI 正是如果客户端发起请求时会将同一查询定向到的 URI (除了服务器推送通常所需的其他安全检查之外).

5.4. 内容协商​

为了最大限度地提高互操作性, DoH 客户端和 DoH 服务器 MUST 支持 "application/dns-message" 媒体类型. 其他媒体类型 MAY 按 HTTP Content Negotiation 的定义使用 (见 [RFC7231] 第 3.4 节). 这些媒体类型 MUST 足够灵活, 能表达通常会通过 DNS over UDP 发送的每一个 DNS 查询 (包括使用 DNS 扩展的查询和响应, 但不包括需要多个响应的查询和响应).