DNS, TCP и HTTP на собеседовании

Вечный вопрос «что происходит, когда вы вводите адрес в браузере» — только у DevOps его задают с уклоном в диагностику.

Вопрос: «Пользователь говорит, что сайт не открывается. С хоста рядом всё работает. Как будете локализовать проблему по слоям?»

Что на самом деле проверяет интервьюер

Проверяют дисциплину диагностики: умеете ли вы идти по слоям сверху вниз, а не тыкать наугад. Хороший ответ звучит как алгоритм: DNS → TCP → TLS → HTTP → приложение. На каждом шаге — конкретная команда и понятный признак «здесь проблема или идём дальше».

Слой 1: DNS

Первое, что нужно проверить, — резолвится ли имя и в тот ли адрес. Классические причины отказа именно здесь: старый TTL, из-за которого часть пользователей ещё видит прежний IP; закэшированный отрицательный ответ; ошибка в записи; разные ответы у разных резолверов.

dig +short app.example.com
dig app.example.com @8.8.8.8      # спросить у чужого резолвера — сравнить
dig +trace app.example.com        # пройти цепочку от корня
dig app.example.com SOA           # чья зона и какой TTL негативного кэша

Что стоит знать про типы записей: A и AAAA — адреса IPv4/IPv6, CNAME — псевдоним (нельзя на вершине домена), TXT — подтверждения владения и SPF/DKIM. И главное правило эксплуатации: перед плановой сменой адреса TTL заранее снижают до 60 секунд, иначе переключение растянется на сутки. Отдельная деталь для Kubernetes: внутри кластера имена вида api.production.svc.cluster.local резолвит CoreDNS, и «неработающий сервис» нередко оказывается сбоем именно резолвинга — проверяется командой kubectl run -it --rm dnsutils --image=alpine -- nslookup api.

Слой 2: TCP

Имя разрешилось — проверяем, устанавливается ли соединение. TCP-соединение открывается рукопожатием из трёх пакетов (SYN, SYN-ACK, ACK), и характер отказа сам подсказывает причину:

СимптомВероятная причина
Connection refusedхост доступен, но на порту никто не слушает
Timeout без ответапакеты дропает firewall или security group
Connection resetсоединение оборвал сервер или промежуточное устройство
nc -zv app.example.com 443        # порт открыт?
ss -tlnp                          # кто слушает на сервере
ss -s                             # сводка по состояниям соединений
traceroute -T -p 443 app.example.com
sudo tcpdump -ni any port 443 and host 203.0.113.10 -c 20

Про состояния соединений спрашивают отдельно. TIME_WAIT — нормальное состояние закрытой стороны, длится обычно 60 секунд и нужно, чтобы «опоздавшие» пакеты не попали в новое соединение с теми же портами; десятки тысяч TIME_WAIT на сервере — признак того, что не используются keep-alive-соединения. Растущий CLOSE_WAIT, наоборот, почти всегда баг приложения: оно не закрывает сокеты и рано или поздно упрётся в лимит файловых дескрипторов.

Слой 3: TLS

Порт открыт, но браузер ругается на сертификат. Самые частые причины: истёк срок, не отдана промежуточная цепочка (в браузере работает, curl-ом нет), имя в сертификате не совпадает с доменом, или клиент не поддерживает нужную версию протокола.

openssl s_client -connect app.example.com:443 -servername app.example.com </dev/null 2>/dev/null \
  | openssl x509 -noout -dates -subject -issuer

# notBefore=Jul  1 00:00:00 2026 GMT
# notAfter=Sep 29 23:59:59 2026 GMT

curl -vI https://app.example.com    # видно версию TLS и цепочку

Параметр -servername здесь не формальность: это SNI, благодаря которому один IP отдаёт разные сертификаты для разных доменов. Забыв его, легко получить «чужой» сертификат и уйти отлаживать несуществующую проблему.

Слой 4: HTTP

Соединение установлено — смотрим, что отвечает приложение. Коды, значение которых обязан различать DevOps:

  • 301 против 302 — постоянный редирект (браузеры и прокси кэшируют его надолго, ошибку тяжело откатить) против временного.
  • 401 против 403 — «не аутентифицирован, представьтесь» против «аутентифицирован, но доступ запрещён».
  • 502 против 503 против 504 — самая ценная тройка. 502: прокси получил от бэкенда мусор или бэкенд оборвал соединение. 503: сервис недоступен, обычно нет живых бэкендов или сработала защита от перегрузки. 504: бэкенд не ответил за отведённое время. Каждый код указывает на свой участок пути, и разбор инцидента начинается именно с этого разделения.
  • 429 — сработал rate limiting.
curl -w "dns:%{time_namelookup} tcp:%{time_connect} tls:%{time_appconnect} ttfb:%{time_starttransfer} total:%{time_total}\n" \
     -o /dev/null -s https://app.example.com

Эта одна команда сразу показывает, на каком этапе теряется время: медленный DNS, долгая установка соединения, тяжёлое TLS-рукопожатие или тормозящий бэкенд. На собеседовании её знание производит хорошее впечатление, потому что видно практику, а не теорию.

Типичные ошибки кандидатов

  • Начинают с логов приложения, не проверив, доходит ли до него запрос вообще.
  • Не различают 502, 503 и 504 — и теряют время, ища проблему не там.
  • Забывают про TTL DNS при переключении на новый адрес.
  • Считают, что ping проверяет доступность сервиса. ICMP может быть закрыт, а порт открыт — и наоборот.
  • Не знают про SNI и получают «неправильный» сертификат при проверке через openssl.
  • Списывают рост CLOSE_WAIT на «сеть», хотя это утечка сокетов в приложении.

Как ответить кратко (20–30 секунд)

«Иду по слоям. DNS: dig с разных резолверов — резолвится ли имя и в тот ли адрес, не мешает ли старый TTL. TCP: nc или ss — connection refused значит никто не слушает, timeout значит дропает firewall. TLS: openssl s_client с SNI — срок и полнота цепочки сертификатов. HTTP: curl и коды ответа, где 502 указывает на битый ответ бэкенда, 503 — на отсутствие живых бэкендов, 504 — на таймаут. И только потом смотрю логи приложения. Быстрый способ понять, где теряется время, — curl с выводом time_namelookup, time_connect, time_appconnect и time_starttransfer.»

Проверьте себя
1. Что означает ответ 504 Gateway Timeout от nginx перед приложением?
AПриложение вернуло некорректный ответ, который прокси не смог разобрать
BПрокси не дождался ответа от бэкенда за отведённое время
CНи один бэкенд не помечен как живой
DКлиент превысил лимит запросов
2. Почему перед плановой сменой IP-адреса домена заранее снижают TTL записи?
AЧтобы уменьшить нагрузку на авторитативный сервер
BЧтобы резолверы быстрее забыли старый адрес и переключение не растянулось на время старого TTL
CЧтобы обновить сертификат TLS
DЧтобы включить поддержку IPv6
3. На сервере постоянно растёт число соединений в состоянии CLOSE_WAIT. О чём это говорит?
AНормальная работа TCP, состояние исчезнет через 60 секунд
BПриложение не закрывает сокеты после того, как их закрыла удалённая сторона — утечка дескрипторов
CСеть перегружена и пакеты теряются
DНе хватает памяти на сервере