跳到主要内容

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 扩展的查询和响应, 但不包括需要多个响应的查询和响应).