本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。
本章节介绍DoH的接入过程。
阿里公共DNS通过RFC 8484指定的经过TLS加密的HTTP连接提供DNS解析。
接入流程
获取user_id
请在云解析DNS产品控制台 > 递归解析(公共DNS) > 接入配置 路径下查看 专属配置ID(Account ID)。
打开DoH接入开关
在 递归解析(公共DNS) 页面选择 接入配置 页签。
单击 接入指引 栏下的 启用状态 开关按钮,将开关打开。
警告若您决定弃用DoH方式接入公共DNS,可以将启用状态设置为关闭。
请慎重操作停服功能。停服后将降级为免费用户,即停止计费、停止控制台报表展示和其他功能操作。您的公共DNS服务也将不再有SLA保证,且会被限速和拒绝解析应答。
停服之后支持重启服务。重启后,服务恢复原来的配置,并重新开始计费。
普通用户使用DoH服务
假设Account_ID是9**9,则用户的DoH接口配置为:https://9**9.alidns.com/dns-query
。
本文以Chrome为例,介绍如何配置DoH。
打开Chrome浏览器,从 Chrome 菜单栏中点击 【设置】选项。
在搜索框中输入“DNS”,在下方的检索结果中,点击【安全】右侧的展开箭头。
页面下拉到最下方,在【高级】选项中,开通“使用安全DNS”功能,并在【使用】-【自定义】框中输入“
https://9**9.alidns.com/dns-query
”即可完成配置。
开发者使用DoH服务
对开发者,需要按照RFC8484中的标准要求生成DoH的 HTTP request请求发送给DoH服务地址。
DoH可以同时用GET和POST两种方法。当使用POST方法,DNS查询消息被包含在HTTP 请求的message body中。当使用GET方法,唯一的变量"dns"被赋值为base64url编码的DNS请求内容。
开发者案例 (附python和Golang代码示例)
例如用GET方式发起DoH查询,先将DNS二进制报文经过base64url的处理得到DNS参数,生成完整的DoH HTTP URL,再发起HTTP请求,获得DNS应答报文。
下面是一段python的代码,演示开发者如何使用DoH查询域名alibaba.com。
import dns.message
import requests
import base64
import json
doh_url = "https://9**9.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))
运行结果如下:
$ python test_doh.py
[{"Answer": "106.11.XXX.XXX", "Query": "alibaba.com.", "RR": "A", "TTL": "133"}]
下面是一段Golang的代码,演示开发者如何使用DoH查询域名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://9**9.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())
}
运行结果如下:
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