本文统一说明阿里云 HTTPDNS 的 DoH(DNS over HTTPS)端点、请求/响应格式、错误语义。
1. 前提条件
在完成配置DoH服务后,您可以通过直接调用DoH接口,获取解析 IP。
2. DoH接口说明
接口符合 RFC 8484 标准,支持 GET 与 POST 两种方式:GET 通过 dns
参数(Base64URL)提交 DNS 报文,POST 通过二进制请求体提交 DNS 报文。
2.1 GET 接口
用于通过 URL 查询参数传递 DNS 报文(Base64URL 编码),请求和响应如下:
请求
方法:
GET
路径:
/dns-query?dns=<base64url(dns_wire_message)>
请求头:
Accept: application/dns-message
查询参数:
dns
(必填):DNS 二进制报文经 Base64URL 编码后的字符串(无=
补位)。
响应
200:成功,Body 为
application/dns-message
(DNS 二进制应答)。400:参数错误(未开启 DoH、缺失/非法
dns
参数等)。5xx:服务端错误。
对于不在解析域名列表的域名,DoH 会返回 200 的状态码但没有解析结果。
2.2 POST 接口
用于在请求体中直接传输 DNS 二进制报文,请求和响应如下:
请求
方法:POST
路径:
/dns-query
请求头:
Content-Type: application/dns-message
Accept: application/dns-message
请求体:
DNS 二进制报文(wire format)。
响应
200:成功,Body 为
application/dns-message
(DNS 二进制应答)。400:参数错误(未开启 DoH 或报文非法)。
5xx:服务端错误。
对于不在解析域名列表的域名,DoH 会返回 200 的状态码但没有解析结果。
2.3 请求示例
下面以python为例,依赖网络库 dnspython
和 requests
,演示如何通过 DoH 请求,获取www.aliyun.com
的解析结果。
GET请求示例
示例代码
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import requests import base64 import dns.message def query_doh(domain, rrType): # 创建DNS请求 request = dns.message.make_query(domain, rrType) request_data = request.to_wire() # 将请求编码为base64URL格式 base64_query = base64.urlsafe_b64encode(request_data).decode().rstrip("=") # 使用HTTPDNS的DoH接入点 url = f"https://1xxxx3.aliyunhttpdns.com/dns-query?dns={base64_query}" # 发送GET请求 headers = { "Accept": "application/dns-message" } response = requests.get(url, headers=headers) # 错误检查 if response.status_code != 200: print(f"Error: {response.status_code}") return # 解析响应 response_data = response.content dns_response = dns.message.from_wire(response_data) # 提取和打印IP地址 for answer in dns_response.answer: ttl = answer.ttl for item in answer.items: print(f"Answer: {item} TTL: {ttl}") if __name__ == "__main__": # 查询的域名 domain = "www.aliyun.com" rrType = "A" query_doh(domain, rrType)
预期结果
Answer: www-jp-de-intl-adns.aliyun.com. TTL: 3600 Answer: www-jp-de-intl-adns.aliyun.com.gds.alibabadns.com. TTL: 3600 Answer: www.aliyun.com.w.cdngslb.com. TTL: 3600 Answer: 61.164.xxx.xxx TTL: 3600 Answer: 183.146.xxx.xxx TTL: 3600 Answer: 60.188.xxx.xxx TTL: 3600 Answer: 122.228.xxx.xxx TTL: 3600
POST请求示例
示例代码
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import requests import dns.message def query_doh_post(domain, rrType): # 创建DNS请求 request = dns.message.make_query(domain, rrType) request_data = request.to_wire() # 使用HTTPDNS的DoH接入点 url = "https://1xxxx3.aliyunhttpdns.com/dns-query" # 发送POST请求 headers = { "Accept": "application/dns-message", "Content-Type": "application/dns-message" } # 直接发送DNS wire format数据作为POST body response = requests.post(url, headers=headers, data=request_data) # 错误检查 if response.status_code != 200: print(f"Error: {response.status_code}") return # 解析响应 response_data = response.content dns_response = dns.message.from_wire(response_data) # 提取和打印IP地址 for answer in dns_response.answer: ttl = answer.ttl for item in answer.items: print(f"Answer: {item} TTL: {ttl}") if __name__ == "__main__": # 查询的域名 domain = "www.aliyun.com" rrType = "AAAA" query_doh_post(domain, rrType)
预期结果
Answer: www-jp-de-intl-adns.aliyun.com. TTL: 120 Answer: www-jp-de-intl-adns.aliyun.com.gds.alibabadns.com. TTL: 300 Answer: www.aliyun.com.w.cdngslb.com. TTL: 120 Answer: 240e:f7:7c00:xxxx:xxxx::xxxx TTL: 60 Answer: 240e:f7:7c00:xxxx:xxxx::xxxx TTL: 60
3. 总结
本文介绍了HTTPDNS 提供的 DoH 接口,您可以参考接口说明和示例代码访问 DoH 接入点进行域名解析。