8

Is there an equivalent function of nslookup in node.js?

Here's the execution result of nslookup command on my MacBook Pro:

> nslookup www.amagicshop.com.tw 8.8.8.8
Server:         8.8.8.8
Address:        8.8.8.8#53

Non-authoritative answer:
www.amagicshop.com.tw   canonical name = s16959.dname.91app.io.
s16959.dname.91app.io   canonical name = proxy.letssl.91app.io.
proxy.letssl.91app.io   canonical name = proxy-letssl-91app-io-196811564.ap-northeast-1.elb.amazonaws.com.
Name:   proxy-letssl-91app-io-196811564.ap-northeast-1.elb.amazonaws.com
Address: 54.178.248.57
Name:   proxy-letssl-91app-io-196811564.ap-northeast-1.elb.amazonaws.com
Address: 52.196.80.17

I'm wondering if there is a function in node.js which, given www.amagicshop.com.tw, and 8.8.8.8 as input, also returns
s16959.dname.91app.io., proxy.letssl.91app.io., proxy-letssl-91app-io-196811564.ap-northeast-1.elb.amazonaws.com., 52.196.80.17, and 54.178.248.57 as output.

I originally thought that dns.resolveAny is an equivalent function of nslookup in node.js. But I was wrong.

Because the following code returns Error: queryAny ESERVFAIL www.amagicshop.com.tw error.

const { Resolver } = require('dns')
const resolver = new Resolver()
resolver.setServers(['8.8.8.8'])

resolver.resolveAny('www.amagicshop.com.tw', (err, result) => {
  if (err) {
    console.error(`error: ${err}`)
  } else {
    console.log(`result:  ${JSON.stringify(result)}`)
  }
})

The result is different from the result of nslookup.

Maybe I have to implement a function which combines resolveCname and resolve4 so that I can achieve what I want.

Brian
  • 12,145
  • 20
  • 90
  • 153

1 Answers1

6

In order to get all the canonical names we have to call recursively (in nslookup the definition is recursive as well!).

CNAME

const dns = require('dns')

let accum = []
const getCnames = (err, result) => {
  if (err) {
    // no more records
    console.log(accum)
    return accum
  } else {
    const cname = result[0]
    accum.push(cname)
    return dns.resolveCname(cname, getCnames)
  }
}

dns.resolveCname('www.amagicshop.com.tw', getCnames)

OUPUT

[ 's16959.dname.91app.io',
  'proxy.letssl.91app.io',
  'proxy-letssl-91app-io-196811564.ap-northeast-1.elb.amazonaws.com' ]

IP addresses

dns.resolve('www.amagicshop.com.tw', callback=(err, result) => {

if (err) {
    console.error(`error: ${err}`)
  } else {
    console.log(result)
  }
})

OUTPUT

[ '52.196.80.17', '54.178.248.57' ]

Combined

const dns = require('dns')

const resolve = (cname) => {
  const getIp = (accum) =>
    dns.resolve(cname,
      callback=(err, result) => {
        if (err) {
            console.error(`error: ${err}`)
          } else {
            result.push.apply(result, accum)
            console.log(result)
          }
      })

  let accum = []
  const getCnames = (err, result) => {
    if (err) {
      // no more records
      getIp(accum)
    } else {
      const cname = result[0]
      accum.push(cname)
      dns.resolveCname(cname, getCnames)
    }
  }

  dns.resolveCname(cname, getCnames)
}

resolve('www.amagicshop.com.tw')

OUTPUT

[ '52.196.80.17',
  '54.178.248.57',
  's16959.dname.91app.io',
  'proxy.letssl.91app.io',
  'proxy-letssl-91app-io-196811564.ap-northeast-1.elb.amazonaws.com' ]
Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
  • `lookup`'s output doesn't contain `s16959.dname.91app.io.`, `proxy.letssl.91app.io.`, and `proxy-letssl-91app-io-196811564.ap-northeast-1.elb.amazonaws.com.`. So it is not something I'm looking for. – Brian Nov 29 '17 at 03:54
  • `resolveCname` does not return `proxy.letssl.91app.io.`, `proxy-letssl-91app-io-196811564.ap-northeast-1.elb.amazonaws.com.`, `52.196.80.17`, and `54.178.248.57` in its output. – Brian Nov 29 '17 at 03:58
  • They are probably all available resolver methods from the DNS module - https://nodejs.org/api/dns.html – DaveStSomeWhere Nov 29 '17 at 03:59