DNS
Модуль dns содержит функции, относящиеся к двум различным категориям:
1) Функции, использующие ресурсы операционной системы для выполнения разрешения имен и не обязательно выполняющие сетевое взаимодействие. Эта категория содержит только одну функцию: dns.lookup(). Разработчики, стремящиеся выполнить разрешение имен так же, как и другие приложения в той же операционной системе, должны использовать dns.lookup().
Например, поиск iana.org.
const dns = require('dns');
dns.lookup('iana.org', (err, address, family) => {
console.log('address: %j family: IPv%s', address, family);
});
// address: "192.0.43.8" family: IPv4
2) Функции, подключающиеся к фактическому серверу DNS для выполнения разрешения имен и всегда использующие сеть для выполнения запросов DNS. Эта категория содержит все функции в модуле dns кроме dns.lookup(). Эти функции не используют тот же набор конфигурационных файлов, что и dns.lookup() (например, /etc/hosts). Эти функции должны использоваться разработчиками, которые не хотят использовать средства операционной системы для разрешения имен и вместо этого всегда хотят выполнять запросы DNS.
Ниже приведён пример, в котором выполняется разрешение 'archive.org', а затем обратное разрешение возвращённых IP-адресов.
const dns = require('dns');
dns.resolve4('archive.org', (err, addresses) => {
if (err) throw err;
console.log(`addresses: ${JSON.stringify(addresses)}`);
addresses.forEach((a) => {
dns.reverse(a, (err, hostnames) => {
if (err) {
throw err;
}
console.log(`reverse for ${a}: ${JSON.stringify(hostnames)}`);
});
});
});
Существуют тонкие последствия при выборе одного из них над другим; для получения дополнительной информации см. раздел Общие соображения по реализации.
Класс dns.Resolver
Независимый решатель для запросов DNS.
Обратите внимание, что создание нового решателя использует параметры сервера по умолчанию. Настройка серверов, используемых для решателя с помощью resolver.setServers(), не влияет на другие решатели:
const { Resolver } = require('dns');
const resolver = new Resolver();
resolver.setServers(['4.4.4.4']);
// This request will use the server at 4.4.4.4, independent of global settings.
resolver.resolve4('example.org', (err, addresses) => {
// ...
});
Доступны следующие методы из модуля dns:
resolver.getServers()resolver.setServers()resolver.resolve()resolver.resolve4()resolver.resolve6()resolver.resolveAny()resolver.resolveCname()resolver.resolveMx()resolver.resolveNaptr()resolver.resolveNs()resolver.resolvePtr()resolver.resolveSoa()resolver.resolveSrv()resolver.resolveTxt()resolver.reverse()
resolver.cancel()
Отменить все активные запросы DNS, выполненные этим решателем. Соответствующие обратные вызовы будут вызваны с ошибкой с кодом ECANCELLED.
dns.getServers()
Возвращает массив строк IP-адресов, отформатированных в соответствии с rfc5952, которые в настоящее время настроены для разрешения DNS. Строка будет содержать раздел порта, если используется пользовательский порт.
Например:
[ '4.4.4.4', '2001:4860:4860::8888', '4.4.4.4:1053', '[2001:4860:4860::8888]:1053' ]
dns.lookup(hostname[, options], callback)
-
hostname<строка> -
options<целое число> | <объект>-
family<целое число> Семейство записей. Должно быть4или6. IPv4 и IPv6 адреса возвращаются по умолчанию. -
hints<число> Один или несколько поддерживаемыхgetaddrinfoфлагов. Несколько флагов могут быть переданы с помощью поразрядногоORсоединения их значений. -
all<логическое значение> Еслиtrue, обратный вызов возвращает все разрешённые адреса в массиве. В противном случае возвращает один адрес. По умолчанию:false. -
verbatim<логическое значение> Еслиtrue, обратный вызов получает адреса IPv4 и IPv6 в том порядке, в котором их вернул DNS-решатель. Еслиfalse, адреса IPv4 размещаются перед адресами IPv6. По умолчанию: в настоящее времяfalse(адреса переупорядочиваются), но ожидается, что это изменится в ближайшем будущем. Новый код должен использовать{ verbatim: true }.
-
-
callback<Функция>-
err<Ошибка> -
address<строка> Строковое представление адреса IPv4 или IPv6. -
family<целое число>4или6, обозначающие семействоaddress.
-
Разрешает имя хоста (например, 'nodejs.org') в первую найденную запись A (IPv4) или AAAA (IPv6). Все option свойства необязательны. Если options является целым числом, то оно должно быть 4 или 6 – если options не предоставлено, то адреса IPv4 и IPv6 возвращаются, если они найдены.
При установке параметра all в значение true, аргументы для callback изменяются на (err, addresses), при этом addresses является массивом объектов со свойствами address и family.
При ошибке err является объектом Error, где err.code — код ошибки. Имейте в виду, что err.code будет установлено в 'ENOENT' не только в случае отсутствия имени хоста, но и в случае других сбоев в поиске, таких как отсутствие доступных дескрипторов файлов.
dns.lookup() не обязательно имеет отношение к протоколу DNS. Реализация использует средство операционной системы, которое может связывать имена с адресами и наоборот. Эта реализация может иметь тонкие, но важные последствия для поведения любой программы Node.js. Пожалуйста, уделите время, чтобы ознакомиться с разделом Общие соображения по реализации перед использованием dns.lookup().
Пример использования:
const dns = require('dns');
const options = {
family: 6,
hints: dns.ADDRCONFIG | dns.V4MAPPED,
};
dns.lookup('example.com', options, (err, address, family) =>
console.log('address: %j family: IPv%s', address, family));
// address: "2606:2800:220:1:248:1893:25c8:1946" family: IPv6
// When options.all is true, the result will be an Array.
options.all = true;
dns.lookup('example.com', options, (err, addresses) =>
console.log('addresses: %j', addresses));
// addresses: [{"address":"2606:2800:220:1:248:1893:25c8:1946","family":6}]
Если этот метод вызывается как его util.promisify() версия, и all не установлено в true, она возвращает обещание объекта со свойствами address и family.
Поддерживаемые флаги getaddrinfo
Следующие флаги могут быть переданы в качестве подсказок для dns.lookup().
-
dns.ADDRCONFIG: Типы возвращаемых адресов определяются типами адресов, поддерживаемыми текущей системой. Например, адреса IPv4 возвращаются только в том случае, если текущая система имеет хотя бы один настроенный адрес IPv4. Адреса обратной связи не учитываются. -
dns.V4MAPPED: Если семейство IPv6 было указано, но адресов IPv6 не найдено, то возвращаются адреса IPv4, сопоставленные с IPv6. Обратите внимание, что это не поддерживается на некоторых операционных системах (например, FreeBSD 10.1).
dns.lookupService(address, port, callback)
Разрешает заданный address и port в имя хоста и службу, используя внутреннюю getnameinfo реализацию операционной системы.
Если address не является корректным IP-адресом, будет выброшено исключение TypeError. port будет приведено к числу. Если это не допустимый порт, будет выброшено исключение TypeError.
При ошибке, err — это объект Error, где err.code — код ошибки.
const dns = require('dns');
dns.lookupService('127.0.0.1', 22, (err, hostname, service) => {
console.log(hostname, service);
// Prints: localhost ssh
});
Если этот метод вызывается как его util.promisify() версия, он возвращает промис для объекта с hostname и service свойствами.
dns.resolve(hostname[, rrtype], callback)
-
hostname<строка> Имя хоста для разрешения. -
rrtype<строка> Тип записи ресурса. По умолчанию:'A'. -
callback<Функция>-
err<Ошибка> -
records<массив строк> | <массив объектов> | <объект>
-
Использует протокол DNS для разрешения имени хоста (например, 'nodejs.org') в массив записей ресурса. Функция callback имеет аргументы (err, records). При успешном выполнении records будет массивом записей ресурса. Тип и структура отдельных результатов зависят от rrtype:
rrtype |
records содержит | Тип результата | Сокращённый метод |
|---|---|---|---|
'A' | IPv4 адреса (по умолчанию) | <строка> | dns.resolve4() |
'AAAA' | IPv6 адреса | <строка> | dns.resolve6() |
'CNAME' | записи канонического имени | <строка> | dns.resolveCname() |
'MX' | записи обмена почтой | <объект> | dns.resolveMx() |
'NAPTR' | записи указателя имени власти | <объект> | dns.resolveNaptr() |
'NS' | записи сервера имён | <строка> | dns.resolveNs() |
'PTR' | записи указателя | <строка> | dns.resolvePtr() |
'SOA' | записи начала власти | <объект> | dns.resolveSoa() |
'SRV' | записи сервиса | <объект> | dns.resolveSrv() |
'TXT' | текстовые записи | <массив строк> | dns.resolveTxt() |
'ANY' | любые записи | <объект> | dns.resolveAny() |
При ошибке, err — это объект Error, где err.code — один из кодов ошибок DNS.
dns.resolve4(hostname[, options], callback)
-
hostname<строка> Имя хоста для разрешения. -
options<объект>-
ttl<булево> Получить значение Time-To-Live (TTL) каждой записи. Когдаtrue, обратный вызов получает массив{ address: '1.2.3.4', ttl: 60 }объектов, а не массив строк, причём TTL выражается в секундах.
-
-
callback<Функция>-
err<Ошибка> -
addresses<массив строк> | <массив объектов>
-
Использует протокол DNS для разрешения IPv4 адресов (A записи) для hostname. Аргумент addresses переданный функции callback будет содержать массив IPv4 адресов (например, ['74.125.79.104', '74.125.79.105', '74.125.79.106']).
dns.resolve6(hostname[, options], callback)
-
hostname<строка> Имя хоста для разрешения. -
options<объект>-
ttl<булево> Получить значение Time-To-Live (TTL) каждой записи. Когдаtrue, обратный вызов получает массив{ address: '0:1:2:3:4:5:6:7', ttl: 60 }объектов, а не массив строк, причём TTL выражается в секундах.
-
-
callback<Функция>-
err<Ошибка> -
addresses<массив строк> | <массив объектов>
-
Использует протокол DNS для разрешения IPv6 адресов (AAAA записи) для hostname. Аргумент addresses переданный функции callback будет содержать массив IPv6 адресов.
dns.resolveCname(hostname, callback)
-
hostname<строка> -
callback<Функция>-
err<Ошибка> -
addresses<массив строк>
-
Использует протокол DNS для разрешения CNAME записей для hostname. Аргумент addresses переданный функции callback будет содержать массив записей канонического имени, доступных для hostname (например, ['bar.example.com']).
dns.resolveMx(hostname, callback)
-
hostname<строка> -
callback<Функция>-
err<Ошибка> -
addresses<Массив объектов>
-
Использует протокол DNS для разрешения записей MX (записи обмена почтой) для MX. Аргумент addresses, переданный функции callback, будет содержать массив объектов, содержащих как свойство priority, так и свойство exchange (например, [{priority: 10, exchange: 'mx.example.com'}, ...]).
dns.resolveNaptr(hostname, callback)
-
hostname<строка> -
callback<Функция>-
err<Ошибка> -
addresses<Массив объектов>
-
Использует протокол DNS для разрешения записей, основанных на регулярных выражениях (записи NAPTR) для hostname. Аргумент addresses, переданный функции callback, будет содержать массив объектов со следующими свойствами:
flagsserviceregexpreplacementorderpreference
Например:
{
flags: 's',
service: 'SIP+D2U',
regexp: '',
replacement: '_sip._udp.example.com',
order: 30,
preference: 100
}
dns.resolveNs(hostname, callback)
-
hostname<строка> -
callback<Функция>-
err<Ошибка> -
addresses<массив строк>
-
Использует протокол DNS для разрешения записей сервера имен (NS записей) для hostname. Аргумент addresses, переданный функции callback, будет содержать массив записей сервера имен, доступных для hostname (например, ['ns1.example.com', 'ns2.example.com']).
dns.resolvePtr(hostname, callback)
-
hostname<строка> -
callback<Функция>-
err<Ошибка> -
addresses<массив строк>
-
Использует протокол DNS для разрешения записей указателей (PTR записей) для hostname. Аргумент addresses, переданный функции callback, будет массивом строк, содержащих ответные записи.
dns.resolveSoa(hostname, callback)
Использует протокол DNS для разрешения записи начала зоны ответственности (SOA записи) для hostname. Аргумент address, переданный функции callback, будет объектом со следующими свойствами:
nsnamehostmasterserialrefreshretryexpireminttl
{
nsname: 'ns.example.com',
hostmaster: 'root.example.com',
serial: 2013101809,
refresh: 10000,
retry: 2400,
expire: 604800,
minttl: 3600
}
dns.resolveSrv(hostname, callback)
-
hostname<строка> -
callback<Функция>-
err<Ошибка> -
addresses<Массив объектов>
-
Использует протокол DNS для разрешения записей служб (SRV записей) для hostname. Аргумент addresses, переданный функции callback, будет массивом объектов со следующими свойствами:
priorityweightportname
{
priority: 10,
weight: 5,
port: 21223,
name: 'service.example.com'
}
dns.resolveTxt(hostname, callback)
-
hostname<строка> -
callback<Функция>-
err<Ошибка> -
records<двумерный массив строк>
-
Использует протокол DNS для разрешения текстовых запросов (TXT записей) для hostname. Аргумент records, переданный функции callback, является двумерным массивом текстовых записей, доступных для hostname (например, [ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]). Каждый подмассив содержит TXT-фрагменты одной записи. В зависимости от использования, их можно объединить или обработать по отдельности.
dns.resolveAny(hostname, callback)
-
hostname<строка> -
callback<Функция>-
err<Ошибка> -
ret<Массив объектов>
-
Использует протокол DNS для разрешения всех записей (также известный как ANY или * запрос). Аргумент ret, переданный функции callback, будет массивом, содержащим различные типы записей. Каждый объект имеет свойство type, указывающее тип текущей записи. В зависимости от type, дополнительные свойства будут присутствовать в объекте:
| Тип | Свойства |
|---|---|
'A' |
address / ttl
|
'AAAA' |
address / ttl
|
'CNAME' | value |
'MX' | См. dns.resolveMx()
|
'NAPTR' | См. dns.resolveNaptr()
|
'NS' | value |
'PTR' | value |
'SOA' | См. dns.resolveSoa()
|
'SRV' | См. dns.resolveSrv()
|
'TXT' | Этот тип записи содержит массив свойств под названием entries, который ссылается на dns.resolveTxt(), например { entries: ['...'], type: 'TXT' }
|
Вот пример объекта ret , переданного в обратный вызов:
[ { type: 'A', address: '127.0.0.1', ttl: 299 },
{ type: 'CNAME', value: 'example.com' },
{ type: 'MX', exchange: 'alt4.aspmx.l.example.com', priority: 50 },
{ type: 'NS', value: 'ns1.example.com' },
{ type: 'TXT', entries: [ 'v=spf1 include:_spf.example.com ~all' ] },
{ type: 'SOA',
nsname: 'ns1.example.com',
hostmaster: 'admin.example.com',
serial: 156696742,
refresh: 900,
retry: 900,
expire: 1800,
minttl: 60 } ]
dns.reverse(ip, callback)
-
ip<string> -
callback<Function>-
err<Error> -
hostnames<string[]>
-
Выполняет обратный DNS-запрос, который преобразует IPv4 или IPv6 адрес в массив имён хостов.
При ошибке, err является объектом Error, где err.code — один из кодов ошибок DNS.
dns.setServers(servers)
-
servers<string[]> массив адресов в формате rfc5952
Устанавливает IP-адрес и порт серверов, которые будут использоваться при выполнении разрешения DNS. Аргумент servers — массив адресов в формате rfc5952. Если порт является стандартным портом DNS (53), его можно опустить.
Например:
dns.setServers([ '4.4.4.4', '[2001:4860:4860::8888]', '4.4.4.4:1053', '[2001:4860:4860::8888]:1053' ]);
Будет выброшено исключение, если предоставлен неверный адрес.
Метод dns.setServers() не должен вызываться во время выполнения запроса 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: Указаны недопустимые флаги подсказок. -
dns.NOTINITIALIZED: Инициализация библиотеки c-ares ещё не выполнена. -
dns.LOADIPHLPAPI: Ошибка при загрузке iphlpapi.dll. -
dns.ADDRGETNETWORKPARAMS: Не удалось найти функцию GetNetworkParams. -
dns.CANCELLED: Запрос DNS отменён.
Особенности реализации
Хотя dns.lookup() и различные функции dns.resolve*()/dns.reverse() преследуют одну и ту же цель — сопоставление имени сети с сетевым адресом (или наоборот), их поведение значительно отличается. Эти различия могут иметь тонкие, но значительные последствия для поведения программ Node.js.
dns.lookup()
Внутри dns.lookup() используются те же средства операционной системы, что и в большинстве других программ. Например, dns.lookup() почти всегда разрешает данное имя таким же образом, как команда ping. На большинстве операционных систем семейства POSIX поведение функции dns.lookup() может быть изменено путём изменения настроек в файле nsswitch.conf(5) и/или resolv.conf(5), но обратите внимание, что изменение этих файлов изменит поведение всех других программ, работающих в той же операционной системе.
Хотя вызов dns.lookup() асинхронный с точки зрения JavaScript, он реализован как синхронный вызов getaddrinfo(3), который выполняется в пуле потоков libuv. Это может иметь неожиданно негативные последствия для производительности некоторых приложений, см. документацию UV_THREADPOOL_SIZE для получения дополнительной информации.
Обратите внимание, что различные сетевые API будут внутри себя вызывать dns.lookup() для разрешения имён хостов. Если это проблема, рассмотрите возможность преобразования имени хоста в адрес с помощью dns.resolve() и использование адреса вместо имени хоста. Также некоторые сетевые API (например, socket.connect() и dgram.createSocket()) позволяют заменить стандартный разрешитель, dns.lookup().
dns.resolve(), dns.resolve*() и dns.reverse()
Эти функции реализованы совсем по-другому, чем dns.lookup(). Они не используют getaddrinfo(3) и всегда выполняют запрос DNS в сети. Это сетевое взаимодействие всегда выполняется асинхронно и не использует пул потоков libuv.
В результате, эти функции не могут иметь такого же негативного влияния на другие процессы, выполняющиеся в пуле потоков libuv, как dns.lookup().
Они не используют тот же набор конфигурационных файлов, что и dns.lookup(). Например, они не используют конфигурацию из /etc/hosts.
© Joyent, Inc. and other Node contributors
Licensed under the MIT License.
Node.js is a trademark of Joyent, Inc. and is used with its permission.
We are not endorsed by or affiliated with Joyent.
https://nodejs.org/dist/latest-v8.x/docs/api/dns.html