Відкриті порти — це мережеві “входи” на сервер. Через них працюють 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