custom-dns/index.js
2025-07-12 20:00:16 +08:00

81 lines
2.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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端口。');
}
});