
Быстрая библиотека и CLI-утилита для поиска DNS
ZDNS — это высокоскоростной DNS-резолвер и утилита командной строки для выполнения крупномасштабных DNS-измерений. ZDNS написан на Go и содержит собственный код рекурсивного разрешения и кэш, оптимизированный для выполнения запросов к разнообразному набору имен. Мы используем https://github.com/zmap/dns для создания и разбора сырых DNS-пакетов. Для получения дополнительной информации об архитектуре и производительности ZDNS ознакомьтесь со следующей статьей, представленной на конференции ACM Internet Measurement Conference '22.
[!TIP] ZDNS Wiki содержит дополнительную информацию о ZDNS, а также примеры использования и сценарии.
ZDNS можно установить, клонировав репозиторий и выполнив make install.
git clone https://github.com/zmap/zdns.git
cd zdns
make install
ZDNS состоит из библиотеки рекурсивного разрешителя и CLI-обертки.
Библиотека состоит из структуры ResolverConfig, которая содержит все параметры конфигурации для всех выполняемых запросов. ResolverConfig используется для создания одной или нескольких структур Resolver, которые будут выполнять все запросы. Resolver должен выполнять только один запрос за раз (он не является потокобезопасным), а для параллелизма следует использовать несколько структур Resolver. Смотрите наши примеры по использованию библиотеки. Модули используются для определения поведения запросов.
ZDNS предоставляет несколько типов модулей:
Сырые DNS-модули предоставляют сырой DNS-ответ от сервера, аналогично dig, но в формате JSON. Существует модуль (почти) для каждого типа DNS-записи
Модули поиска предоставляют более полезные ответы, когда требуется несколько запросов (например, дополнительный A-запрос для IP-адресов, если получен NS в NSLOOKUP)
Прочие модули предоставляют другие дополнительные способы запроса серверов (например, bind.version)
Ниже мы описываем модули:
Модули A, AAAA, AFSDB, ANY, ATMA, AVC, AXFR, BINDVERSION, CAA, CDNSKEY, CDS, CERT, CNAME, CSYNC, DHCID, DMARC, DNSKEY, DS, EID, EUI48, EUI64, GID, GPOS, HINFO, HIP, HTTPS, ISDN, KEY, KX, L32, L64, LOC, LP, MB, MD, MF, MG, MR, MX, NAPTR, NID, NINFO, NS, NSAPPTR, NSEC, NSEC3, NSEC3PARAM, NSLOOKUP, NULL, NXT, OPENPGPKEY, PTR, PX, RP, RRSIG, RT, SVCBS, MIMEA, SOA, SPF, SRV, SSHFP, TALINK, TKEY, TLSA, TXT, UID, UINFO, UNSPEC и URI предоставляют сырой DNS-ответ в формате JSON, аналогично dig.
Например, команда:
echo "censys.io" | zdns A
возвращает:
{
"name": "censys.io",
"results": {
"A": {
"data": {
"additionals": [
{
"flags": "",
"type": "EDNS0",
"udpsize": 512,
"version": 0
}
],
"answers": [
{
"answer": "104.18.10.85",
"class": "IN",
"name": "censys.io",
"ttl": 300,
"type": "A"
},
{
"answer": "104.18.11.85",
"class": "IN",
"name": "censys.io",
"ttl": 300,
"type": "A"
}
],
"protocol": "udp",
"resolver": "[2603:6013:9d00:3302::1]:53"
},
"duration": 0.285295416,
"status": "NOERROR",
"timestamp": "2024-08-23T13:12:43-04:00"
}
}
}
Сырые DNS-ответы часто не содержат данных, которые вам нужны. Например, MX-ответ может не включать связанные A-записи в дополнительном разделе, что требует дополнительного запроса. Чтобы устранить этот пробел и предоставить более удобный интерфейс, мы также предлагаем несколько модулей поиска: alookup, mxlookup и nslookup.
alookup ведет себя аналогично nslookup и будет следовать за CNAME-записями.
mxlookup дополнительно выполнит A-запрос для IP-адресов, соответствующих записи обмена.
nslookup дополнительно выполнит A/AAAA-запрос для IP-адресов, соответствующих NS-записи.
Например,
echo "censys.io" | zdns mxlookup --ipv4-lookup
возвращает:
{
"name": "censys.io",
"results": {
"MXLOOKUP": {
"data": {
"exchanges": [
{
"class": "IN",
"ipv4_addresses": [
"209.85.202.27"
],
"name": "alt1.aspmx.l.google.com",
"preference": 5,
"ttl": 300,
"type": "MX"
},
{
"class": "IN",
"ipv4_addresses": [
"142.250.31.26"
],
"name": "aspmx.l.google.com",
"preference": 1,
"ttl": 300,
"type": "MX"
}
]
},
"duration": 0.154786958,
"status": "NOERROR",
"timestamp": "2024-08-23T13:10:11-04:00"
}
}
}
ZDNS также поддерживает специальные «отладочные» DNS-запросы. Модули включают: BINDVERSION.
ZDNS поддерживает ввод в различных форматах в зависимости от желаемого поведения.
Самый базовый ввод — это список имен, разделенных переводами строк. Например:
Из stdin:
echo "google.com\nyahoo.com" | zdns A
cat list_of_domains.txt | zdns A
Из файла:
zdns A --input-file=list_of_domains.txt
Если вам не нужно разрешать много доменов, для удобства поддерживается указание домена в качестве аргумента CLI, аналогично dig.
Например:
zdns A google.com --name-servers=1.1.1.1
Эквивалентно dig -t A google.com @1.1.1.1
Обычно ZDNS выбирает случайный сервер имен для каждого запроса домена из --name-servers. Если вместо этого вы хотите указать другой сервер имен для каждого домена, вы можете сделать это, передав пары domainName,serverIP, разделенные переводами строк. Это переопределит любые серверы имен, указанные с помощью --name-servers.
Например:
echo "google.com,1.1.1.1\nfacebook.com,8.8.8.8" | zdns A
Вы можете видеть, что resolver указан для каждого домена в выводе (дополнительные/ответы сокращены для краткости):
$ echo "google.com,1.1.1.1\nfacebook.com,8.8.8.8" | zdns A
{"name":"google.com","results":{"A":{"data":{"additionals":...,"answers":[...],"protocol":"udp","resolver":"1.1.1.1:53"},"duration":0.030490042,"status":"NOERROR","timestamp":"2024-09-13T09:51:34-04:00"}}}
{"name":"facebook.com","results":{"A":{"data":{"additionals":[...],"answers":[...],"protocol":"udp","resolver":"8.8.8.8:53"},"duration":0.061365459,"status":"NOERROR","timestamp":"2024-09-13T09:51:34-04:00"}}}
Файлы зон (из ICANN CZDS или аналогичных) могут использоваться в качестве источника ввода для ZDNS с флагом --zone-file. Это позволяет анализировать файлы зон либо из stdin (по умолчанию), либо из файла с флагом --input-file.
По умолчанию ZDNS извлекает только имя из каждой записи файла зоны. Если вы также хотите разрешать имена, указанные в разделе ответов для таких типов записей, как CNAME или NS, вы можете использовать флаг CLI --zone-file-include-targets.