Node.js与DNS域名解析dns模块介绍

 2015年08月19日    2346     声明


DNS(Domain Name System,域名系统),DNS协议运行在UDP协议之上,使用端口号53。DNS是因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。简单的说,就是把域名(网址)解析成对应的IP地址。Node.js的dns模块,提供了DNS解析功能。当使用dns模块中的net.connect(80, 'itbilu.com')方法 或 http模块的http.get({ host: 'itbilu.com' })方法时,在其底层会使用dns模块中的dns.lookup 方法进行域名解析。

  1. dns模块的两种域名解析方式
  2. dns模块中的域名解析方法
  3. dns模块中的IP反查方法
  4. dns模块中的其它方法和错误码


1. dns模块的两种域名解析方式

dns模块中,对域名的解析有两种方式:1. 使用操作系统底层的DNS服务解析、2. 连接到DNS服务器解析域名

使用操作系统底层的DNS服务解析:进行域名解析时,不需要连接到网络仅使用系统自带DNS解析功能。这个功能由 dns.lookup()方法实现。

使用dns.lookup()方法解析itbilu.com

var dns = require('dns');

dns.lookup('itbilu.com', function (err, addresses, family) {
    console.log('IP地址:%s,协议版本:%s', addresses, family);
});
//IP地址:115.28.135.70,协议版本:4

连接到DNS服务器解析域名:dns模块中,除 dns.lookup()方法外都是使用DNS服务器进行域名解析,解析时需要连接到网络。

使用dns.resolve4()方法解析itbilu.com

dns.resolve4('www.itbilu.com', function (err, addresses) {
    if (err) throw err;
    console.log('IP地址:: ' + JSON.stringify(addresses));
});
//IP地址:: ["115.28.135.70"]


2. dns模块中的域名解析方法

2.1 dns.lookup(hostname[, options], callback):将一个域名(如:'itbilu.com.com')解析为第一个找到的 A 记录(IPv4)或 AAAA 记录(IPv6)

hostname表示要解析的域名。

options可以是一个对象或整数。如果没有提供options参数,则IP v4 和 v6 地址都可以。如果 options 是整数,则必须是 46。如果 options 是对象时,会包含以下两个可选参数:

  • family:可选,IP版本。如果提供,必须是 46。不提供则,IP v4 和 v6 地址都可以
  • hints:可选。如果提供,可以是一个或者多个 getaddrinfo 标志。若不提供,则没有标志会传给 getaddrinfo

callback回调函数,参数包含(err, address, family)。出错时,参数 errError 对象。address参数表示 IP v4 或 v6 地址。family 参数是4 或 6,表示 address协议版本。


2.2 dns.resolve(hostname[, rrtype], callback):将一个域名(如 'itbilu.com.com')解析为一个rrtype指定类型的数组

hostname表示要解析的域名。

rrtype有以下可用值:

  • 'A':IPv4 地址,缺省
  • 'AAAA':IPv4 地址
  • 'MX':邮件交换记录
  • 'TXT':text 文本记录
  • 'SRV':SRV 记录
  • 'PTR':反向 IP 查找
  • 'NS':域名服务器记录
  • 'CNAME':别名记录
  • 'SOA':授权记录的初始值

callback回调函数,参数包含(err, addresses)。出错时,参数 errError 对象。addresses根据记录类型的不同返回值也不同。

除使用dns.resolve()进行DNS解析外,dns模块还提供了几个快捷方法,它们只按某一种有效rrtype类型进行解析。


2.3 dns.resolve4(hostname, callback):查询域名的IPv4记录,即:A记录

hostname表示要解析的域名。

callback回调函数,参数包含(err, addresses)。出错时,参数 errError 对象。addresses为IPv4地址数组,如:['74.125.79.104', '74.125.79.105', '74.125.79.106']


2.4 dns.resolve6(hostname, callback):查询域名的IPv6记录,即:AAAA记录

hostname表示要解析的域名。

callback回调函数,参数包含(err, addresses)。出错时,参数 errError 对象。addresses为IPv6地址数组,如:['2404:6800:4005:80b::2004']


2.5 dns.resolveMx(hostname, callback):查询邮件交换记录,即:MX记录

hostname表示要解析的域名。

callback回调函数,参数包含(err, addresses)。出错时,参数 errError 对象。addresses是MX记录数组, 每一项包含优先级和交换属性,如:[{'priority': 10, 'exchange': 'mx.example.com'},...]


2.6 dns.resolveTxt(hostname, callback):查询文本记录,即:TXT记录

hostname表示要解析的域名。

callback回调函数,参数包含(err, addresses)。出错时,参数 errError 对象。addressesdomain 可用文本记录的数组,如:['v=spf1 ip4:0.0.0.0 ~all']


2.7 dns.resolveSrv(domain, callback):仅能进行服务记录查询,即:SRV记录

hostname表示要解析的域名。

callback回调函数,参数包含(err, addresses)。出错时,参数 errError 对象。addresseshostname可用的 SRV 记录数组。 SRV记录属性有:优先级(priority)、权重(weight)、端口(port)、名称(name)。如:[{'priority': 10, 'weight': 5, 'port': 21223, 'name': 'service.example.com'}, ...]


2.8 dns.resolveSoa(hostname, callback):查询授权记录,即:SOA记录

hostname表示要解析的域名。

callback回调函数,参数包含(err, addresses)。出错时,参数 errError 对象。addresses是一个包含以下属性的对象:

{
    nsname: 'ns.example.com',
    hostmaster: 'root.example.com',
    serial: 2013101809,
    refresh: 10000,
    retry: 2400,
    expire: 604800,
    minttl: 3600
}


2.9 dns.resolveNs(hostname, callback):查询域名服务器查询,即:NS记录

hostname表示要解析的域名。

callback回调函数,参数包含(err, addresses)。出错时,参数 errError 对象。addresses是域名服务器记录数组。如:['ns1.example.com', 'ns2.example.com']


2.10 dns.resolveCname(hostname, callback):查询别名记录,即:CNAME记录

hostname表示要解析的域名。

callback回调函数,参数包含(err, addresses)。出错时,参数 errError 对象。addresses是域名可用的别名记录数组 。如:['bar.example.com']


3. dns模块中的IP反查方法

3.1 dns.lookupService(address, port, callback):使用getnameinfo方法将传入的地址和端口解析为域名和服务

address表示要解析的IP地址字符串。

port表示要解析的端口号。

callback回调函数,参数包含(err, hostname, service)。出错时,参数 errError 对象。hostnameservice 都是字符串 (比如 'localhost''http')。

var dns = require('dns');

dns.lookupService('127.0.0.1', 80, function(err, hostname, service){
    if (err) throw err;
    console.log('主机名:%s,服务类型:%s', hostname, service);
})
//主机名:localhost,服务类型:http


3.2 dns.reverse(ip, callback):反向解析IP地址,返回指向该 IP 地址的域名数组

ip表示要反向解析的IP地址。

callback回调函数,参数包含(err, domains)。出错时,参数 errError 对象。domains解析后的域名数组。


4. 模块中的其它方法和错误码

4.1 DNS服务器设置与获取

dns.getServers():获取用于解析的 IP 地址的字符串数组,即:获取DNS服务器地址

dns.setServers(servers):设置用于解析的 IP 地址的字符串数组,即:设置DNS服务器地址

var dns = require('dns');

var ips = dns.getServers();
console.log('当前DNS服务器:', JSON.stringify(ips));  //当前DNS服务器: ["192.168.1.1"]

//重新设置DNS服务器IP
dns.setServers(['8.8.4.4']);
var newIps = dns.getServers();
console.log('设置后DNS服务器:', JSON.stringify(newIps)); //设置后DNS服务器: ["8.8.4.4"]


4.3 dns模块可能出现的错误

dns模块进行域名解析或DNS查询时,可能会出现以下错误:

  • dns.NODATA:DNS服务器返回无数据应答。
  • dns.FORMERR:DNS服务器查返回询格式错误。
  • dns.SERVFAIL:DNS服务器返回一般失败。
  • dns.NOTFOUND:域名未找到。
  • dns.NOTIMP:DNS服务器未实现请求的操作。
  • dns.REFUSED:DNS服务器拒绝查询。
  • dns.BADQUERY:DNS查询格式错误。
  • dns.BADNAME:域名格式错误。
  • dns.BADFAMILY:地址协议不支持。
  • dns.BADRESP:DNS回复格式错误。
  • dns.CONNREFUSED:无法连接到DNS服务器。
  • dns.TIMEOUT:连接DNS服务器超时。
  • dns.EOF:文件末端。
  • dns.FILE:读文件错误。
  • dns.NOMEM:内存溢出。
  • dns.DESTRUCTION:通道被摧毁。
  • dns.BADSTR:字符串格式错误。
  • dns.BADFLAGS:非法标识符。
  • dns.NONAME:所给主机不是数字。
  • dns.BADHINTS:非法HINTS标识符。
  • dns.NOTINITIALIZED:c-ares 库尚未初始化。
  • dns.LOADIPHLPAPI:加载 iphlpapi.dll 出错。
  • dns.ADDRGETNETWORKPARAMS:无法找到 GetNetworkParams 函数。
  • dns.CANCELLED:取消 DNS 查询。