first commit
This commit is contained in:
commit
6a467ca16c
58
.gitignore
vendored
Normal file
58
.gitignore
vendored
Normal 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
6
dns-records.js
Normal 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
81
index.js
Normal 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
34
package-lock.json
generated
Normal 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
17
package.json
Normal 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"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user