81 lines
2.2 KiB
JavaScript
81 lines
2.2 KiB
JavaScript
import dgram from 'dgram';
|
||
import dnsPacket from 'dns-packet';
|
||
import { records } from './dns-records.js';
|
||
|
||
const server = dgram.createSocket('udp4');
|
||
const PORT = 53;
|
||
|
||
server.on('error', (err) => {
|
||
console.error(`服务器异常:\n${err.stack}`);
|
||
server.close();
|
||
});
|
||
|
||
server.on('message', (msg, rinfo) => {
|
||
console.log(`收到来自 ${rinfo.address}:${rinfo.port} 的DNS查询`);
|
||
|
||
const request = dnsPacket.decode(msg);
|
||
// 确保至少有一个问题
|
||
if (!request.questions || request.questions.length === 0) {
|
||
return;
|
||
}
|
||
const question = request.questions[0];
|
||
|
||
console.log(`查询的域名: ${question.name}, 类型: ${question.type}`);
|
||
|
||
// 只处理 A 记录查询 (IPv4)
|
||
if (question.type !== 'A') {
|
||
// 对于非A记录查询,可以不响应或发送适当的错误
|
||
return;
|
||
}
|
||
|
||
const domain = question.name;
|
||
const ip = records[domain];
|
||
|
||
let response;
|
||
|
||
if (ip) {
|
||
console.log(`为 ${domain} 找到IP: ${ip}`);
|
||
response = dnsPacket.encode({
|
||
type: 'response',
|
||
id: request.id,
|
||
flags: dnsPacket.AUTHORITATIVE_ANSWER,
|
||
questions: request.questions,
|
||
answers: [{
|
||
type: 'A',
|
||
class: 'IN',
|
||
name: domain,
|
||
ttl: 300, // Time-to-live
|
||
data: ip,
|
||
}],
|
||
});
|
||
} else {
|
||
console.log(`未找到域名 ${domain} 的记录`);
|
||
response = dnsPacket.encode({
|
||
type: 'response',
|
||
id: request.id,
|
||
flags: dnsPacket.AUTHORITATIVE_ANSWER | dnsPacket.RECURSION_AVAILABLE,
|
||
questions: request.questions,
|
||
rcode: 'NXDOMAIN' // Non-Existent Domain
|
||
});
|
||
}
|
||
|
||
server.send(response, rinfo.port, rinfo.address, (err) => {
|
||
if (err) {
|
||
console.error('发送响应失败:', err);
|
||
} else {
|
||
console.log(`已向 ${rinfo.address}:${rinfo.port} 发送响应`);
|
||
}
|
||
});
|
||
});
|
||
|
||
server.on('listening', () => {
|
||
const address = server.address();
|
||
console.log(`DNS 服务器正在监听 ${address.address}:${address.port}`);
|
||
});
|
||
|
||
server.bind(PORT, () => {
|
||
// 在 Windows 上,可能需要管理员权限才能绑定到 53 端口
|
||
if (process.platform === 'win32') {
|
||
console.log('在 Windows 上运行,请确保您有管理员权限来绑定到53端口。');
|
||
}
|
||
});
|