Как проверить открытые порты в Linux через ss
Узнайте, как работают порты в Linux и как определить, какая служба занимает нужный адрес. Используйте команду ss -tulpn для поиска активных соединений и портов.
Что такое порт на самом деле
Порт — это число, которое позволяет одному серверу одновременно запускать множество служб, не смешивая их трафик. Ваш VPS имеет один IP-адрес, но на нём могут одновременно работать веб-сервер, SSH-сервер и база данных. Когда пакет прибывает на сервер, операционная система должна определить, какому из этих приложений он предназначен. Номер порта дает ответ на этот вопрос. Веб-трафик направляется на порт 443, SSH — на порт 22. IP-адрес доставляет пакет на ваш сервер, а порт направляет его нужной программе на этом сервере.
Порт представляет собой 16-битное число: 16 бит дают диапазон от 0 до 65535, при этом 0 зарезервирован, поэтому на практике порты используются в диапазоне от 1 до 65535. Порты ниже 1024 являются «общеизвестными» (well-known), и для их открытия требуются права root. Именно поэтому стандартные службы используют именно их: 22 для SSH, 80 для HTTP, 443 для HTTPS, 53 для DNS. Любые порты выше 1024 доступны для обычных программ.
Существует два типа портов: TCP и UDP. Номер порта в одном протоколе никак не связан с таким же номером в другом. TCP — это протокол с установлением соединения, который используют большинство служб, таких как SSH, HTTP и базы данных. UDP — это протокол без установления соединения, используемый для таких задач, как DNS и некоторые VPN. При настройке межсетевого экрана вы обычно указываете тип протокола, например 22/tcp.
Состояние listening означает, что программа ожидает соединений на порту
Программа, которой необходимо принимать входящие соединения, запрашивает у ядра разрешение «слушать» порт. С этого момента порт становится открытым на машине, и программа обрабатывает все поступающие на него данные, если это разрешено межсетевым экраном. Если на порту нет слушающего процесса, он просто отклоняет соединения. Поэтому первый вопрос при любой проверке безопасности звучит так: что именно слушает порты и где это происходит.
Команда для получения ответа на этот вопрос — ss:
sudo ss -tlnpФлаги означают использование протокола TCP (t), отображение только слушающих сокетов (l), использование числовых значений портов (n, чтобы вы видели 22, а не ssh) и вывод идентификатора процесса-владельца (p). Типичный результат выглядит так:
State Recv-Q Local Address:Port Process
LISTEN 0 0.0.0.0:22 sshd
LISTEN 0 127.0.0.1:5432 postgres
LISTEN 0 [::]:80 nginxСтолбец Process показывает, какая программа владеет каждым портом. Это позволяет отследить процессы, которые вы не планировали оставлять запущенными.
Столбец Local Address — это то, что имеет значение
Внимательно читайте адрес перед каждым портом, так как именно он определяет, кто может получить доступ к сервису. Вы постоянно будете сталкиваться с тремя вариантами.
0.0.0.0:22 означает «слушать на всех IPv4-адресах, которые есть у этой машины», включая публичный. Сервис доступен из интернета по протоколу IPv4, если это разрешено брандмауэром.
[::]:80 означает то же самое для IPv6: прослушивание всех IPv6-адресов, включая публичные. Многие программы по умолчанию привязываются к этому адресу, и в Linux сокет :: часто принимает и IPv4-соединения.
127.0.0.1:5432 означает «слушать только на loopback-интерфейсе». 127.0.0.1 — это адрес, который машина использует для связи с самой собой, и он недоступен для маршрутизации откуда-либо еще. Сервис, привязанный к этому адресу, доступен только с того же сервера и никогда — из интернета, независимо от настроек вашего брандмауэра. Упомянутая выше строка с Postgres безопасна по своей архитектуре.
Практическое правило вытекает из этого напрямую: база данных, кэш или панель администратора, которые используют только ваши собственные приложения, должны быть привязаны к 127.0.0.1, а не к 0.0.0.0. Если сервис никогда не слушает на публичном адресе, злоумышленнику не к чему подключаться.
Состояние прослушивания не означает доступность
Ещё одно различие помогает избежать путаницы. Открытый на машине порт, означающий, что программа его прослушивает, — это не то же самое, что доступность порта извне, которую определяет межсетевой экран. Для подключения удаленного клиента должны выполняться оба условия. С точки зрения клиента эти сбои выглядят по-разному: отказ в соединении означает, что порт никто не слушает, а зависание с последующим таймаутом обычно указывает на то, что межсетевой экран отбросил пакет. Именно об этом сообщают две ошибки SSH.
Таким образом, существуют два уровня контроля. Вы определяете, что именно прослушивается, задавая адрес привязки для каждого сервиса. И вы определяете, что доступно извне, с помощью межсетевого экрана. На грамотно настроенном сервере используются оба метода: сервисы привязываются только к нужным интерфейсам, а межсетевой экран блокирует всё, что не было явно разрешено. Проверка прослушиваемых портов с помощью ss — это первый шаг; определение правил межсетевого экрана — второй, он описан в основах работы с UFW.
Здесь есть тонкий момент, на котором часто ошибаются. IPv4 и IPv6 — это разные протоколы, и межсетевой экран, настроенный только для IPv4, оставляет сервисы [::] доступными по IPv6. Этому специфическому сценарию посвящена отдельная статья: ловушка межсетевого экрана IPv6.
FAQ
Как узнать, какие порты открыты на сервере Linux?
Выполните sudo ss -tlnp для TCP или sudo ss -ulnp для UDP. Эти команды выводят список всех слушающих сокетов, портов, локальных адресов, к которым они привязаны, и процессов, владеющих ими. Изучите столбец Local Address: значения 0.0.0.0 или [::] означают, что сервис доступен из сети, тогда как 127.0.0.1 указывает на то, что сервис слушает только локальный интерфейс машины.
В чем разница между 0.0.0.0 и 127.0.0.1?
0.0.0.0 означает «слушать на всех IPv4-адресах», включая публичный, поэтому сервис будет доступен из сети. 127.0.0.1 — это loopback, адрес, который машина использует для связи с самой собой; он недоступен извне, поэтому сервис, привязанный к нему, доступен только локально. Привязывайте внутренние сервисы к 127.0.0.1, чтобы они не были доступны извне.
Нужно ли открывать порт в брандмауэре для работы сервиса?
Только для тех сервисов, к которым необходим доступ с других машин. Сервису, привязанному к 127.0.0.1, не требуется правило брандмауэра, так как никто извне не сможет к нему подключиться. Для сервиса на 0.0.0.0 или [::] необходимо правило брандмауэра, разрешающее трафик; по умолчанию доступ должен быть запрещён, пока вы не добавите соответствующее правило.
В чем разница между TCP-портом и UDP-портом?
TCP — это протокол с установлением соединения, используемый большинством сервисов, таких как SSH, веб-серверы и базы данных. UDP — это протокол без установления соединения, используемый DNS и некоторыми VPN. Один и тот же номер порта в TCP и UDP — это разные порты, поэтому 53/tcp и 53/udp — это разные вещи. При настройке правил брандмауэра необходимо указывать протокол, например 22/tcp.