本文統一說明阿里雲 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-messageAccept: 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: 603. 總結
本文介紹了HTTPDNS 提供的 DoH 介面,您可以參考介面說明和範例程式碼訪問 DoH 存取點進行網域名稱解析。