Python中如何实现DNS over HTTP/HTTPS?

https://pypi.org/project/doh-proxy/

从 GitHub 上的信息来看,似乎是一个来自 Facebook 的项目。
Python中如何实现DNS over HTTP/HTTPS?

6 回复

其实我主要是好奇,像 1.1.1.1 的这个查询接口,应该是基于某个开源软件的吧,但具体是哪个呢:

curl -H ‘accept: application/dns-json’ ‘https://cloudflare-dns.com/dns-query?name=example.com&type=AAAA’


在Python里实现DNS over HTTP/HTTPS (DoH),直接用requests库配合公共DoH服务商就行,比如Cloudflare或Google的。下面给你个完整可跑的示例:

import requests
import json

def resolve_doh(domain, dns_server="https://cloudflare-dns.com/dns-query"):
    """
    使用DoH解析域名
    
    Args:
        domain: 要解析的域名 (如 "example.com")
        dns_server: DoH服务器地址,默认用Cloudflare
    
    Returns:
        解析结果列表
    """
    headers = {
        'accept': 'application/dns-json'
    }
    
    params = {
        'name': domain,
        'type': 'A'  # A记录,可改为AAAA、MX等
    }
    
    try:
        response = requests.get(dns_server, headers=headers, params=params)
        response.raise_for_status()
        data = response.json()
        
        if data['Status'] == 0:  # 0表示成功
            answers = data.get('Answer', [])
            return [answer['data'] for answer in answers]
        else:
            print(f"查询失败,状态码: {data['Status']}")
            return []
            
    except requests.exceptions.RequestException as e:
        print(f"网络请求出错: {e}")
        return []
    except json.JSONDecodeError:
        print("响应解析失败")
        return []

# 使用示例
if __name__ == "__main__":
    # 解析域名
    results = resolve_doh("github.com")
    print(f"解析结果: {results}")
    
    # 也可以指定其他DoH服务器
    google_results = resolve_doh(
        "google.com", 
        dns_server="https://dns.google/resolve"
    )
    print(f"Google DoH结果: {google_results}")

代码说明:

  1. 用了Cloudflare的公共DoH端点 https://cloudflare-dns.com/dns-query
  2. 请求头设置 accept: application/dns-json 告诉服务器返回JSON格式
  3. 查询参数包括域名和记录类型(A记录、AAAA记录等)
  4. 响应状态Status为0表示成功,从Answer字段提取结果

其他常用DoH服务器:

  • Google: https://dns.google/resolve
  • Quad9: https://dns.quad9.net/dns-query
  • 阿里云: https://dns.alidns.com/dns-query

如果要更专业的控制,可以用dnspython库:

import dns.message
import dns.query
import base64

def resolve_doh_advanced(domain):
    query = dns.message.make_query(domain, 'A')
    wire_data = query.to_wire()
    
    # 将DNS查询转换为DoH需要的格式
    b64_data = base64.urlsafe_b64encode(wire_data).decode('utf8').rstrip('=')
    
    url = f"https://cloudflare-dns.com/dns-query?dns={b64_data}"
    headers = {'accept': 'application/dns-message'}
    
    response = requests.get(url, headers=headers)
    return dns.message.from_wire(response.content)

requests最简单直接,需要高级功能再上dnspython

一句话建议:直接用requests调公共DoH API最省事。

> While DNSSEC ensures integrity of data between a resolver and an authoritative server, it does not protect the privacy of the “ last mile ” towards you. DNS resolver, 1.1.1.1, supports both emerging DNS privacy standards - DNS-over-TLS, and DNS-over-HTTPS, which both provide last mile encryption to keep your DNS queries private and free from tampering.

> In the end, we decided to build the system around the Knot Resolver from CZ NIC.

https://blog.cloudflare.com/dns-resolver-1-1-1-1/

也写过一个 https://github.com/JamCh01/dohpp 但是有一些小问题始终得不到解决 emmm 很头痛

回到顶部