SSD Nodes Learn Hosting plans →
Посібники Matt ConnorВід Matt Connor

Що таке порт і як Linux-сервіси слухають мережу

Розберіться, як порт спрямовує трафік до сервісу, перевірте прослуховування командою ss і відрізніть локальний порт від доступного з Інтернету.

Що насправді таке порт

Порт — це номер, який дає змогу одному серверу одночасно запускати багато сервісів, не змішуючи їхній мережевий трафік. Ваш VPS має одну IP-адресу, але на ньому можуть одночасно працювати вебсервер, SSH-сервер і база даних. Коли надходить пакет, операційній системі потрібно визначити, для якого з цих сервісів він призначений. На це вказує номер порту. HTTPS-трафік зазвичай надходить на порт 443, а SSH — на порт 22. IP-адреса доставляє пакет на ваш сервер, а порт — потрібній програмі на цьому сервері.

Порт — це 16-бітове число: 16 бітів дають діапазон від 0 до 65535, а 0 зарезервований, тому на практиці порти мають номери від 1 до 65535. Порти з номерами менше ніж 1024 є «відомими» портами. За замовчуванням Linux дає змогу відкривати їх лише root або програмі, якій надано capability CAP_NET_BIND_SERVICE. Саме тому стандартні сервіси використовують ці порти: 22 для SSH, 80 для HTTP, 443 для HTTPS, 53 для DNS. Параметр sysctl net.ipv4.ip_unprivileged_port_start може змінити цю межу, але за замовчуванням вона становить 1024. Будь-які порти з номером 1024 і вище можуть використовувати звичайні програми.

Є два типи портів: TCP і UDP. Номер порту в одному з них не залежить від такого самого номера в іншому. TCP — протокол на основі з’єднання, який використовує більшість сервісів, зокрема SSH, HTTP і бази даних. UDP не встановлює з’єднання; його використовують, наприклад, DNS і деякі VPN. Під час відкриття порту у firewall зазвичай потрібно вказати тип протоколу, наприклад 22/tcp.

Прослуховування означає, що програма очікує підключення на порту

Програма, яка має приймати підключення, просить ядро «прослуховувати» порт. Від цього моменту порт відкритий на машині, а програма відповідає на все, що надходить на цей порт, з урахуванням правил firewall. Порт, який ніхто не прослуховує, просто відхиляє підключення. Тому перше питання під час будь-якої перевірки безпеки таке: що прослуховує порт і де саме.

Команда для цього — 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, якщо це дозволяє firewall.

[::]:80 означає те саме для IPv6: слухати на всіх IPv6-адресах, зокрема публічних. Багато програм прив’язуються до цієї адреси за замовчуванням, а в Linux сокет :: часто також приймає IPv4-з’єднання.

127.0.0.1:5432 означає «слухати лише на loopback». 127.0.0.1 — це адреса, яку комп’ютер використовує для взаємодії із самим собою. За типовими налаштуваннями ядра вона недоступна для маршрутизації з інших систем. Сервіс, прив’язаний до цієї адреси, доступний лише з того самого сервера, а не з інтернету, навіть якщо firewall дозволяє цей порт. Наведений вище рядок Postgres за замовчуванням безпечний. Є виняток — параметр ядра route_localnet. За замовчуванням він вимкнений, але деякі інструменти вмикають його, зокрема kube-proxy у Kubernetes. Якщо його ввімкнено і налаштовано відповідну маршрутизацію або правила NAT, loopback-трафік може надходити ззовні. На кожному рядку sysctl -a | grep route_localnet має показувати = 0.

Практичне правило безпосередньо випливає з цього: база даних, кеш або панель адміністрування, якими користуються лише ваші застосунки, мають прив’язуватися до 127.0.0.1, а не до 0.0.0.0. Якщо сервіс ніколи не слухає на публічній адресі, ззовні немає доступної точки для атаки.

Слухати порт — не те саме, що бути доступним

Ще одна відмінність допомагає уникнути багатьох непорозумінь. Відкритий на комп’ютері порт, тобто порт, на якому слухає програма, — це не те саме, що доступний ззовні порт, для якого firewall пропускає трафік. Для підключення віддаленого клієнта мають виконуватися обидві умови. З боку клієнта ці два випадки також виглядають по-різному: відмова в підключенні зазвичай означає, що жодна програма не слухає порт, а зависання з подальшим очікуванням тайм-ауту зазвичай означає, що firewall відкинув пакет. Саме це повідомляють ці дві помилки SSH.

Отже, є два рівні керування. Ви визначаєте, що саме слухає порт, налаштовуючи адресу прив’язки кожного сервісу. Також ви визначаєте, до чого може отримати доступ зовнішній світ, за допомогою firewall. На належно налаштованому сервері використовуються обидва рівні: сервіси прив’язуються лише до потрібних адрес, а firewall забороняє все, що ви не дозволили явно. Перевірка активних портів за допомогою ss — це перший крок. Визначення того, що дозволяє firewall, — другий крок, описаний у матеріалі основи firewall з UFW.

Тут є важливий нюанс. IPv4 та IPv6 — окремі протоколи. Якщо firewall захищає лише IPv4, сервіси [::] залишаються відкритими через IPv6. Цій конкретній проблемі присвячено окремий матеріал: пастка firewall для 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, щоб вони не були доступні з мережі.

Чи потрібно відкривати порт у firewall, щоб сервіс працював?

Лише для сервісів, до яких мають підключатися інші комп’ютери. Сервіс, прив’язаний до 127.0.0.1, не потребує правила allow, оскільки за типовими налаштуваннями ядра зовнішні системи все одно не можуть до нього підключитися. Для сервісу на 0.0.0.0 або [::] потрібне правило allow, якщо firewall за замовчуванням забороняє вхідний трафік, як і має бути. Якщо firewall неактивний або його політика дозволяє весь трафік, такий сервіс уже доступний без будь-якого правила.

У чому різниця між TCP-портом і UDP-портом?

TCP працює зі встановленням з’єднання. Його використовує більшість сервісів, зокрема SSH, вебсервери та бази даних. UDP працює без встановлення з’єднання. Його використовують DNS і деякі VPN. Однакові номери в TCP та UDP є окремими портами, тому 53/tcp і 53/udp — це різні порти. Під час написання правил firewall потрібно вказувати протокол, наприклад 22/tcp.