跳到正文
IT技术

DNS-over-HTTP/3 和 DNS-over-QUIC 的区别

DNS-over-HTTP/3 和 DNS-over-QUIC 两种协议都基于 UDP,且传输数据都经过 TLS 加密,但是这两种协议是完全不同的。


先来简单了解下 QUIC 协议:

QUIC 和 TCP、UDP 一样,是传输层协议,不过 QUIC 协议是基于加密 UDP 的(使用 TLS 1.3 来加密),QUIC 还具有 TCP 的一些优点。

DNS-over-QUIC:

DNS-over-QUIC 是通过 QUIC 加密的 DNS 协议,有时会被简写为 DoQ,这个协议于 2022 年 5 月 发布为 RFC 9250,它比较类似 DNS-over-TLS,但是 DNS-over-QUIC 会比 DNS-over-TLS 更快一些。可以看到握手成功,服务器返回了 HTTP 状态码 400(这是正常的。为什么?因为 dns-query 没有提供 DNS 查询的参数,所以服务器返回了 Bad Request)

curl 无法与 DNS-over-QUIC 服务器进行握手和数据交换,因为 DNS-over-QUIC 只是经过 QUIC 封装的原生 DNS,并不能处理 HTTP 请求。

尝试使用 curl 来连接 DNS-over-QUIC 服务器,得到的输出如下:

$ curl https://dns.mbrjun.cn:784 --http3 -v
*   Trying 127.0.0.1:784...
* Connect socket 5 over QUIC to 127.0.0.1:784
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
* ngtcp2_conn_handle_expiry returned error: ERR_HANDSHAKE_TIMEOUT
* connect to 127.0.0.1 port 784 failed: Failed sending data to the peer
* Failed to connect to dns.mbrjun.cn port 784 after 10050 ms: Failed sending data to the peer
* Closing connection 0
curl: (55) ngtcp2_conn_handle_expiry returned error: ERR_HANDSHAKE_TIMEOUT
````

可以看到 QUIC 套接字已经创建完成,但是服务器并不响应这个 HTTP 请求:

DNS-over-QUIC = QUIC + DNS

### DNS-over-HTTP/3:

DNS-over-HTTP/3,有时也会被称作 DoH3,也是一种加密的 DNS 协议,这种协议在 Android 11 中通过增量更新得到了 Android 的原生支持。

DNS-over-HTTP/3 使用 HTTP 作为传输层协议,本质上是 DNS-over-HTTPS 的一种。

DNS-over-HTTPS 允许使用 HTTP/3、HTTP/2、HTTP/1.1、HTTP/1.0、HTTP/0.9 作为底层协议(实际上,只有前种常被使用),而 DNS-over-HTTP/3 是指使用 HTTP/3 做底层协议的 DNS-over-HTTPS

HTTP/3 协议基于 QUIC,因此可以说 HTTP/3 = QUIC + HTTP

DNS-over-HTTP/3 = QUIC + HTTP + DNS

curl 可以和 DNS-over-HTTP/3 服务器进行握手和数据交换,因为 DNS-over-HTTP/3 是经过 QUIC 封装的 HTTP,在 HTTP 上提供 DNS 查询的功能,因此可以处理 HTTP 请求。

尝试使用 curl 来连接 DNS-over-HTTP/3 服务器,得到的输出如下:

$ curl https://dns.mbrjun.cn/dns-query --http3 -vI

  • Trying 127.0.0.1:443...
  • Connect socket 5 over QUIC to 127.0.0.1:443
  • CAfile: /etc/ssl/certs/ca-certificates.crt
  • CApath: none
  • subjectAltName: host "dns.mbrjun.cn" matched cert's "*.mbrjun.cn"
  • Verified certificate just fine
  • Connected to dns.mbrjun.cn (127.0.0.1) port 443 (#0)
  • h2h3 [:method: HEAD]
  • h2h3 [:path: /dns-query]
  • h2h3 [:scheme: https]
  • h2h3 [:authority: dns.mbrjun.cn]
  • h2h3 [user-agent: curl/7.87.1-DEV-MBRjun]
  • h2h3 [accept: /]
  • Using HTTP/3 Stream ID: 0 (easy handle 0x5612c27f71b0)

    HEAD /dns-query HTTP/3
    Host: dns.mbrjun.cn
    user-agent: curl/7.87.1-DEV-MBRjun
    accept: /
  • ngh3_stream_recv returns 0 bytes and EAGAIN
  • ngh3_stream_recv returns 0 bytes and EAGAIN
  • ngh3_stream_recv returns 0 bytes and EAGAIN
    < HTTP/3 400
    HTTP/3 400
    < (headers)
    (headers)
    ...

可以看到握手成功,服务器返回了 HTTP 状态码 400(这是正常的。为什么?因为 dns-query 没有提供 DNS 查询的参数,所以服务器返回了 Bad Request)

## 对比和总结

DNS-over-QUIC = QUIC + DNS

DNS-over-HTTP/3 = QUIC + HTTP + DNS

DoH3 比 DoQ 多了一层 HTTP 封装,因此可以使用类似 curl 的工具进行查询。

由于 DoH3 有一层 HTTP 封装,所以它在传输时会带上 Request Header 和 Response Header,这其中可能包含了 User-Agent 之类的信息,这种信息对于 DNS 来说通常是毫无作用的,理论上,DoH3 会比 DoQ 更慢,但实际上带来的影响是极其少的(可能只会慢个 1-2ms)。

端口号:DoQ 更类似于 DoT,通常使用端口号 443、784 和 853,而 DoH3 是 DoH 的一种,通常使用端口 443。

兼容性:从 Android 11 开始,DoH3 得到了部分支持(谷歌设置了白名单,只有少数公共 DNS 服务器会启用 DoH3),从 iOS 15 (macOS Monterty)开始,Apple 设备支持了 DoQ(仅可通过 iCloud Private Relay 开启,不支持自定义服务器),现在 DoH3 的用户数量和 DoQ 的差不多。

---

附:AdGuard 认为使用 HTTP 作为传输层协议会引起很多不必要的风险,使用 HTTP 发送 DNS 请求会导致下列结果:

* HTTP cookies
* 其他 HTTP 消息头(HTTP headers)(包括 Authentication, User-Agent, Accept-Language)
* 给预谋犯更多机会
* Tracking using ETag
  
Yangsh888
很荣幸您能访问我的网站!这里是一位全栈工程师 & 科技爱好者的个人博客,我是 Yangsh888,微信公众号:"老杨漫谈"

支持使用 Tab 键浏览评论操作;进入回复状态后,按 Esc 可以取消回复并返回原位置。

评论

留下你的想法
还没有评论
期待你的第一条评论。