Как командой ss найти процесс на порту, увидеть подключённых клиентов и прочитать очереди Recv-Q и Send-Q. Плюс замены для netstat.
Приложение запустилось, а порт не отвечает. Или наоборот: порт занят, а кем - непонятно. В старых инструкциях в таких случаях стоит netstat, но на свежем сервере этой команды чаще всего нет, а то, что в ней искали, давно умеет делать ss. Разберём три вопроса, которые решает ss в первые минуты: кто слушает порт, кто сейчас подключён и не копятся ли соединения.
Коротко.
sudo ss -tulpnпоказывает, какие процессы слушают порты и на каких адресах.ss -tnp 'sport = :22'- кто подключён к порту 22.ss -s- сводка по сокетам.netstatвходит в пакет net-tools, который давно не развивается, и в свежих образах его обычно нет; ключи уssпочти те же. Если приложение слушает127.0.0.1, снаружи оно недоступно, и это самая частая причина «порт открыт, но не отвечает». У слушающего портаSend-Q- это размер очереди, а не отправленные байты.
Это команда, которой начинается почти любая диагностика сети на сервере. Она спрашивает у ядра список открытых сокетов и показывает, какой процесс держит каждый. Запускаем от root, иначе имён процессов не будет:
sudo ss -tulpnРасшифровка ключей: -t - TCP, -u - UDP, -l - только слушающие сокеты, -p - показать процесс, -n - числа вместо имён служб и хостов (быстрее и однозначнее). Ответ на нашем сервере (оставили несколько строк):
Самое важное здесь - колонка Local Address. 0.0.0.0:80 значит «принимаю подключения на всех адресах сервера», то есть nginx доступен снаружи. 127.0.0.53:53 - адрес из диапазона 127.x, он доступен только самому серверу: это локальный DNS-резолвер systemd. Именно так выглядит ситуация, когда приложение «слушает порт, но снаружи не открывается»: в этой колонке стоит 127.0.0.1, а нужно 0.0.0.0 или адрес сервера. Перенастраивать надо само приложение, а не фаервол.
У sshd в колонке Process два владельца: сам sshd и systemd с pid=1. Это нормально: на Ubuntu 24.04 порт 22 открывает systemd (юнит ssh.socket) и передаёт сокет сервису sshd, поэтому у одного сокета два держателя.
В выводе выше у nginx в Send-Q стоит 511, у sshd 4096. Для обычного соединения Recv-Q - это байты, которые пришли, но приложение ещё не прочитало, а Send-Q - байты, которые отправлены, но собеседник ещё не подтвердил. У слушающего сокета числа значат другое:
511 у nginx - его значение по умолчанию. Практический вывод: если у слушающего порта Recv-Q долго больше нуля, приложение не успевает принимать соединения, и клиенты либо ждут, либо получают отказ. Нулевой Recv-Q у слушающего порта в норме.
Чтобы увидеть живые соединения на конкретном порту, к ключам добавляется фильтр. Кавычки нужны, чтобы оболочка не трогала символы в выражении:
sudo ss -tnp 'sport = :22'ESTAB - соединение установлено. Слева наш адрес и порт 22, справа клиент и его случайный порт, в конце процесс, который его обслуживает. Ненулевой Send-Q здесь не ошибка: это байты, которые сервер уже отправил (в нашем случае сам вывод этой команды по SSH), а подтверждение ещё не пришло.
Фильтры, которые чаще всего нужны:
ss -tn state established - только установленные соединения;ss -tn '( dport = :443 or sport = :443 )' - всё, что связано с портом 443;ss -tn dst 203.0.113.0/24 - соединения с конкретной подсетью;ss -tn state time-wait - соединения в состоянии TIME-WAIT.Когда нужно понять картину целиком, а не разглядывать строки, достаточно ss -s:
ss -sВ строке TCP видно, сколько соединений установлено, сколько висит в TIME-WAIT и сколько «осиротело» (orphaned - сокеты, которые приложение уже закрыло, а ядро ещё держит). Сотни и даже десятки тысяч TIME-WAIT на нагруженном публичном сервисе могут быть нормой. Тревожный сигнал - когда кончаются порты или файловые дескрипторы, либо растёт задержка.
Ключ -o добавляет таймеры соединения:
ss -tno state establishedon означает таймер повторной отправки, 100ms - сколько до его срабатывания, последняя цифра - сколько повторных отправок уже было. Для обычной диагностики хватает знать, что растущее число повторов - признак потерь на канале.
У ss почти те же ключи, поэтому привычка переносится быстро. Часть возможностей netstat перекочевала в другие команды из пакета iproute2:
Было (netstat) | Стало | Что показывает |
|---|---|---|
| | слушающие порты и процессы |
| | все сокеты в числовом виде |
|
| сводка по сокетам и счётчики протоколов |
| | таблица маршрутов |
| | статистика сетевых интерфейсов |
Пакет net-tools с netstat ставится отдельно, если очень нужно: sudo apt install net-tools. Но проще привыкнуть к ss: он есть в системе сразу и обычно работает быстрее, когда сокетов много.
ss входит в пакет iproute2 и запрашивает данные у ядра напрямую, netstat относится к пакету net-tools, который давно не развивается. У ss больше фильтров и он обычно быстрее на большом числе соединений.
Выполните sudo ss -ltnp 'sport = :8080', подставив нужный порт. В колонке Process будет имя и pid процесса. Без sudo имя процесса не покажется, если процесс запущен другим пользователем.
Чаще всего приложение слушает 127.0.0.1 вместо 0.0.0.0. Проверьте колонку Local Address. Если там 127.0.0.1, поменяйте адрес в настройках приложения. Если там 0.0.0.0, а снаружи всё равно закрыто, смотрите фаервол.
Это обычное состояние закрытых соединений, которое ядро держит некоторое время. Много TIME-WAIT на нагруженном сервере - норма. Проблемой это становится, только если не хватает портов или растёт задержка.
sudo ss -tulpn - кто слушает порты и на каких адресах.0.0.0.0 (доступно снаружи) и 127.0.0.1 (только изнутри).ss -tnp 'sport = :22' - кто подключён к порту; фильтры state, dport, dst сужают выборку.ss -s - сводка, ss -o - таймеры.ip route и ip -s link.