Открытые порты — это сетевые “входы” на сервер. Через них работают SSH, веб-сервер, базы данных, панели управления, почтовые сервисы, Docker-приложения и другие службы.
Чем больше портов открыто наружу, тем больше потенциальная поверхность атаки. Поэтому после установки VPS или dedicated server важно проверить, какие сервисы слушают сеть, какие из них доступны из интернета и что действительно нужно оставить открытым.
В этой статье рассмотрим 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-нагрузок.