first commit

This commit is contained in:
nie 2025-07-12 20:00:16 +08:00
commit 6a467ca16c
5 changed files with 196 additions and 0 deletions

58
.gitignore vendored Normal file
View File

@ -0,0 +1,58 @@
# Logs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules
jspm_packages
# Optional npm cache directory
.npm
# Optional REPL history
.node_repl_history
# 0x
profile-*
# mac files
.DS_Store
# vim swap files
*.swp
# webstorm
.idea
# vscode
.vscode
*code-workspace
# clinic
profile*
*clinic*
*flamegraph*

6
dns-records.js Normal file
View File

@ -0,0 +1,6 @@
export const records = {
'my-pc.local': '192.168.1.100',
'nas.local': '192.168.1.101',
'dev.server.local': '127.0.0.1',
'test.com': '1.2.3.4',
};

81
index.js Normal file
View File

@ -0,0 +1,81 @@
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端口。');
}
});

34
package-lock.json generated Normal file
View File

@ -0,0 +1,34 @@
{
"name": "custom-dns",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "custom-dns",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"dns-packet": "^5.6.1"
}
},
"node_modules/@leichtgewicht/ip-codec": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz",
"integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==",
"license": "MIT"
},
"node_modules/dns-packet": {
"version": "5.6.1",
"resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz",
"integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==",
"license": "MIT",
"dependencies": {
"@leichtgewicht/ip-codec": "^2.0.1"
},
"engines": {
"node": ">=6"
}
}
}
}

17
package.json Normal file
View File

@ -0,0 +1,17 @@
{
"name": "custom-dns",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"dns-packet": "^5.6.1"
}
}