TGViewer
Сетевик Джонни // Network Admin Сетевик Джонни // Network Admin @iscode · 5.79K subscribers
Post #1133 1.98K
Сетевик Джонни // Network Admin 🥷 Как работает DNS в Linux. Часть 1: порядок реализации запросов и приоритеты
🥷 Как работает DNS в Linux. Часть 1: порядок реализации запросов и приоритеты

Важно: если имя найдено на одном из шагов, например, в hosts, последующие источники не используются.

В минималистичных системах, таких как Alpine Linux с musl, порядок может отличаться, так как musl не использует NSS и реализует DNS-запросы напрямую, читая /etc/hosts и resolv.conf самостоятельно.

Некоторые приложения и языки (например, Go, Java, Node.js) могут использовать собственные DNS-резолверы, полностью игнорируя системные настройки.

Для примера проанализируем работу утилиты curl.

Команда:

strace -f -e trace=network curl -s download.astralinux.ru > /dev/null
Вывод strace:
socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP) = 3
socketpair(AF_UNIX, SOCK_STREAM, 0, [3, 4]) = 0
socketpair(AF_UNIX, SOCK_STREAM, 0, [5, 6]) = 0
strace: Process 283163 attached
[pid 283163] socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 7
[pid 283163] connect(7, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (Нет такого файла или каталога)
[pid 283163] socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 7
[pid 283163] connect(7, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (Нет такого файла или каталога)
[pid 283163] socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_IP) = 7
[pid 283163] connect(7, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("172.24.31.107")}, 16) = 0
[pid 283163] sendmmsg(7, [{msg_hdr={msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="\250\207\1\0\0\1\0\0\0\0\0\0\10download\nastralinux"..., iov_len=40}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, msg_len=40}, {msg_hdr={msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="\240\215\1\0\0\1\0\0\0\0\0\0\10download\nastralinux"..., iov_len=40}], msg_iovlen=1, msg_controllen=0, msg_flags=0}, msg_len=40}], 2, MSG_NOSIGNAL) = 2
[pid 283163] recvfrom(7, "\250\207\201\200\0\1\0\1\0\0\0\0\10download\nastralinux"..., 2048, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("172.24.31.107")}, [28->16]) = 56
[pid 283163] recvfrom(7, "\240\215\201\200\0\1\0\0\0\1\0\0\10download\nastralinux"..., 65536, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("172.24.31.107")}, [28->16]) = 114
[pid 283163] sendto(6, "\1", 1, MSG_NOSIGNAL, NULL, 0) = 1
[pid 283163] +++ exited with 0 +++
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 5
setsockopt(5, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(5, SOL_SOCKET, SO_KEEPALIVE, [1], 4) = 0
setsockopt(5, SOL_TCP, TCP_KEEPIDLE, [60], 4) = 0
setsockopt(5, SOL_TCP, TCP_KEEPINTVL, [60], 4) = 0
connect(5, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("130.193.50.59")}, 16) = -1 EINPROGRESS (Операция выполняется в данный момент)
getsockopt(5, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
getpeername(5, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("130.193.50.59")}, [128->16]) = 0
getsockname(5, {sa_family=AF_INET, sin_port=htons(48488), sin_addr=inet_addr("172.24.31.241")}, [128->16]) = 0
sendto(5, "GET / HTTP/1.1\r\nHost: download.a"..., 86, MSG_NOSIGNAL, NULL, 0) = 86
recvfrom(5, "HTTP/1.1 200 OK\r\nServer: nginx/1"..., 102400, 0, NULL, NULL) = 1617

🔍 Что мы видим в этом strace?

1. Попытка использовать NSCD (Name Service Cache Daemon)

connect(..., "/var/run/nscd/socket", ...) = -1 ENOENT
- Это означает, что glibc сначала пытается использовать кеш имён из NSCD, если он запущен. В системе его нет, и запрос идёт дальше.

2. Вызов socket() и connect() к DNS-серверу

socket(AF_INET, SOCK_DGRAM|..., IPPROTO_IP) = 7
connect(7, ..., sin_addr=inet_addr("172.24.31.107")...)

- Здесь создаётся UDP-сокет для обращения к DNS-серверу, указанному в /etc/resolv.conf.

3. Вызов sendmmsg() — отправка DNS-запросов

sendmmsg(7, [ { "download.astralinux.ru" }, { "download.astralinux.ru" } ], ...)
Здесь отправляются запросы на резолв имени.

4. Ответ от DNS

recvfrom(...) = 56
recvfrom(...) = 114

Теперь IP-адрес известен.

56 - это размер DNS-ответа в байтах, содержащего А-запись (IPv4-адрес)
  • 👍 7
  • ⚡ 1
More from @iscode
  1. Oct 1, 2026🥷 Подключилось новое устройство. Назвалось «принтер_бухгалтерия». IP свободный, MAC похож…
  2. Oct 1, 2026🎇Главная идея DevSecOps: безопасность перестаёт тормозить разработку. Вместо проверок «по…
  3. Sep 29, 2026Заморочились 😀
  4. Sep 28, 202622 октября встречаемся в Москве: Kuber Conf уже совсем скоро! Что будет на конференции: –…
  5. Aug 23, 2026🥸 OWASP Agentic Skills Top 10: критические уязвимости при работе с агентами Свежак от OWA…
  6. Aug 8, 2026Технологический радар и принятие изменений Когда вы уже достаточно выросли из штанишек и к…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →