Открытые порты — это сетевые “входы” на сервер. Через них работают SSH, веб-сервер, базы данных, панели управления, почтовые сервисы, Docker-приложения и другие службы.

Чем больше портов открыто наружу, тем больше потенциальная поверхность атаки. Поэтому после установки VPS или dedicated server важно проверить, какие сервисы слушают сеть, какие из них доступны из интернета и что действительно нужно оставить открытым.

В этой статье рассмотрим 5 основных решений:

  1. Проверить открытые порты на сервере
  2. Проверить, какие порты видны снаружи
  3. Определить, какие порты действительно нужны
  4. Остановить или ограничить лишние сервисы
  5. Закрыть лишние порты через firewall

1. Проверьте открытые порты на сервере

Сначала нужно понять, какие сервисы вообще слушают сеть на сервере.

Основная команда:

sudo ss -tulpn

Что означают параметры:

-t  — TCP-порты
-u  — UDP-порты
-l  — только listening-сокеты
-p  — показать процесс
-n  — не преобразовывать порты и IP в имена

Пример вывода:

Netid State  Local Address:Port  Process

tcp   LISTEN 0.0.0.0:22          users:(("sshd",pid=812,fd=3))
tcp   LISTEN 0.0.0.0:80          users:(("nginx",pid=1043,fd=6))
tcp   LISTEN 0.0.0.0:443         users:(("nginx",pid=1043,fd=7))
tcp   LISTEN 127.0.0.1:3306      users:(("mysqld",pid=1201,fd=21))

Важно понимать разницу:

0.0.0.0:PORT      — сервис слушает на всех интерфейсах
127.0.0.1:PORT    — сервис доступен только локально
PUBLIC_IP:PORT    — сервис слушает на публичном IP

Например:

0.0.0.0:22       — SSH потенциально доступен извне
0.0.0.0:80       — HTTP доступен извне
0.0.0.0:443      — HTTPS доступен извне
127.0.0.1:3306   — MySQL доступен только локально

Альтернативно можно использовать lsof:

sudo lsof -i -P -n | grep LISTEN

Эта команда удобна, если нужно быстро увидеть, какой процесс держит конкретный порт.

2. Проверьте, какие порты видны снаружи

Команды ss и lsof показывают, что слушает сам сервер. Но это не всегда означает, что порт доступен из интернета. Firewall может блокировать внешний доступ.

Поэтому важно проверить сервер снаружи, например через nmap с другого компьютера:

nmap -Pn SERVER_IP

Проверить конкретные порты:

nmap -Pn -p 22,80,443,3306,5432 SERVER_IP

Проверить диапазон портов:

nmap -Pn -p 1-10000 SERVER_IP

Разница простая:

ss/lsof  — показывает, что слушает сервер
nmap     — показывает, что видно извне

Если ss показывает порт, но nmap снаружи его не видит, значит порт слушается локально или закрыт firewall.

Если nmap показывает порт открытым, значит он доступен извне.

3. Определите, какие порты действительно нужны

Не каждый открытый порт является проблемой. Проблема возникает, когда наружу доступен сервис, который не должен быть публичным.

Для обычного веб-сервера обычно достаточно:

22/tcp    — SSH, желательно только для доверенных IP
80/tcp    — HTTP
443/tcp   — HTTPS

Остальные порты нужно проверять отдельно.

Типовые порты и рекомендации

Сервис

Порт

Нужно ли открывать наружу

SSH

22/tcp

Лучше только для доверенных IP или через VPN

HTTP

80/tcp

Да, если сервер обслуживает сайты

HTTPS

443/tcp

Да, если сервер обслуживает сайты

MySQL/MariaDB

3306/tcp

Обычно нет

PostgreSQL

5432/tcp

Обычно нет

Redis

6379/tcp

Нет

MongoDB

27017/tcp

Обычно нет

Proxmox VE

8006/tcp

Лучше только через VPN или allowlist

WHM/cPanel

2086/2087/tcp

Лучше ограничить по IP

Plesk

8443/tcp

Лучше ограничить по IP

Portainer

9000/9443/tcp

Лучше ограничить по IP или VPN

Важно
Базы данных, Redis, MongoDB и панели управления обычно не должны быть открыты для всего интернета.

