使用 Curl 检查 DoH 可用性
简单快速检测、一般 Linux 和 Windows 10 版本 1803 后都自带 Curl。
文末带有示例,复制执行即可。
标准请求
根据 RFC 8484,DNS over HTTPS (DoH)支持通过 HTTP GET 和 POST 两种方法发送请求。
-
GET 请求:
- 在 GET 请求中,DNS 查询被编码为一个查询参数。这个参数使用 Base64URL 编码的 DNS 请求内容,并附加到 URI 上。例如,一个 GET 请求的 URI 可能类似于
https://dnsserver.example.net/dns-query?dns=<base64url-encoded-query>
。 - 使用 GET 请求的优点是它更友好于许多 HTTP 缓存实现,可以利用 HTTP 缓存来缓存响应。
- 在 GET 请求中,DNS 查询被编码为一个查询参数。这个参数使用 Base64URL 编码的 DNS 请求内容,并附加到 URI 上。例如,一个 GET 请求的 URI 可能类似于
-
POST 请求:
- 在 POST 请求中,DNS查询被包含在 HTTP 请求的主体中,媒体类型为
application/dns-message
。例如,POST 请求的内容类型和长度需要在 HTTP 头中指定,且 DNS 查询以 DNS wireformat 编码放在请求体中。 - POST 请求通常比 GET 请求更小,因为不需要将请求内容编码到 URI 中。
- 在 POST 请求中,DNS查询被包含在 HTTP 请求的主体中,媒体类型为
无论是 GET 还是 POST 方法,DoH 服务器都需要实现这两种方法来处理 DNS 查询。
RFC 8484 还规定,DoH 客户端应该包含 HTTP Accept 头字段,以指示可以处理的响应类型,并且必须能够处理 application/dns-message
类型的响应。
请求例如:
curl -vH "accept: application/dns-message" "https://cloudflare-dns.com/dns-query?dns=AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB"
你或许尝试过对
AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB
进行 Base64URL 解码,但你会得到一些乱码。那是因为这个 Base64URL 是二进制编码转 Base64URL 而不是字符串转 Base64URL,但是我没找到具体定义。(看起来是 RFC 1035 中定义的 DNS wireformat)
而且这种请求返回的响应 application/dns-message
也是一个二进制,该格式在 RFC 1035 中定义,因此标准 DoH 请求非常不利于人类查看和使用。
7.1. Registration of the "application/dns-message" Media Type
Type name: application
Subtype name: dns-message
Required parameters: N/A
Optional parameters: N/A
Encoding considerations: This is a binary format. The contents are a
DNS message as defined in RFC 1035. The format used here is for
DNS over UDP, which is the format defined in the diagrams in
RFC 1035.Security considerations: See RFC 8484. The content is a DNS message
and thus not executable code.Interoperability considerations: None.
Published specification: RFC 8484.
Applications that use this media type:
Systems that want to exchange full DNS messages.
摘自 RFC 8484
所以在我们人类快速检查可用性时,大概应该使用下面的 JSON API 形式。
JSON API
RFC 8427 定义了以下 JSON 对象成员来表示 DNS 消息:
- ID:整数,范围为 0 到 65535。
- QR:布尔值,表示查询或响应。
- Opcode:整数,范围为 0 到 15,表示操作码。
- AA:布尔值,表示是否权威回答。
- TC:布尔值,表示是否被截断。
- RD:布尔值,表示是否递归期望。
- RA:布尔值,表示是否递归可用。
- AD:布尔值,表示是否经过 DNSSEC 验证。
- CD:布尔值,表示是否禁用 DNSSEC 验证。
- RCODE:整数,范围为 0 到 15,表示返回码。
- QDCOUNT:整数,范围为 0 到 65535,表示问题计数。
- ANCOUNT:整数,范围为 0 到 65535,表示回答计数。
- NSCOUNT:整数,范围为 0 到 65535,表示权威记录计数。
- ARCOUNT:整数,范围为 0 到 65535,表示附加记录计数。
然而并没有人在乎 RFC 8427,我也没有看到哪个 RFC 规定了 JSON API 实现方式。
实践中,各大公共 DNS 几乎都支持以如下方式请求:
curl -vH "accept: application/dns-json" "https://cloudflare-dns.com/dns-query?name=example.com&type=A"
但部分公共 DNS 似乎也存在分歧,有的也会要求使用 /resolve
路径:
curl -vH "accept: application/dns-json" "https://dns.google/resolve?name=example.com&type=A"
返回的 JSON 示例如下:
{
"Status":0,
"TC":false,
"RD":true,
"RA":true,
"AD":true,
"CD":false,
"Question":[
{
"name":"example.com",
"type":1
}
],
"Answer":[
{
"name":"example.com",
"type":1,
"TTL":2080,
"data":"93.184.215.14"
}
]
}
与 RFC 8427 定义不同,这似乎是事实标准。
所以也许应该是 Cloudflare Style 和 Google Style?
但即使这样,返回格式也不一定是一样的(比如 dns.sb),所以如果你写程序,最好还是不要用 JSON API 了。
快速检测请使用文末的示例。
Curl 原生
curl 7.62.0 版本中原生支持了 DoH。
请求如:
curl --doh-url https://cloudflare-dns.com/dns-query https://www.example.com
详情请参阅:https://github.com/curl/curl/wiki/DOH-implementation
但我并不推荐使用,因为我们只是测试,而且你的版本不一定达标,而且此命令的目的是通过 DoH 解析后请求目标网址。
那么 DoT 呢?
很遗憾,我并没有找到简单快速且 Linux/Windows 自带的工具。
你也可以尝试这些全平台工具:
或这些 Linux Only 工具:
不过在 Linux 中如果你的 dig (BIND) 版本大于 9.17.10,那么你很可能已经有了 DoH 支持。
请求如:
dig +https @cloudflare-dns.com example.com A
详情请参阅:https://www.isc.org/blogs/bind-doh-update-2021/
JSON API 请求示例
中国大陆
Dnspod 公共 DNS
https://docs.dnspod.cn/public-dns/dot-doh/
虽然有文档,但是完全没说请求方式,相当于没有文档。
地区:CN、有部分全球接入能力
域名
curl -vH "accept: application/dns-json" "https://doh.pub/dns-query?name=example.com&type=A"
IPv4
curl -vH "accept: application/dns-json" "https://1.12.12.12/dns-query?name=example.com&type=A"
curl -vH "accept: application/dns-json" "https://120.53.53.53/dns-query?name=example.com&type=A"
IPv6
看起来没有,2402:4e00::
并不能用。
阿里公共 DNS
https://alidns.com/articles/6018321800a44d0e45e90d71
特别注意,阿里 DNS 的 JSON API 查询路径不是 /dns-query
而是 /resolve
。
地区:CN、有部分全球接入能力
域名
curl -vH "accept: application/dns-json" "https://dns.alidns.com/resolve?name=example.com&type=A"
IPv4
curl -vH "accept: application/dns-json" "https://223.5.5.5/resolve?name=example.com&type=A"
curl -vH "accept: application/dns-json" "https://223.6.6.6/resolve?name=example.com&type=A"
IPv6
看起来没有,2400:3200::1
和 2400:3200:baba::1
并不能用,但是文档说可以。
curl -vH "accept: application/dns-json" "https://[2400:3200::1]/resolve?name=example.com&type=A"
curl -vH "accept: application/dns-json" "https://[2400:3200:baba::1]/resolve?name=example.com&type=A"
360安全 DNS
https://sdns.360.net/index.html
IP 有亿点多,但是没有 BGP 和全球接入能力。
地区:CN
域名
curl -vH "accept: application/dns-json" "https://doh.360.cn/resolve?name=example.com&type=A"
IPv4
curl -vH "accept: application/dns-json" "https://180.163.249.75/resolve?name=example.com&type=A"
curl -vH "accept: application/dns-json" "https://101.198.192.33/resolve?name=example.com&type=A"
curl -vH "accept: application/dns-json" "https://101.198.191.4/resolve?name=example.com&type=A"
curl -vH "accept: application/dns-json" "https://101.226.4.6/resolve?name=example.com&type=A"
curl -vH "accept: application/dns-json" "https://218.30.118.6/resolve?name=example.com&type=A"
curl -vH "accept: application/dns-json" "https://123.125.81.6/resolve?name=example.com&type=A"
curl -vH "accept: application/dns-json" "https://140.207.198.6/resolve?name=example.com&type=A"
IPv6
无?
EasyMosdns
已禁止其它 DoH 客户端请求,仅 EasyMosdns 可用。
由于一些 UP 主将分流 API 宣传成 DoH 用途,以及各种不可描述的产品内置,原公益版 API 已于 2025 年 3 月 5 日关闭服务。
本站从未提供过公共 DNS 服务,公益版 API 仅作为项目的演示地址与分流 API 使用,为防止被滥用,新版 API 已限制 DoH 请求
分流 API 已内置在开源项目中,禁止其它 DoH 客户端请求,仅限在本项目使用
如需在更多客户端体验分流效果,请通过打赏项目获取无请求限制的分流 API
个人自建的 DNS,于 2019 启用,仅提供 DoH,仅限研究用途,不承诺 SLA,在 CN 提供无污染 DNS,本质是一个 DNS 转发器。开源项目 EasyMosdns 官方的 DNS 分流 API。
地区:CN
不支持 JSON API
域名
curl -vH "accept: application/dns-message" "https://doh.apad.pro/dns-query?dns=AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB"
IPv4
183.134.17.113
不能用。
IPv6
无
微步 OneDNS
纯净版,不拦截域名。
然而完全没有反应,服务器甚至没有返回 TLS 证书。
估计已被放弃。
域名
curl -vH "accept: application/dns-json" "https://doh-pure.onedns.net/dns-query?dns=AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB"
IPv4
我觉得没必要测了。
全球/中国大陆外
Cloudflare 公共 DNS
https://developers.cloudflare.com/1.1.1.1/encryption/dns-over-https/
地区:Global、CN 除外
域名
curl -vH "accept: application/dns-json" "https://cloudflare-dns.com/dns-query?name=example.com&type=A"
curl -vH "accept: application/dns-json" "https://mozilla.cloudflare-dns.com/dns-query?name=example.com&type=A"
IPv4
curl -vH "accept: application/dns-json" "https://1.1.1.1/dns-query?name=example.com&type=A"
curl -vH "accept: application/dns-json" "https://1.0.0.1/dns-query?name=example.com&type=A"
IPv6
curl -vH "accept: application/dns-json" "https://[2606:4700:4700::1111]/dns-query?name=example.com&type=A"
curl -vH "accept: application/dns-json" "https://[2606:4700:4700::1001]/dns-query?name=example.com&type=A"
Google 公共 DNS
https://developers.google.com/speed/public-dns/docs/doh
特别注意,Goole DNS 的 JSON API 查询路径不是 /dns-query
而是 /resolve
。
地区:Global、CN 除外
域名
curl -vH "accept: application/dns-json" "https://dns.google/resolve?name=example.com&type=A"
IPv4
curl -vH "accept: application/dns-json" "https://8.8.8.8/resolve?name=example.com&type=A"
curl -vH "accept: application/dns-json" "https://8.8.4.4/resolve?name=example.com&type=A"
IPv6
curl -vH "accept: application/dns-json" "https://[2001:4860:4860::8888]/resolve?name=example.com&type=A"
curl -vH "accept: application/dns-json" "https://[2001:4860:4860::8844]/resolve?name=example.com&type=A"
DNS.SB
返回的 JSON 和相比其他家略有不同。
地区:Global(但接入能力比较有限)、CN 除外
域名
curl -vH "accept: application/dns-json" "https://doh.dns.sb/dns-query?name=example.com&type=A"
curl -vH "accept: application/dns-json" "https://doh.sb/dns-query?name=example.com&type=A"
IPv4
curl -vH "accept: application/dns-json" "https://45.11.45.11/dns-query?name=example.com&type=A"
curl -vH "accept: application/dns-json" "https://185.222.222.222/dns-query?name=example.com&type=A"
IPv6
看起来没有,2a09::
和 2a11::
并不能用。
Quad 101
无文档。
返回的 JSON 和相比其他家略有不同。
地区:TW
域名
curl -vH "accept: application/dns-json" "https://dns.twnic.tw/dns-query?name=example.com&type=A"
域名测试我没有成功,IP 倒是可以。
IPv4
curl -vH "accept: application/dns-json" "https://101.101.101.101/dns-query?name=example.com&type=A"
101.102.103.104
不能用。
IPv6
看起来没有,2001:de4::101
及 2001:de4::102
并不能用。
NextDNS
私人定制 DNS,免费每月 3000000 次查询,超过后可以继续应答,但是自定义规则失效。
地区:Global,似乎有 CN 节点。
域名
curl -vH "accept: application/dns-message" "https://dns.nextdns.io/c98785c/dns-query?dns=AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB"
注意:路径中的 c98785c
是一个临时 ID,一段时间后失效,要测试请访问其网站,获取一个临时 ID 并替换。
不支持 JSON API。
IPv4
似乎要 IP 白名单才能使用,但是并没有 IP 证书,所以不能用。
IPv6
虽然它会根据你的 ID 生成唯一 IPv6,例如 c98785c :2a07:a8c0::c9:785c
和 2a07:a8c1::c9:785c
但是并没有 IP 证书,所以不能用。
无评论