Модул 5 · 5.1
Портове и слушащи услуги
Модул 5: Защита на мрежата · Време за четене: 10 минути
Цел на урока: След този урок ще можете да видите кои услуги слушат на Вашия сървър и на кой адрес, да обясните разликата между 0.0.0.0 и 127.0.0.1 и да проверите отвън какво вижда всеки в интернет от Вашия сървър.
Основни понятия: порт, TCP и UDP, слушане, ss -tulpn, 0.0.0.0 и [::], 127.0.0.1 и [::1], bind-address, отворен, затворен и филтриран, повърхност за атака, скенери
Един IP адрес с 65.535 врати
Вашият сървър има IP адрес, например 192.0.2.10 и 2001:db8::10. На този адрес могат едновременно да бъдат достъпни различни програми, всяка на собствен порт: число от 1 до 65.535. Програма, която приема връзки, слуша на даден порт. Няколко известни порта:
| Порт | Протокол | Услуга |
|---|---|---|
| 22 | TCP | SSH |
| 80 | TCP | http (уеб сървър) |
| 443 | TCP и UDP | https (UDP за HTTP/3) |
| 25 | TCP | поща между пощенски сървъри (SMTP) |
| 3306 | TCP | MySQL и MariaDB |
| 5432 | TCP | PostgreSQL |
| 6379 | TCP | Redis |
TCP е протоколът за връзки, при които данните трябва да пристигнат надеждно (уеб, SSH, бази данни). UDP е за бързи отделни пакети (DNS, VPN като WireGuard, HTTP/3). Една услуга слуша на TCP, на UDP или и на двата.
Всеки слушащ порт е врата към Вашия сървър. Зад всяка врата има софтуер, който може да съдържа грешки. Съвкупността от врати, достъпни отвън, се нарича Вашата повърхност за атака. Колкото по-малка е тя, толкова по-добре: сървър с уебсайт се нуждае отвън само от 22, 80 и 443.
Какво слуша: ss
Командата ss (socket statistics) показва какво слуша на Вашия сървър. С опциите -t (TCP), -u (UDP), -l (само слушащи), -p (коя програма) и -n (числа, а не имена):
anna@web1:~$ sudo ss -tulpn
Netid State Local Address:Port Peer Address:Port Process
udp UNCONN 127.0.0.54:53 0.0.0.0:* users:(("systemd-resolve",pid=402,fd=16))
tcp LISTEN 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=611,fd=3))
tcp LISTEN 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=902,fd=6))
tcp LISTEN 0.0.0.0:443 0.0.0.0:* users:(("nginx",pid=902,fd=7))
tcp LISTEN 127.0.0.1:3306 0.0.0.0:* users:(("mariadbd",pid=755,fd=21))
tcp LISTEN 0.0.0.0:6379 0.0.0.0:* users:(("redis-server",pid=780,fd=6))
tcp LISTEN [::]:22 [::]:* users:(("sshd",pid=611,fd=4))
tcp LISTEN [::]:80 [::]:* users:(("nginx",pid=902,fd=8))
tcp LISTEN [::]:443 [::]:* users:(("nginx",pid=902,fd=9))Най-важната колона е Local Address: адресът, на който слуша програмата.
| Адрес | Значение |
|---|---|
0.0.0.0 | Всички IPv4 адреси на сървъра, включително публичния: достъпен отвън (освен ако защитна стена не го блокира) |
[::] | Всички IPv6 адреси: същото за IPv6 |
127.0.0.1 или [::1] | Само самият сървър (loopback): никога не е достъпен отвън |
127.0.0.53, 127.0.0.54 | Също loopback; тук слуша локалният DNS помощник на systemd-resolved |
192.0.2.10 | Само този един адрес |
В примера по-горе MariaDB е наред: тя слуша на 127.0.0.1, така че само програми на самия сървър (Вашият уебсайт) имат достъп до нея. Redis обаче слуша на 0.0.0.0:6379. Ако защитната стена не е настроена правилно, целият интернет има достъп до него. Точно за този вид грешка става дума в този урок.
Слушане на правилния адрес
База данни, кеш или административен панел почти никога не бива да са достъпни отвън. Първата и най-добра защита е услугата да слуша само на loopback. Защитната стена (урок 5.2) е вторият слой; тя може по невнимание да е изключена или да не действа (например при Docker, урок 9.3).
Къде се настройва това, зависи от програмата:
| Програма | Настройка | Файл (Debian/Ubuntu) |
|---|---|---|
| MariaDB/MySQL | bind-address = 127.0.0.1 | /etc/mysql/mariadb.conf.d/50-server.cnf |
| PostgreSQL | listen_addresses = 'localhost' | /etc/postgresql/<versie>/main/postgresql.conf |
| Redis | bind 127.0.0.1 -::1 и protected-mode yes | /etc/redis/redis.conf |
Пакетите на Debian и Ubuntu по подразбиране вече настройват тези услуги на localhost. Обикновено проблемът възниква, когато някой следва ръководство, което казва "задайте bind-address на 0.0.0.0, за да се свързвате отвън". Ако самите Вие искате достъп до базата данни от лаптопа си, използвайте SSH тунел (урок 2.3): портът остава затворен и достъп има само този, който влезе през SSH.
След промяна рестартирайте услугата и проверете отново с ss -tulpn.
Отворен, затворен и филтриран
Погледнат отвън, един порт може да бъде в едно от три състояния:
- Отворен (open): нещо слуша и връзката се осъществява.
- Затворен (closed): нищо не слуша или защитна стена активно отказва. Сървърът веднага връща "не" (при TCP пакет RST). Връзката се проваля веднага с "Connection refused".
- Филтриран (filtered): защитна стена тихо изхвърля пакета. Връзката виси до изтичане на времето за изчакване (time-out).
За Вашата база данни и затворен, и филтриран са добре: никой няма достъп. Разликата Ви казва само защо: филтриран почти винаги означава, че Вашата защитна стена блокира връзката.
Проверка отвън
ss показва какво слуша на сървъра, но не и какво е достъпно отвън. Между тях стои защитната стена, а при Вашия доставчик понякога и мрежова защитна стена. Затова единствената истинска проверка е: погледнете отвън, от друг компютър.
От собствения Ви компютър (не от самия сървър, защото тогава минавате през loopback) това става с nc (netcat) за един порт:
anna@laptop:~$ nc -vz -w 3 192.0.2.10 6379
nc: connect to 192.0.2.10 port 6379 (tcp) failed: Connection refused
anna@laptop:~$ nc -vz -w 3 192.0.2.10 22
Connection to 192.0.2.10 22 port [tcp/ssh] succeeded!В Windows PowerShell прави същото с Test-NetConnection 192.0.2.10 -Port 6379. Скенер за портове като nmap може да провери много портове наведнъж; използвайте такъв скенер само за собствения си сървър.
Не забравяйте IPv6. Честа грешка е защитна стена, която има правила само за IPv4, докато услугата слуша и на [::]. Затова тествайте и IPv6 адреса: nc -6 -vz -w 3 2001:db8::10 6379.
Защо това е толкова важно
Вашият сървър бива сканиран от първата минута. Търсачки за устройства и услуги в интернет, както и ботове на престъпници, непрекъснато проверяват всички IPv4 адреси на известни портове. Отворен Redis без парола, клъстер на Elasticsearch или MongoDB без контрол на достъпа бива открит за кратко време. Изтичания на данни заради отворени бази данни и отворени клъстери за търсене редовно попадат в новините и почти винаги става дума точно за тази грешка: услуга, предназначена за вътрешна употреба, е слушала на всички адреси.
И на порта на SSH се чука по цял ден. Това е нормално и с ключове (урок 2.2) и fail2ban (урок 5.3) не е проблем.
Проверката от курса
В задачата към този урок програмата на курса проверява отвън пет фиксирани порта за бази данни на Вашия сървър: 3306 (MySQL/MariaDB), 5432 (PostgreSQL), 6379 (Redis), 9200 (Elasticsearch/OpenSearch) и 27017 (MongoDB). Програмата само опитва дали се осъществява връзка, не изпраща данни и никъде не влиза. Тя не сканира други портове. Проверките идват от IP адреса, посочен в задачата, за да можете да ги разпознаете в собствения си лог. Един адрес може да бъде проверен само няколко пъти на час.
На AlmaLinux и Rocky Linux
ss работи по същия начин. Файловете на услугите се намират на други места (например /etc/my.cnf.d/ за MariaDB, /var/lib/pgsql/data/postgresql.conf за PostgreSQL). Освен това SELinux може да спре услуга, която иска да слуша на необичаен порт; това ще видите в journalctl (урок 6.2), а не в ss.
Обобщение
- Всеки слушащ порт е врата; отвън оставяйте отворено само това, което наистина е нужно (обикновено 22, 80 и 443).
sudo ss -tulpnпоказва коя програма на кой адрес и на кой порт слуша.0.0.0.0и[::]означават "всички адреси",127.0.0.1и[::1]означават "само самият сървър". Базите данни, кешовете и клъстерите за търсене трябва да са на loopback.- Затворен и филтриран са добре за база данни; отворен е грешка.
- Винаги проверявайте отвън, за IPv4 и за IPv6, защото
ssне вижда защитната стена.
Тест (quiz)
Задача
Задача Z5.1: Портовете на базите данни са затворени отвън. Изпълнете sudo ss -tulpn на Вашия сървър и установете на кои адреси слушат Вашите услуги. След това оставете програмата на курса да провери отвън, че портовете 3306, 5432, 6379, 9200 и 27017 на Вашия сървър не са достъпни, за IPv4 и (ако сървърът Ви има AAAA запис) за IPv6. Посочете също кои услуги при Вас слушат на 0.0.0.0 или [::]. Програмата само осъществява връзка към тези пет порта и не изпраща нищо.