4. Остановите лишние сервисы или ограничьте их localhost

Если сервис не нужен, его лучше остановить и отключить из автозапуска.

Проверить запущенные сервисы:

systemctl --type=service --state=running

Проверить конкретный сервис:

systemctl status SERVICE_NAME

Остановить сервис:

sudo systemctl stop SERVICE_NAME

Отключить автозапуск:

sudo systemctl disable SERVICE_NAME

Остановить и отключить сразу:

sudo systemctl disable --now SERVICE_NAME

Например, если Apache не используется:

sudo systemctl disable --now apache2

После этого снова проверьте порты:

sudo ss -tulpn

Если сервис нужен, но только локально, его лучше привязать к 127.0.0.1.

Например, для MariaDB/MySQL:

bind-address = 127.0.0.1

Для PostgreSQL:

listen_addresses = 'localhost'

Для Redis:

bind 127.0.0.1 ::1
protected-mode yes

После изменения конфигурации перезапустите сервис и проверьте порт:

sudo systemctl restart SERVICE_NAME
sudo ss -tulpn | grep PORT

Ожидаемый результат для локального сервиса:

127.0.0.1:PORT

Хорошая практика
Если база данных используется только сайтом или приложением на этом же сервере, не открывайте её на публичный IP.

5. Закройте лишние порты через firewall и проверьте Docker

Даже если сервис должен работать, это не значит, что он должен быть доступен всему интернету. Лишние порты нужно закрыть firewall-ом.

Если используется UFW, сначала проверьте статус:

sudo ufw status verbose

Разрешите только нужные порты:

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Если SSH должен быть доступен только с вашего IP:

sudo ufw allow from YOUR_TRUSTED_IP to any port 22 proto tcp
sudo ufw deny 22/tcp

Закрыть лишний порт, например MySQL:

sudo ufw deny 3306/tcp

Включить firewall:

sudo ufw enable

Проверить правила:

sudo ufw status numbered

Предупреждение
Перед включением firewall убедитесь, что SSH-порт разрешён для вашего IP. Иначе можно потерять доступ к серверу.

Отдельно проверьте Docker, если он установлен:

docker ps

Опасный пример:

0.0.0.0:5432->5432/tcp
0.0.0.0:6379->6379/tcp

Это означает, что PostgreSQL или Redis опубликованы наружу.

Если база данных нужна только другим контейнерам, не публикуйте её через ports.

Плохо:

ports:
  - "5432:5432"

Лучше:

services:
 postgres:
   image: postgres:16
   networks:
     - internal
networks:
  internal:

Важно
Docker может публиковать порты на хосте. После запуска контейнеров всегда проверяйте docker ps, ss -tulpn и внешний nmap.

Частые ошибки

Открытая база данных

Порт 3306, 5432, 6379 или 27017 открыт на 0.0.0.0 и доступен из интернета. Это опасно, особенно если пароль слабый или сервис настроен без дополнительной защиты.

Закрыли SSH и потеряли доступ

Перед изменением firewall-правил всегда проверяйте, что SSH разрешён для вашего IP. Не закрывайте текущую SSH-сессию, пока не открыли новую и не убедились, что вход работает.

Остановили сервис, но не отключили автозапуск

После перезагрузки сервер снова открывает порт, потому что сервис остался в автозапуске.

Docker открыл порт наружу

В docker-compose.yml указали:

ports:
  - "5432:5432"

В результате база данных стала доступна с публичного IP. Если доступ нужен только между контейнерами, используйте внутреннюю Docker-сеть без публикации порта.

Сервис слушает 0.0.0.0 вместо 127.0.0.1

Если сервис нужен только локально, лучше привязать его к localhost.

Итог

В этой статье мы рассмотрели только 5 основных решений.

Для обычного веб-сервера чаще всего достаточно оставить открытыми:

22/tcp   — SSH, желательно только с доверенных IP
80/tcp   — HTTP
443/tcp  — HTTPS

Все остальные порты должны быть либо закрыты, либо доступны только из доверенной сети, VPN или внутренней Docker-сети. Такой подход снижает риск атак и делает сервер безопаснее для production-нагрузок.

Tagged: