summaryrefslogtreecommitdiff
path: root/9_dot_fake/send_doh_query.py
blob: 4dec9e4e7ccc01f2e58a3120731696675d3bcd03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import socket
import ssl
import dns.message
import dns.query
import dns.rcode
import argparse
import ipaddress
import base64
import httpx


def do53_query(name,type):
    query = dns.message.make_query(qname=name, rdtype=type)
    response_message = dns.query.udp(q=query, port=53, where='127.0.0.54', timeout=5)
    print(f'本地do53解析域名{name}的{type}记录:\n{response_message}')


def p1(doh,mode,name,type):
    print(f'========Phase 1: 解析获取DoT服务器的IP地址========')
    query = dns.message.make_query(qname=doh, rdtype='A')
    for i in range(1,4):
        try:
            response_message = dns.query.udp(q=query, port=53, where='127.0.0.54', timeout=5)
        except:
            response_message = ''
            print(f'获取失败,重试{i}')
    if response_message != '':
        print(f'{doh} A 记录地址为 {response_message.answer[0]}')
        p2(str(response_message.answer[0]).split(' ')[-1],args.mode,args.name,args.type)
    else:
        if mode == 'opportunistic':
            print('机会隐私设置,降为明文进行查询')
            do53_query(name, type)
        else:
            print('严格隐私设置,查询结束')


def p2(doh_ip,mode,name,type):
    print(f'========Phase 2: 与DoT服务器{doh_ip}建立连接========')
    query = dns.message.make_query(qname=name, rdtype=type)
    headers = {"content-type": "application/dns-message", "accept": "application/dns-message", "host":doh_ip}
    for i in range(1,4):
        try:
            with httpx.Client(http2=True, http1=True, verify=True, timeout=5) as client:
                resp = client.get(f"https://{doh_ip}/dns-query?dns=" + base64.b64encode(query.to_wire()).decode("UTF8").rstrip("="),
                           headers=headers)
                response_message = dns.message.from_wire(resp.content)
                #print(response_message)

        except:
            response_message = ''
            print(f'获取失败,重试{i}')
    if response_message == '':
        if mode == 'opportunistic':
            print('机会隐私设置,降为明文进行查询')
            do53_query(name, type)
        else:
            print('严格隐私设置,查询结束')
    else:
        print(f'解析域名{name}的{type}记录:\n{response_message}')



parser = argparse.ArgumentParser()
parser.add_argument('-doh', '--doh', default='dns.alidns.com')
parser.add_argument('-mode', '--mode', default='opportunistic')
parser.add_argument('-name', '--name', default='www.baidu.com')
parser.add_argument('-type', '--type', default='A')
args = parser.parse_args()

print(f'DoH server: {args.doh}')
try:
    if ipaddress.ip_address(args.doh):
        p2(args.doh, args.mode, args.name, args.type)

except:
    p1(args.doh,args.mode,args.name,args.type)