node下dns服务搭建

node下dns服务搭建


直接上码:

// https://github.com/hello/dns-server

// The regular expression keyword in domain name.
const domain = /hello/
// When keyword matched, resolve to this IP.
const targetIp = '127.0.0.1'
// When keyword not matched, use the fallback dns server to resolve.
const fallbackServer = '114.114.114.114'

const dgram = require('dgram')

const server = dgram.createSocket('udp4')

function copyBuffer(src, offset, dst) {
 for (let i = 0; i < src.length; ++i) {
   dst.writeUInt8(src.readUInt8(i), offset + i)
 }
}

function resolve(msg, rinfo) {
 const queryInfo = msg.slice(12)
 const response = Buffer.alloc(28 + queryInfo.length)
 let offset = 0
 const id = msg.slice(0, 2)
 copyBuffer(id, 0, response)  // Transaction ID
 offset += id.length
 response.writeUInt16BE(0x8180, offset)  // Flags
 offset += 2
 response.writeUInt16BE(1, offset)  // Questions
 offset += 2
 response.writeUInt16BE(1, offset)  // Answer RRs
 offset += 2
 response.writeUInt32BE(0, offset)  // Authority RRs & Additional RRs
 offset += 4
 copyBuffer(queryInfo, offset, response)
 offset += queryInfo.length
 response.writeUInt16BE(0xC00C, offset)  // offset to domain name
 offset += 2
 const typeAndClass = msg.slice(msg.length - 4)
 copyBuffer(typeAndClass, offset, response)
 offset += typeAndClass.length
 response.writeUInt32BE(600, offset)  // TTL, in seconds
 offset += 4
 response.writeUInt16BE(4, offset)  // Length of IP
 offset += 2
 targetIp.split('.').forEach(value => {
   response.writeUInt8(parseInt(value), offset)
   offset += 1
 })
 // console.log(response.toString('hex'))
 server.send(response, rinfo.port, rinfo.address, (err) => {
   if (err) {
     console.log(err)
     server.close()
   }
 })
}

function forward(msg, rinfo) {
 const client = dgram.createSocket('udp4')
 client.on('error', (err) => {
   console.log(`client error:\n${err.stack}`)
   client.close()
 })
 client.on('message', (fbMsg, fbRinfo) => {
   server.send(fbMsg, rinfo.port, rinfo.address, (err) => {
     err && console.log(err)
   })
   client.close()
 })
 client.send(msg, 53, fallbackServer, (err) => {
   if (err) {
     console.log(err)
     client.close()
   }
 })
}

function parseHost(msg) {
 let num = msg.readUInt8(0)
 let offset = 1
 let host = ""
 while (num !== 0) {
   host += msg.slice(offset, offset + num).toString()
   offset += num
   num = msg.readUInt8(offset)
   offset += 1
   if (num !== 0) {
     host += '.'
   }
 }
 return host
}

server.on('message', (msg, rinfo) => {
 // console.log(msg.toString('hex'))
 const host = parseHost(msg.slice(12))
 console.log(`receive query: ${host}`)
 if (domain.test(host)) {
   resolve(msg, rinfo)
 } else {
   forward(msg, rinfo)
 }
})

server.on('error', (err) => {
 console.log(`server error:\n${err.stack}`)
 server.close()
})

server.on('listening', () => {
 const address = server.address()
 console.log(`server listening ${address.address}:${address.port}`)
})

// On linux or Mac, run node with sudo. Because port 53 is lower then 1024.
server.bind(53)
node index

搞定!

但是53端口可能会被占用,如何排查:

  1. 定位被谁使用
netstat -ano|findstr 53

在这里插入图片描述
后面数字是 进程id

  1. 定位是那个应用服务
    在这里插入图片描述
    关闭进程或服务即可

有些服务如svchost.exe,它是 dns client 服务,需要进入到 services.msc 停用 dns client 服务, 个别电脑会是灰色的导致,无法禁用,这时需要进入注册表 regedit,编辑如下项目:
计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Dnscache
修改 start 值
在这里插入图片描述
2为自动,3为手动,4为禁用

参考:https://www.zhihu.com/question/264016881
https://blog.csdn.net/hursing/article/details/81236290

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值