Porty i nasłuchujące usługi
Moduł 5: Zabezpieczanie sieci · Czas czytania: 10 min
Cel lekcji: Po tej lekcji będą Państwo potrafili sprawdzić, które usługi nasłuchują na serwerze i na jakim adresie, wyjaśnić różnicę między 0.0.0.0 a 127.0.0.1 oraz skontrolować z zewnątrz, co każdy w internecie widzi na Państwa serwerze.
Kluczowe pojęcia: port, TCP i UDP, nasłuchiwanie, ss -tulpn, 0.0.0.0 i [::], 127.0.0.1 i [::1], bind-address, otwarty, zamknięty i filtrowany, powierzchnia ataku, skanery
Jeden adres IP z 65 535 drzwiami
Państwa serwer ma adres IP, na przykład 192.0.2.10 i 2001:db8::10. Pod tym adresem może być jednocześnie dostępnych wiele programów, każdy na własnym porcie: liczbie od 1 do 65 535. Program, który przyjmuje połączenia, nasłuchuje na porcie. Kilka znanych przykładów:
| Port | Protokół | Usługa |
|---|---|---|
| 22 | TCP | SSH |
| 80 | TCP | http (serwer WWW) |
| 443 | TCP i UDP | https (UDP dla HTTP/3) |
| 25 | TCP | poczta między serwerami pocztowymi (SMTP) |
| 3306 | TCP | MySQL i MariaDB |
| 5432 | TCP | PostgreSQL |
| 6379 | TCP | Redis |
TCP to protokół dla połączeń, w których dane muszą dotrzeć niezawodnie (WWW, SSH, bazy danych). UDP służy do szybkich, pojedynczych pakietów (DNS, sieci VPN takie jak WireGuard, HTTP/3). Usługa nasłuchuje na TCP, na UDP albo na obu.
Każdy nasłuchujący port to drzwi do Państwa serwera. Za każdymi drzwiami działa oprogramowanie, które może zawierać błędy. Całość drzwi dostępnych z zewnątrz nazywa się powierzchnią ataku. Im mniejsza, tym lepiej: serwer ze stroną internetową potrzebuje z zewnątrz tylko portów 22, 80 i 443.
Sprawdzanie, co nasłuchuje: ss
Polecenie ss (socket statistics) pokazuje, co nasłuchuje na Państwa serwerze. Z opcjami -t (TCP), -u (UDP), -l (tylko nasłuchujące), -p (który program) i -n (numery zamiast nazw):
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))Najważniejsza kolumna to Local Address: adres, na którym program nasłuchuje.
| Adres | Znaczenie |
|---|---|
0.0.0.0 | Wszystkie adresy IPv4 serwera, a więc także adres publiczny: dostępny z zewnątrz (chyba że zablokuje go zapora) |
[::] | Wszystkie adresy IPv6: to samo dla IPv6 |
127.0.0.1 lub [::1] | Tylko sam serwer (loopback): nigdy niedostępny z zewnątrz |
127.0.0.53, 127.0.0.54 | Również loopback; tu nasłuchuje lokalny pomocnik DNS systemd-resolved |
192.0.2.10 | Tylko ten jeden adres |
W powyższym przykładzie MariaDB jest w porządku: nasłuchuje na 127.0.0.1, więc dostęp do niej mają tylko programy na samym serwerze (Państwa strona internetowa). Natomiast Redis nasłuchuje na 0.0.0.0:6379. Jeśli zapora nie jest poprawnie ustawiona, dostęp do niego ma cały internet. To dokładnie ten rodzaj błędu, o którym jest ta lekcja.
Nasłuchiwanie na właściwym adresie
Baza danych, pamięć podręczna (cache) czy panel administracyjny prawie nigdy nie powinny być dostępne z zewnątrz. Pierwszą i najlepszą obroną jest to, by usługa nasłuchiwała tylko na loopbacku. Zapora (lekcja 5.2) to druga warstwa; może zostać przypadkiem wyłączona lub nie obowiązywać (na przykład przy Dockerze, lekcja 9.3).
Miejsce tego ustawienia zależy od programu:
| Program | Ustawienie | Plik (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 i protected-mode yes | /etc/redis/redis.conf |
Pakiety Debiana i Ubuntu domyślnie ustawiają te usługi na localhost. Problem pojawia się zwykle wtedy, gdy ktoś postępuje według poradnika, który mówi: "ustaw bind-address na 0.0.0.0, aby łączyć się z zewnątrz". Jeśli chcą Państwo sami połączyć się z bazą danych ze swojego laptopa, prosimy użyć tunelu SSH (lekcja 2.3): port pozostaje zamknięty, a dostęp ma tylko ten, kto wejdzie przez SSH.
Po zmianie należy zrestartować usługę i ponownie sprawdzić wynik poleceniem ss -tulpn.
Otwarty, zamknięty i filtrowany
Widziany z zewnątrz port może być w jednym z trzech stanów:
- Otwarty (open): coś nasłuchuje i połączenie się udaje.
- Zamknięty (closed): nic nie nasłuchuje albo zapora aktywnie odmawia. Serwer od razu odsyła "nie" (przy TCP pakiet RST). Połączenie natychmiast kończy się błędem "Connection refused".
- Filtrowany (filtered): zapora po cichu odrzuca pakiet. Połączenie zawisa aż do przekroczenia limitu czasu (time-out).
Dla bazy danych stan zamknięty i filtrowany są oba dobre: nikt nie uzyska dostępu. Różnica mówi tylko dlaczego: filtrowany prawie zawsze oznacza, że blokuje to Państwa zapora.
Sprawdzanie z zewnątrz
ss pokazuje, co nasłuchuje na serwerze, ale nie to, co jest dostępne z zewnątrz. Pomiędzy jest jeszcze zapora, a u dostawcy czasem także zapora sieciowa. Jedyną prawdziwą kontrolą jest więc sprawdzenie z zewnątrz, z innego komputera.
Z własnego komputera (nie z samego serwera, bo wtedy ruch idzie przez loopback) można to zrobić dla jednego portu za pomocą 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!W systemie Windows to samo robi PowerShell poleceniem Test-NetConnection 192.0.2.10 -Port 6379. Skaner portów, taki jak nmap, może sprawdzić wiele portów naraz; prosimy używać takiego skanera wyłącznie na własnym serwerze.
Prosimy nie zapominać o IPv6. Częstym błędem jest zapora, która ma reguły tylko dla IPv4, podczas gdy usługa nasłuchuje również na [::]. Należy więc przetestować także adres IPv6: nc -6 -vz -w 3 2001:db8::10 6379.
Dlaczego to takie ważne
Państwa serwer jest skanowany od pierwszej minuty. Wyszukiwarki urządzeń i usług w internecie oraz boty przestępców nieustannie sprawdzają wszystkie adresy IPv4 na znanych portach. Otwarty Redis bez hasła, klaster Elasticsearch czy MongoDB bez kontroli dostępu zostaje znaleziony w krótkim czasie. Wycieki danych z otwartych baz danych i otwartych klastrów wyszukiwania regularnie trafiają do wiadomości i prawie zawsze chodzi o dokładnie ten błąd: usługa przeznaczona do użytku wewnętrznego nasłuchiwała na wszystkich adresach.
Również do portu SSH ktoś puka przez cały dzień. To normalne i przy kluczach (lekcja 2.2) oraz fail2ban (lekcja 5.3) nie stanowi problemu.
Kontrola w ramach kursu
W zadaniu do tej lekcji program kursu sprawdza z zewnątrz pięć stałych portów baz danych Państwa serwera: 3306 (MySQL/MariaDB), 5432 (PostgreSQL), 6379 (Redis), 9200 (Elasticsearch/OpenSearch) i 27017 (MongoDB). Program sprawdza jedynie, czy udaje się nawiązać połączenie, nie wysyła żadnych danych i nigdzie się nie loguje. Nie skanuje innych portów. Kontrole pochodzą z adresu IP podanego w zadaniu, dzięki czemu mogą je Państwo rozpoznać we własnym logu. Jeden adres można sprawdzić tylko kilka razy na godzinę.
W systemach AlmaLinux i Rocky Linux
ss działa tak samo. Pliki usług znajdują się w innych miejscach (na przykład /etc/my.cnf.d/ dla MariaDB, /var/lib/pgsql/data/postgresql.conf dla PostgreSQL). Ponadto SELinux może zablokować usługę, która chce nasłuchiwać na nietypowym porcie; widać to wtedy w journalctl (lekcja 6.2), a nie w ss.
Podsumowanie
- Każdy nasłuchujący port to drzwi; z zewnątrz prosimy zostawiać otwarte tylko to, co naprawdę potrzebne (zwykle 22, 80 i 443).
sudo ss -tulpnpokazuje, który program nasłuchuje na jakim adresie i porcie.0.0.0.0i[::]oznaczają "wszystkie adresy",127.0.0.1i[::1]oznaczają "tylko sam serwer". Bazy danych, pamięci podręczne i klastry wyszukiwania powinny działać na loopbacku.- Stan zamknięty i filtrowany są oba dobre dla bazy danych; otwarty jest błędem.
- Prosimy zawsze sprawdzać z zewnątrz, dla IPv4 i IPv6, ponieważ
ssnie widzi zapory.
Quiz
Zadanie
Zadanie Z5.1: Porty baz danych zamknięte z zewnątrz. Prosimy uruchomić sudo ss -tulpn na serwerze i ustalić, na jakich adresach nasłuchują Państwa usługi. Następnie prosimy zlecić programowi kursu sprawdzenie z zewnątrz, że porty 3306, 5432, 6379, 9200 i 27017 Państwa serwera są niedostępne, dla IPv4 oraz (jeśli serwer ma rekord AAAA) IPv6. Prosimy również wpisać, które usługi u Państwa nasłuchują na 0.0.0.0 lub [::]. Program nawiązuje połączenie tylko z tymi pięcioma portami i niczego nie wysyła.
