風雲 (ID: 3)
头衔:论坛版主
等级:大天使
积分:2030
发帖:84 篇
来自:保密
注册:2022/3/30 15:28:53
造访:2026/9/19 15:59:39
[ 第 1 楼 ]
回复
人人都是 DNS 服务器 😀,先来个基础版(需要 npm i multicast-dns):
var MDns = require("multicast-dns");
var dns = MDns();
var cfg = { "test.local": "127.3.4.5" };
dns.on("query", ({ questions: [ { name, type } ] }) => {
if(!cfg[name]) return;
if(type != "A") return;
dns.respond([ { name, type, data: cfg[name], ttl: 300 } ]);
});
当一个 IP 出现多个网站时,特别适合用这种方式广播别名,这样,就能用不同主机头访问不同网站了。

2026/9/19 16:07:00

IP:已设置保密
風雲 (ID: 3)
头衔:论坛版主
等级:大天使
积分:2030
发帖:84 篇
来自:保密
注册:2022/3/30 15:28:53
造访:2026/9/19 15:59:39
[ 第 2 楼 ]
回复
配置文件版,修改 mdns.json 即可,无需重启服务:
// mDNS 应答器: 从 mdns.json 加载 { "名字.local": "IPv4或IPv6" }
// 热加载: 每次查询入口懒校验(10 秒节流)
var fs = require("fs");
var Dns = require("multicast-dns");
var cfgFile = require("path").join(__dirname, "mdns.json");
var cfg = {};
function respond(record, rinfo) {
mdns.respond({ answers: [record] });
console.log("[" + (rinfo ? rinfo.address + ":" + rinfo.port : "?") + "] " + record.type + " " + record.name + " -> " + record.data);
}
// 加载配置
function loadCfg() {
try { parseJson(fs.readFileSync(cfgFile)); }
catch(err) { console.log("无法加载配置文件:" + err.message); }
}
// 解析配置
function parseJson(text) {
var json = JSON.parse(text);
var next = { A: {}, AAAA: {} };
for(var x in json) {
// 判断是否包含 : 来区分是 AAAA 还是 A 记录
var type = json[x].indexOf(":") < 0 ? "A" : "AAAA";
var name = x.toLowerCase();
next[type][name] = { name, type, data: json[x], ttl: 300 };
}
cfg.A = next.A; // 全部解析成功才整体替换, 避免半途出错配置残缺
cfg.AAAA = next.AAAA;
cfg.mtime = fs.statSync(cfgFile).mtime.getTime();
}
// 检查配置文件是否更新(自带 10 秒节流)
function recheck() {
var now = new Date;
if(now - cfg.lastCheck < 1e4) return;
cfg.lastCheck = now;
try {
var mtime = fs.statSync(cfgFile).mtime.getTime();
if(mtime != cfg.mtime) { cfg.mtime = mtime; loadCfg(); }
} catch(err) { console.log("检查配置文件失败:" + err.message); }
}
var mdns = Dns();
mdns.on("query", (q, rinfo) => {
if(!q.questions) return;
recheck(); // 放入口而不是 miss 分支: 否则改已有记录的 IP 永远不生效; 自带 10 秒节流不亏
q.questions.forEach(item => {
if(!item || !item.name) return;
var name = String(item.name).toLowerCase();
var data = (cfg[item.type] || {})[name];
// 未找到?可能是其他设备上存在, 也可能是配置刚更新过(上面的 recheck 已兜住)
if(data) respond(data, rinfo);
});
});
console.log("mDNS responder started, config=" + cfgFile);

2026/9/19 16:24:46

IP:已设置保密