All Products
Search
Document Center

Alibaba Cloud DNS:DNS over HTTPs(DoH)

Last Updated:Sep 22, 2023

This topic describes how to access Alibaba Cloud Public DNS by using DNS over HTTPS (DoH).

Alibaba Cloud Public DNS provides DNS resolution by using the TLS-encrypted HTTP connections as specified in the RFC 8484 specifications.

https://user_id.alidns.com/dns-query

Obtain user_id

The account ID can be checked in the Alibaba Cloud DNS console.

Configure DoH as common users

Assuming that the account ID is 9999, set the address of the DoH server as follows:

https://9999.alidns.com/dns-query

The following example describes how to configure a DoH server on Firefox.

Step 1: Click the More icon in the upper-right corner of the browser and select Options.

Step 2: Enter DNS in the search box and click Settings in the Network Settings section.

Step 3: In the lower part of the Connection Settings dialog box, select Enable DNS over HTTPS, select Custom from the Use Provider drop-down list, and then enter https://9999.alidns.com/dns-query in the Custom field. Then, click OK.

Use DoH services as developers

As a developer, you must generate a DoH HTTP request and send it to the DoH service address as specified in the RFC 8484 specifications.

You can use both the GET and POST methods to generate a DoH HTTP request. When the POST method is used, the DNS query is included in the message body of the HTTP request. When the GET method is used, the only variable dns is assigned to the Base64URL-encoded DNS request content.

Sample code (Python and Golang)

For example, if you use GET to initiate a DoH query, the DNS binary packet is processed by using Base64URL to obtain DNS parameters and generate a complete DoH HTTP URL. Then, an HTTP request is initiated to obtain a DNS response packet.

The following Python code example shows how to use DoH to query the domain name alibaba.com:

import dns.message
import requests
import base64
import json

doh_url = "https://dns.alidns.com/dns-query"
domain = "alibaba.com"
rr = "A"
result = []

message = dns.message.make_query(domain, rr)
dns_req = base64.b64encode(message.to_wire()).decode("UTF8").rstrip("=")
r = requests.get(doh_url + "?dns=" + dns_req,
                 headers={"Content-type": "application/dns-message"})
for answer in dns.message.from_wire(r.content).answer:
    dns = answer.to_text().split()
    result.append({"Query": dns[0], "TTL": dns[1], "RR": dns[3], "Answer": dns[4]})
    print(json.dumps(result))

The following result is returned:

$ python test_doh.py
[{"Answer": "106.11.XXX.XXX", "Query": "alibaba.com.", "RR": "A", "TTL": "133"}]

The following Golang code example shows how to use DoH to query the domain name alibaba.com:

package main

import (
        "encoding/base64"
        "fmt"
        "github.com/miekg/dns"
        "io/ioutil"
        "net/http"
        "os"
)

func main() {
       query := dns.Msg{}
       query.SetQuestion("www.taobao.com.", dns.TypeA)
       msg, _ := query.Pack()
       b64 := base64.RawURLEncoding.EncodeToString(msg)
       resp, err := http.Get("https://dns.alidns.com/dns-query?dns=" + b64)
       if err != nil {
            fmt.Printf("Send query error, err:%v\n", err)
            os.Exit(1)
       }
       defer resp.Body.Close()
       bodyBytes, _ := ioutil.ReadAll(resp.Body)
       response := dns.Msg{}
       response.Unpack(bodyBytes)
       fmt.Printf("Dns answer is :%v\n", response.String())
}

The following result is returned:

Sent Get query https://dns.alidns.com/dns-query?dns=xzEBAAABAAAAAAAAA3d3dwZ0YW9iYW8DY29tAAABAAE
Dns answer is :;; opcode: QUERY, status: NOERROR, id: 50993
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; QUESTION SECTION:
;www.taobao.com.        IN       A

;; ANSWER SECTION:
www.taobao.com. 15      IN      CNAME   www.taobao.com.danuoyi.tbcache.com.
www.taobao.com.danuoyi.tbcache.com.     15      IN      A       221.229.XXX.XXX
www.taobao.com.danuoyi.tbcache.com.     15      IN      A       221.229.XXX.XXX

;; ADDITIONAL SECTION:

;; OPT PSEUDOSECTION:
; EDNS: version 0; flags: ; udp: 4096