Самый частый вопрос на собесе DevOps и бэкендера: «сервис недоступен, что будешь проверять?». Ответ это прогулка по стеку снизу вверх: интерфейс, маршрут, DNS, порт, фаервол, приложение. Ниже инструменты для каждого шага.
Интерфейсы и адреса: ip
ifconfig и netstat из пакета net-tools устарели, на свежих системах их может не быть. Современный набор это ip и ss (iproute2).
ip -br addr # кратко: интерфейс, состояние, адреса
ip addr show eth0
ip link set eth0 up
ip route # таблица маршрутов
ip route get 8.8.8.8 # через какой интерфейс и шлюз пойдёт пакет
ip neigh # ARP-таблица
default via 10.0.0.1 dev eth0 в ip route это шлюз по умолчанию. Нет его, значит в интернет пакеты не уйдут.
Порты и сокеты: ss
ss -tlnp # TCP, слушающие, без резолва имён, с процессом
ss -ulnp # то же для UDP
ss -tn state established '( dport = :5432 )'
ss -s # сводка по состояниям
Важно смотреть, на каком адресе слушает сервис. 127.0.0.1:8080 доступен только с этой машины, 0.0.0.0:8080 или *:8080 со всех интерфейсов. Классика: приложение в контейнере слушает 127.0.0.1, и снаружи до него не достучаться.
Состояния TCP, о которых спрашивают:
LISTEN: ждёт соединений.ESTABLISHED: открыто.TIME_WAIT: сторона, закрывшая первой, ждёт 2×MSL (в Linux 60 секунд), чтобы опоздавшие пакеты не попали в новое соединение. Тысячи TIME_WAIT у клиента часто значат, что соединения не переиспользуются.CLOSE_WAIT: удалённая сторона закрыла, а наше приложение ещё нет. Рост CLOSE_WAIT это почти всегда баг в коде: соединения не закрываются.
DNS: dig и resolv.conf
dig example.com # A-запись через системный резолвер
dig +short example.com AAAA
dig @1.1.1.1 example.com # спросить конкретный сервер
dig example.com MX
dig +trace example.com # пройти от корня
getent hosts example.com # как резолвит система (с /etc/hosts)
Порядок резолвинга задаёт /etc/nsswitch.conf (обычно сначала files, то есть /etc/hosts, потом dns). Серверы DNS лежат в /etc/resolv.conf; в Ubuntu там часто 127.0.0.53, это локальный systemd-resolved, настоящие серверы смотрят resolvectl status. dig идёт в DNS напрямую и /etc/hosts не читает, а getent и обычные программы читают.
HTTP: curl
curl -I https://api.example.com/health # только заголовки
curl -v https://api.example.com # TLS, заголовки, всё подряд
curl -sS -o /dev/null -w '%{http_code} %{time_total}\n' URL
curl --resolve api.example.com:443:10.0.0.5 https://api.example.com/ # мимо DNS
curl -k https://... # не проверять сертификат (только для отладки)
-w с переменными time_namelookup, time_connect, time_starttransfer показывает, где теряется время: на DNS, на TCP или на ответе приложения.
Проверка доступности порта
ping проверяет ICMP, а его часто режут. Для TCP: nc -zv host 5432, curl -v telnet://host:5432 или чистый bash timeout 2 bash -c '</dev/tcp/host/5432'.
Что означает ответ:
- Connection refused: хост доступен, но на порту никто не слушает (или фаервол отвечает RST).
- Timeout: пакеты теряются: фаервол с DROP, нет маршрута, хост выключен.
- No route to host: нет маршрута или ICMP host unreachable (иногда так отвечает фаервол с REJECT).
Фаервол: iptables и nftables
Под капотом netfilter в ядре. iptables это классический интерфейс, nftables (nft) современный, и на свежих дистрибутивах команда iptables часто работает через слой совместимости iptables-nft. Надстройки: ufw в Ubuntu, firewalld в RHEL.
Цепочки таблицы filter: INPUT (пакеты к этой машине), OUTPUT (от неё), FORWARD (транзитные, например в контейнеры). Правила проверяются по порядку, первое совпавшее с действием ACCEPT, DROP или REJECT решает судьбу пакета. Если ничего не совпало, работает политика цепочки.
iptables -L -n -v --line-numbers
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -P INPUT DROP
nft list ruleset
DROP молча выбрасывает (клиент видит таймаут), REJECT отвечает ошибкой (клиент видит refused). Таблица nat делает DNAT и SNAT/MASQUERADE: так Docker публикует порты контейнеров.
Правила iptables не переживают перезагрузку сами: их сохраняют (iptables-save, пакет iptables-persistent) или описывают в конфиге nftables.
Алгоритм «сервис недоступен»
- Слушает ли процесс и на каком адресе:
ss -tlnp | grep 8080. - Отвечает ли локально:
curl -v localhost:8080/health. - DNS:
dig +short api.example.com, правильный ли IP. - Сеть до хоста:
ip route get,ping,traceroute/mtr. - Порт снаружи:
nc -zv host 8080, refused или timeout. - Фаервол на хосте и в облаке (security groups).
- Лог приложения и прокси.
Частые ошибки
- Проверять доступность
ping-ом и делать вывод про порт. - Забыть, что сервис слушает только
127.0.0.1. - Править
/etc/resolv.conf, которым управляет systemd-resolved, и терять правки. - Добавлять
iptables -A ... ACCEPTпосле правила, которое уже всё отбросило. - Применить
-P INPUT DROPпо SSH без правила для своего соединения.
Что спросят на собесе
- Сервис недоступен: по шагам, что проверишь.
- Чем
Connection refusedотличается от таймаута. - Что значат TIME_WAIT и CLOSE_WAIT, что делать, если их тысячи.
- Как работает резолвинг имени в Linux.
- Как устроены цепочки iptables и чем DROP отличается от REJECT.