forked from jason5ng32/MyIP
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdnsresolver.js
143 lines (124 loc) · 4.7 KB
/
dnsresolver.js
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// api/dnsresolver.js
import { Resolver } from 'dns';
import { promisify } from 'util';
import { refererCheck } from '../common/referer-check.js';
// 普通 DNS 服务器列表
const dnsServers = {
'Google': '8.8.8.8',
'Cloudflare': '1.1.1.1',
'OpenDNS': '208.67.222.222',
'Quad9': '9.9.9.9',
'ControlD': '76.76.2.0',
'AdGuard': '94.140.14.14',
'Quad 101': '101.101.101.101',
'AliDNS': '223.5.5.5',
'DNSPod': '119.29.29.29',
'114DNS': '114.114.114.114',
'China Unicom': '123.123.123.123',
};
// DNS-over-HTTPS 服务列表
const dohServers = {
'Google': 'https://dns.google/resolve?',
'Cloudflare': 'https://cloudflare-dns.com/dns-query?ct=application/dns-json&',
'AdGuard': 'https://dns.adguard.com/resolve?',
'AliDNS': 'https://dns.alidns.com/resolve?',
};
const resolveDns = async (hostname, type, name, server) => {
const resolver = new Resolver();
resolver.setServers([server]);
const resolve4Async = promisify(resolver.resolve4.bind(resolver));
const resolve6Async = promisify(resolver.resolve6.bind(resolver));
const resolveTxtAsync = promisify(resolver.resolveTxt.bind(resolver));
const resolveCnameAsync = promisify(resolver.resolveCname.bind(resolver));
const resolveNSAsync = promisify(resolver.resolveNs.bind(resolver));
const resolveMXAsync = promisify(resolver.resolveMx.bind(resolver));
try {
let addresses;
// 根据传入的 type 参数选择不同的解析方法
switch (type) {
case 'A':
addresses = await resolve4Async(hostname);
break;
case 'AAAA':
addresses = await resolve6Async(hostname);
break;
case 'TXT':
addresses = await resolveTxtAsync(hostname);
// TXT 记录解析的结果是一个二维数组,这里进行扁平化处理
addresses = addresses.flat();
break;
case 'CNAME':
addresses = await resolveCnameAsync(hostname);
break;
case 'NS':
addresses = await resolveNSAsync(hostname);
break;
case 'MX':
addresses = await resolveMXAsync(hostname);
addresses = addresses.map(item => `${item.priority} ${item.exchange}.`)
.join(', ');
break;
default:
throw new Error('Unsupported type');
}
if (addresses.length === 0 || addresses === '' || addresses === null) {
return { [name]: `N/A` };
}
return { [name]: addresses };
} catch (error) {
console.log(error.message);
return { [name]: `N/A` };
}
};
const resolveDoh = async (hostname, type, name, url) => {
try {
const response = await fetch(`${url}name=${hostname}&type=${type}`, {
headers: { 'Accept': 'application/dns-json' }
});
const data = await response.json();
const addresses = data.Answer ? data.Answer.map(answer => answer.data) : ['N/A'];
if (addresses.length === 0 || addresses === '' || addresses === null) {
return { [name]: `N/A` };
}
return { [name]: addresses };
} catch (error) {
console.log(error.message);
return { [name]: `N/A` };
}
};
const dnsResolver = async (req, res) => {
// 限制请求方法
if (req.method !== 'GET') {
return res.status(405).json({ message: 'Method Not Allowed' });
}
// 限制只能从指定域名访问
const referer = req.headers.referer;
if (!refererCheck(referer)) {
return res.status(403).json({ error: referer ? 'Access denied' : 'What are you doing?' });
}
const { hostname, type } = req.query;
if (typeof hostname !== 'string') {
return res.status(400).send({ error: 'Hostname parameter must be a string' });
}
if (!hostname) {
return res.status(400).send({ error: 'Missing hostname parameter' });
}
if (!hostname.includes('.')) {
return res.status(400).send({ error: 'Invalid hostname' });
}
const dnsPromises = Object.entries(dnsServers).map(([name, ip]) => resolveDns(hostname, type, name, ip));
const dohPromises = Object.entries(dohServers).map(([name, url]) => resolveDoh(hostname, type, name, url));
try {
// 并行执行所有 DNS 和 DoH 查询
const result_dns = await Promise.all(dnsPromises);
const result_doh = await Promise.all(dohPromises);
res.json({
hostname,
result_dns,
result_doh
});
} catch (error) {
res.status(500).send({ error: error.message });
}
};
export default dnsResolver;