This topic describes the DNS over HTTPS (DoH) endpoints, request and response formats, and fault semantics of Alibaba Cloud HTTPDNS.
1. Prerequisites
After you configure the DoH service, you can directly call the DoH API to obtain resolved IP addresses.
2. DoH API details
The API complies with the RFC 8484 standard and supports both GET and POST methods. A GET request submits a DNS message using the dns parameter (Base64URL). A POST request submits a DNS message in a binary request body.
2.1 GET method
You can use this method to pass a Base64URL-encoded DNS message as a URL query parameter. The request and response are as follows:
Request
Method:
GETPath:
/dns-query?dns=<base64url(dns_wire_message)>Request header:
Accept: application/dns-message
Query parameter:
dns(Required): The Base64URL-encoded string of the binary DNS message. The string does not contain=padding.
Response
200: Success. The body is
application/dns-message(binary DNS acknowledgement).400: Bad Request. This error occurs if a parameter is invalid. For example, DoH is not enabled, or the
dnsparameter is missing or invalid.5xx: Internal Server Error.
If a domain name is not in the domain name resolution list, DoH returns a 200 status code but does not return a resolution result.
2.2 POST method
You can use this method to directly transmit a binary DNS message in the request body. The request and response are as follows:
Request
Method: POST
Path:
/dns-queryRequest headers:
Content-Type: application/dns-messageAccept: application/dns-message
Request body:
Binary DNS message (wire format).
Response
200: Success. The body is
application/dns-message(binary DNS acknowledgement).400: Bad Request. This error occurs if a parameter is invalid. For example, DoH is not enabled or the message is invalid.
5xx: Internal Server Error.
If a domain name is not in the domain name resolution list, DoH returns a 200 status code but does not return a resolution result.
2.3 Request examples
The following Python examples show how to send DoH requests to retrieve the resolution result for www.aliyun.com. The examples require the network libraries dnspython and requests.
GET request example
Sample code
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import requests import base64 import dns.message def query_doh(domain, rrType): # Create a DNS request request = dns.message.make_query(domain, rrType) request_data = request.to_wire() # Encode the request in Base64URL format base64_query = base64.urlsafe_b64encode(request_data).decode().rstrip("=") # Use the DoH endpoint of HTTPDNS url = f"https://1xxxx3.aliyunhttpdns.com/dns-query?dns={base64_query}" # Send a GET request headers = { "Accept": "application/dns-message" } response = requests.get(url, headers=headers) # Check for errors if response.status_code != 200: print(f"Error: {response.status_code}") return # Parse the response response_data = response.content dns_response = dns.message.from_wire(response_data) # Fetch and print the IP address for answer in dns_response.answer: ttl = answer.ttl for item in answer.items: print(f"Answer: {item} TTL: {ttl}") if __name__ == "__main__": # The domain name to query domain = "www.aliyun.com" rrType = "A" query_doh(domain, rrType)Expected result
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 request example
Sample code
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import requests import dns.message def query_doh_post(domain, rrType): # Create a DNS request request = dns.message.make_query(domain, rrType) request_data = request.to_wire() # Use the DoH endpoint of HTTPDNS url = "https://1xxxx3.aliyunhttpdns.com/dns-query" # Send a POST request headers = { "Accept": "application/dns-message", "Content-Type": "application/dns-message" } # Directly send the DNS wire format data as the POST body response = requests.post(url, headers=headers, data=request_data) # Check for errors if response.status_code != 200: print(f"Error: {response.status_code}") return # Parse the response response_data = response.content dns_response = dns.message.from_wire(response_data) # Fetch and print the IP address for answer in dns_response.answer: ttl = answer.ttl for item in answer.items: print(f"Answer: {item} TTL: {ttl}") if __name__ == "__main__": # The domain name to query domain = "www.aliyun.com" rrType = "AAAA" query_doh_post(domain, rrType)Expected result
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. Summary
This topic describes the DoH API provided by HTTPDNS. You can refer to the API details and sample code to access the DoH endpoint for domain name resolution.