使用自定义客户端发送请求

更新时间:2025-03-10 11:48:59

本文档介绍如何使用自定义DoH客户端发送请求,获取DNS解析结果

前提条件

开启DoH并获取DoH接入地址,请参考DoH开启与使用

说明
  • 如果 DoH 没有处于开启状态,解析请求会失败,HTTPDNS 服务端会返回 400 错误码。

  • 如果「域名解析范围」设置为「域名列表中的域名」时,对于没有在域名列表中添加的域名,HTTPDNS 服务端会返回 200 的状态码但没有解析结果。

  • 如果「域名解析范围」设置为「所有域名」时,对于在黑名单的域名,HTTPDNS 服务端会返回 200 的状态码但没有解析结果。

DoH接口说明

接口功能

通过HTTPS协议进行加密DNS查询,支持RFC 8484标准。

请求参数

参数名

位置

类型

必填

说明

参数名

位置

类型

必填

说明

dns

URL Query

Base64URL字符串

GET必填

GET请求时使用,需对DNS二进制报文进行Base64URL编码

(body)

Request Body

DNS二进制报文

POST必填

POST请求时直接传输原始DNS报文

Accept

HTTP

字符串

固定值application/dns-message

Content-Type

HTTP

字符串

POST必填

固定值application/dns-message(仅POST请求需要)

响应参数

参数名

类型

说明

参数名

类型

说明

HTTP状态码

整型

200:成功。

400:参数错误。

500:服务端错误。

响应体

DNS二进制报文

可需使用DNS解析库解析,包含标准DNS应答字段。

请求示例

使用Get请求

  1. DNS二进制报文进行编码后,赋值给查询参数dns

  2. 设置Accept请求头为application/dns-message

以下展示一个使用Python获取IPv4解析结果的GET请求示例,在运行前需要完成以下步骤:

  1. 安装依赖库 dnspython 和 requests。

  2. 在控制台将www.aliyun.com添加进域名列表或者在开发配置中允许解析所有域名。

#!/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)
    
  1. 将脚本保存至本地并命名为 doh_get_client.py

  2. 执行命令 python3 doh_get_client.py,返回结果如下,示例:

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请求

  1. DNS二进制报文作为request body传入。

  2. 设置accept请求头为application/dns-message

  3. 设置Content-type请求头为application/dns-message

以下展示一个使用Python获取IPv6解析结果的POST请求示例,在运行前,需要:

  1. 安装依赖库 dnspython 和 requests。

  2. 在控制台将www.aliyun.com添加进域名列表或者在开发配置中允许解析所有域名。

#!/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)
    
  1. 将脚本保存至本地并命名为doh_post_client.py

  2. 执行命令 python3 doh_post_client.py,返回结果如下,示例:

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: 60
  • 本页导读
  • 前提条件
  • DoH接口说明
  • 接口功能
  • 请求参数
  • 响应参数
  • 请求示例
  • 使用Get请求
  • 使用POST请求