Asutorufaのブログ

こんにちは

DNS over HTTPS

发布于 2020-06-23|更新于: 2020-06-23|分类 Network

这个DNS系列现在有以下几篇文章

完整代码请看DNS


DOH就比较简单了,因为DOH使用的请求数据和应答数据均为之前的DNS协议格式,包括DNS,EDNS,DNSSEC…当然是否支持EDNS,DNSSEC需要看DNS服务器的支持情况
DOH的最主要的区别是把DNS使用的UDP,换成了HTTPS,这样就能防止DNS污染了,而且可以使用DNSSEC加上ESNI来防止证书劫持,DOH的协议在rfc8484中有定义
DOH主要有两种方式HTTP的GET请求和POST的请求

GET

GET请求需要使用BASE64对请求的字节数据进行序列化,然后作为参数传递,获取到的数据使用我们之前的解析进行解析就行了

func get(dReq []byte, server string) (body []byte, err error) {	query := strings.Replace(base64.URLEncoding.EncodeToString(dReq), "=", "", -1)	urls := "https://" + server + "/dns-query?dns=" + query	res, err := http.Get(urls)	if err != nil {		return nil, err	}	defer res.Body.Close()	body, err = ioutil.ReadAll(res.Body)	if err != nil {		return nil, err	}	return}

POST

POST并不需要进行序列化,直接把原始请求数据作为body就行了

func post(dReq []byte, server string) (body []byte, err error) {	client := &http.Client{Timeout: 5 * time.Second}	req, err := http.NewRequest(http.MethodPost, "", bytes.NewReader(dReq))	if err != nil {		return nil, fmt.Errorf("DOH:post() newReq -> %v", err)	}	urls, err := url.Parse("//" + server)	if err != nil {		return nil, fmt.Errorf("DOH:post() urlParse -> %v", err)	}	req.URL.Scheme = "https"	req.URL.Host = urls.Host	req.URL.Path = urls.Path + "/dns-query"	req.Header.Set("accept", "application/dns-message")	req.Header.Set("content-type", "application/dns-message")	req.ContentLength = int64(len(dReq)) 	resp, err := client.Do(req)	if err != nil {		return nil, fmt.Errorf("DOH:post() req -> %v", err)	}	defer resp.Body.Close()	body, err = ioutil.ReadAll(resp.Body)	if err != nil {		return nil, fmt.Errorf("DOH:post() readBody -> %v", err)	}	return}

完整代码请看开头


rfc8484

0 条评论

©2026Asutorufa