DNS-диагностика — dig, nslookup, +trace и @resolver
«Сайт не открывается. Сервер ping-ается, но curl говорит ‘could not resolve host’» — это классическая DNS-проблема. Когда DNS ломается, никакие сетевые инструменты не помогают, потому что имя не превращается в IP. И первое, что нужно сделать — посмотреть, что DNS реально отвечает.
В этом уроке разберём два главных инструмента: dig (стандарт de facto, более информативный) и nslookup (старый, но всё ещё везде), плюс продвинутые техники: +trace для пошагового резолва, @resolver для тестирования разных DNS-серверов, и команды для проверки DNSSEC.
dig vs nslookup — кратко
nslookup — старый инструмент, остался с UNIX 80-х. Минималистичный output. Сейчас фактически deprecated, но повсеместен.
dig (DNS Information Groper) — современный инструмент. Очень детальный output, поддерживает все продвинутые опции DNS, является стандартом BIND. На macOS встроен, на Linux в пакете dnsutils или bind-utils.
Для одноразовых проверок nslookup сойдёт, для серьёзной диагностики — только dig.
# nslookup -- лаконично:
nslookup google.com
# Server: 1.1.1.1
# Address: 1.1.1.1#53
#
# Non-authoritative answer:
# Name: google.com
# Address: 142.250.74.110
# dig -- детально:
dig google.com
# ; <<>> DiG 9.10.6 <<>> google.com
# ;; global options: +cmd
# ;; Got answer:
# ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32417
# ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
#
# ;; QUESTION SECTION:
# ;google.com. IN A
#
# ;; ANSWER SECTION:
# google.com. 300 IN A 142.250.74.110
#
# ;; Query time: 5 msec
# ;; SERVER: 1.1.1.1#53(1.1.1.1)
# ;; WHEN: Sun May 18 14:32:01 MSK 2026
# ;; MSG SIZE rcvd: 55
Читаем dig output по разделам
Каждая секция dig output даёт конкретную информацию.
HEADER — статус и флаги
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32417
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
- opcode: QUERY — тип операции, обычно QUERY (стандартный запрос).
- status: NOERROR — статус. Возможные:
NOERROR— всё OK.NXDOMAIN— домен не существует.SERVFAIL— ошибка сервера (resolver не смог получить ответ).REFUSED— сервер отказывается отвечать (например, не его zone).
- id: 32417 — transaction ID.
- flags — битовые флаги:
qr— query/response (всегда есть в ответе).rd— recursion desired (мы хотели рекурсивный резолв).ra— recursion available (сервер поддерживает рекурсию).aa— authoritative answer (ответ от authoritative-сервера, не из кэша).ad— authenticated data (DNSSEC, ответ валиден).
- QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 — количество записей в каждой секции.
QUESTION — что спросили
;; QUESTION SECTION:
;google.com. IN A
Просто эхо нашего запроса: «спрашиваем A-запись для google.com в class IN (Internet)». Полезно для confirmation.
ANSWER — что ответили
;; ANSWER SECTION:
google.com. 300 IN A 142.250.74.110
Поля:
- google.com. — domain (точка в конце — абсолютное имя FQDN).
- 300 — TTL в секундах. 300 = 5 минут. Через это время кэш истечёт.
- IN — class (Internet).
- A — тип записи (A = IPv4 address).
- 142.250.74.110 — значение.
AUTHORITY и ADDITIONAL — метадата
Часто пустые для простого запроса. В AUTHORITY — NS-записи для зоны. В ADDITIONAL — glue records (IP-адреса NS-серверов).
Footer — статистика
;; Query time: 5 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Sun May 18 14:32:01 MSK 2026
;; MSG SIZE rcvd: 55
- Query time: 5 msec — сколько занял resolver. 5ms — из кэша. 100+ ms — рекурсивный резолв.
- SERVER: 1.1.1.1#53 — какой resolver ответил.
- MSG SIZE rcvd: 55 — размер ответа в байтах.
Разные типы записей — A, AAAA, CNAME, MX, TXT
dig может запрашивать любой тип DNS-записей:
# IPv4 (по умолчанию):
dig example.com A
# или просто: dig example.com
# IPv6:
dig example.com AAAA
# MX-записи (mail servers):
dig example.com MX
# TXT-записи (часто SPF, DKIM, DMARC):
dig example.com TXT
# CNAME:
dig www.example.com CNAME
# Все известные записи:
dig example.com ANY
# (часто блокируется -- провайдеры отдают amplification-friendly большие ответы)
# NS-записи (authoritative servers):
dig example.com NS
# SOA (Start of Authority):
dig example.com SOA
Пример MX-запроса:
dig example.com MX
;; ANSWER SECTION:
example.com. 3600 IN MX 10 mail.example.com.
example.com. 3600 IN MX 20 mail-backup.example.com.
Числа 10 и 20 — priority. Меньше = выше приоритет. Mail-сервер сначала пытается mail.example.com (10), потом mail-backup.example.com (20). Это стандартный failover для email.
@resolver — тестируем разные DNS
По умолчанию dig использует системный resolver (из /etc/resolv.conf). Чтобы протестировать конкретный сервер, добавьте @server:
# Использовать Cloudflare DNS:
dig @1.1.1.1 google.com
# Использовать Google Public DNS:
dig @8.8.8.8 google.com
# Использовать конкретный authoritative server:
dig @ns1.google.com google.com
# Сравнить ответы от разных resolvers (выявление DNS issues):
dig @1.1.1.1 yourdomain.com
dig @8.8.8.8 yourdomain.com
dig @ns1.yourdomain.com yourdomain.com
Зачем это нужно:
- DNS propagation. Изменили DNS-запись — хочется увидеть, везде ли распространилось. Запрашиваете разные resolvers, видите, у кого ещё старая запись.
- Кэширование problems. Если ваш системный resolver выдаёт неправильный ответ, а 1.1.1.1 правильный — проблема в кэше вашего resolver.
- Прямое обращение к authoritative. Запрос к ns1.domain.com даёт ground truth — то, что admin зоны действительно настроил.
Кэширование DNS бывает на нескольких уровнях: браузер -> OS -> локальный resolver -> ваш ISP DNS -> recursive resolver -> authoritative. Каждый из этих кэшей может держать старые данные до истечения TTL. Поэтому ‘сменил DNS, не работает’ часто это просто propagation.
+trace — пошаговый рекурсивный резолв
dig +trace показывает пошаговое разрешение имени, как делал бы рекурсивный resolver сам. Это очень мощная диагностика.
dig +trace google.com
; <<>> DiG 9.10.6 <<>> +trace google.com
;; global options: +cmd
. 518400 IN NS a.root-servers.net.
. 518400 IN NS b.root-servers.net.
...
. 518400 IN NS m.root-servers.net.
;; Received 239 bytes from 1.1.1.1#53(1.1.1.1) in 0 ms
com. 172800 IN NS a.gtld-servers.net.
com. 172800 IN NS b.gtld-servers.net.
...
;; Received 1175 bytes from 198.41.0.4#53(a.root-servers.net) in 24 ms
google.com. 172800 IN NS ns1.google.com.
google.com. 172800 IN NS ns2.google.com.
google.com. 172800 IN NS ns3.google.com.
google.com. 172800 IN NS ns4.google.com.
;; Received 668 bytes from 192.5.6.30#53(a.gtld-servers.net) in 32 ms
google.com. 300 IN A 142.250.74.110
;; Received 55 bytes from 216.239.32.10#53(ns1.google.com) in 18 ms
Что происходит:
- Спросили root. Получили 13 NS root-серверов.
a.root-servers.net…m.root-servers.net. - Спросили root: ‘кто отвечает за com?’ Получили NS-серверы TLD
com. Этоa.gtld-servers.netи т.д. - Спросили один из gTLD-серверов: ‘кто отвечает за google.com?’ Получили
ns1.google.com…ns4.google.com. Это authoritative-серверы Google. - Спросили ns1.google.com: ‘какой A-record у google.com?’ Получили
142.250.74.110.
Это видимо, как реально работает DNS-резолюция. Полезно для диагностики:
- Не отвечают root-серверы? Проблема с сетью (вряд ли, root-сервера anycast и почти не падают).
- TLD-серверы не отвечают? Проблема в TLD-регистратуре (тоже маловероятно).
- Authoritative-сервера домена не отвечают? Проблема в DNS-провайдере домена — эскалируйте.
- Authoritative отвечает не то? Запись настроена неправильно.
Реверс-резолв и PTR-записи
DNS обычно про «имя -> IP», но есть и обратный путь: «IP -> имя». Это PTR-записи в специальной зоне in-addr.arpa.
# Реверс-резолв для 8.8.8.8:
dig -x 8.8.8.8
;; ANSWER SECTION:
8.8.8.8.in-addr.arpa. 1234 IN PTR dns.google.
# Или через short:
dig +short -x 8.8.8.8
# dns.google.
Зачем PTR:
- Mail servers требуют PTR для отправляющего IP — иначе принимающие отбрасывают как spam.
- SSH login banners. Многие SSH-серверы делают реверс-резолв для логирования.
- Diagnostic. Когда вы видите IP в логах, dig -x превращает его в человекочитаемое имя.
PTR-записи — ответственность владельца IP-блока (обычно ISP или вы, если у вас свой IP-блок). Поэтому изменить PTR для своего EC2 instance — через AWS Console, для домашнего IP — никак (ISP-владелец).
DNSSEC — проверка подписей
DNSSEC — криптографическая подпись DNS-ответов. dig умеет проверять:
# Запросить с DNSSEC-валидацией:
dig +dnssec google.com
;; ANSWER SECTION:
google.com. 300 IN A 142.250.74.110
# Если зона подписана DNSSEC, увидите RRSIG (signatures):
dig +dnssec cloudflare.com
;; ANSWER SECTION:
cloudflare.com. 300 IN A 104.16.132.229
cloudflare.com. 300 IN A 104.16.133.229
cloudflare.com. 300 IN RRSIG A 13 2 300 20260530000000 ...
# Флаг 'ad' (authenticated data) в HEADER говорит, что resolver проверил подпись:
dig +dnssec cloudflare.com | grep flags
;; flags: qr rd ra ad; ...
Если зона НЕ подписана DNSSEC — RRSIG не будет. Большинство ccTLD (.ru, .de, .uk, …) подписаны. Многие популярные домены — НЕ (Google не подписывает google.com).
# Проверить, поддерживает ли домен DNSSEC:
dig +dnssec example.com | grep -E '(RRSIG|ad)'
# Если ничего не выводит -- домен не подписан
Типичные DNS-проблемы и их диагностика
Симптом: «сайт не открывается, ping не разрешает имя»
# Что отдаёт ваш системный DNS:
dig your-site.com
# Что отдаёт публичный resolver (для сравнения):
dig @1.1.1.1 your-site.com
# Что отдаёт authoritative (ground truth):
dig +short NS your-site.com # узнать authoritative servers
dig @<authoritative-ns> your-site.com # запросить их напрямую
Если все три совпадают — запись настроена правильно. Если системный отличается — проблема в кэше. Если authoritative отличается — DNS-запись неправильная.
Симптом: «изменил DNS, у меня работает, у других — старая запись»
DNS propagation. Решение — ждать TTL предыдущей записи. Можно ускорить через dig +trace — если authoritative отдаёт новый IP, значит распространение идёт.
Симптом: «SERVFAIL от resolver»
dig your-site.com
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, ...
Recursive resolver не смог получить ответ. Возможные причины:
- Authoritative-сервер не отвечает. Зайдите туда напрямую:
dig @authoritative-ns your-site.com. - DNSSEC validation failed. Если запись подписана, но что-то с подписью — resolver вернёт SERVFAIL. Тестируйте без DNSSEC:
dig +cd your-site.com(+cd= check disabled). - Network problem от resolver к authoritative. Сложно диагностировать без логов resolver.
Симптом: «NXDOMAIN»
Домен не существует — ни в DNS, ни в authoritative. Может означать:
- Действительно нет такого домена (опечатка, истёкший домен).
- Domain was created but DNS not propagated yet. Иногда NXDOMAIN кэшируется (negative caching, обычно 1-5 минут).
dig new-domain.com
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, ...
Проверьте через whois new-domain.com — если домен реально зарегистрирован, ждите DNS-распространения.
Симптом: разные ответы от разных resolvers
dig @1.1.1.1 your-site.com
# -> 1.2.3.4 (новый IP)
dig @8.8.8.8 your-site.com
# -> 5.6.7.8 (старый IP)
DNS propagation в действии. Cloudflare уже узнал об изменении, Google — ещё нет. Подождите.
nslookup — быстрая проверка
Когда времени мало, nslookup даёт быстрый ответ:
# Простой A-record:
nslookup google.com
# Server: 1.1.1.1
# Address: 1.1.1.1#53
# Name: google.com
# Address: 142.250.74.110
# Конкретный resolver:
nslookup google.com 8.8.8.8
# Тип записи:
nslookup -type=MX example.com
nslookup -type=TXT example.com
# Реверс:
nslookup 8.8.8.8
Сравнительно с dig:
- nslookup проще, output короче.
- nslookup не показывает TTL, флаги, не умеет +trace.
- nslookup есть на Windows из коробки (dig не всегда).
Для серьёзной работы лучше dig. Для быстрой проверки — nslookup OK.
host — простой wrapper
host — ещё одна команда, что-то между nslookup и dig:
host google.com
# google.com has address 142.250.74.110
# google.com mail is handled by 10 smtp.google.com.
host -t TXT google.com
host -t MX google.com
host -a google.com # всё
Удобно, когда хочется лаконичный output без всего, что даёт dig.
Попробуй сам
Сделайте полный pipeline DNS-диагностики:
# 1. Что отдаёт системный DNS:
dig your-domain.com
# 2. Сравнить с публичными resolvers:
dig @1.1.1.1 your-domain.com
dig @8.8.8.8 your-domain.com
dig @9.9.9.9 your-domain.com # Quad9 -- бесплатный с защитой от malware
# 3. Кто authoritative для домена:
dig +short NS your-domain.com
# 4. Спросить authoritative напрямую (substitute с реальными NS):
dig @ns1.example.com your-domain.com
# 5. Проследить полный путь резолва:
dig +trace your-domain.com
# 6. Проверить разные типы записей:
dig your-domain.com MX
dig your-domain.com TXT
dig _dmarc.your-domain.com TXT # DMARC policy
# 7. Реверс-резолв вашего внешнего IP:
dig -x $(curl -s https://api.ipify.org)
Поэкспериментируйте с TTL:
dig google.com
;; ANSWER SECTION:
google.com. 300 IN A 142.250.74.110
# TTL 300 -- 5 минут. Если попросите снова через 10 секунд:
dig google.com
;; ANSWER SECTION:
google.com. 290 IN A 142.250.74.110
# TTL уменьшился на 10. Это значит, resolver вернул из кэша.
# Когда TTL станет 0, resolver сделает повторный запрос к authoritative.
Проверьте свой собственный домен (если есть):
# Все NS-серверы:
dig +short NS your-domain.com
# Если зарегистрирован у Cloudflare, должно быть что-то типа:
# alex.ns.cloudflare.com.
# steve.ns.cloudflare.com.
# A-запись у каждого NS должна быть одинаковая:
for ns in $(dig +short NS your-domain.com); do
echo "$ns:"
dig @$ns +short your-domain.com
done
Если все NS отвечают одинаково — DNS-конфигурация согласованная. Если разное — есть проблема в синхронизации между NS.
Debugging DNS в Kubernetes: dig внутри pod и CoreDNS logs