Porty a naslouchající služby
Modul 5: Zabezpečení sítě · Doba čtení: 10 min.
Cíl lekce: Po této lekci dokážete zjistit, které služby na Vašem serveru naslouchají a na jaké adrese, vysvětlit rozdíl mezi 0.0.0.0 a 127.0.0.1 a zvenčí ověřit, co z Vašeho serveru vidí kdokoli na internetu.
Klíčové pojmy: port, TCP a UDP, naslouchání, ss -tulpn, 0.0.0.0 a [::], 127.0.0.1 a [::1], bind-address, otevřený, zavřený a filtrovaný, útočná plocha, skenery
Jedna IP adresa s 65 535 dveřmi
Váš server má IP adresu, například 192.0.2.10 a 2001:db8::10. Na této adrese může být současně dostupných více programů, každý na vlastním portu: čísle od 1 do 65 535. Program, který přijímá spojení, na portu naslouchá. Několik známých portů:
| Port | Protokol | Služba |
|---|---|---|
| 22 | TCP | SSH |
| 80 | TCP | http (webový server) |
| 443 | TCP a UDP | https (UDP pro HTTP/3) |
| 25 | TCP | pošta mezi poštovními servery (SMTP) |
| 3306 | TCP | MySQL a MariaDB |
| 5432 | TCP | PostgreSQL |
| 6379 | TCP | Redis |
TCP je protokol pro spojení, u kterých musí data spolehlivě dorazit (web, SSH, databáze). UDP slouží pro rychlé samostatné pakety (DNS, VPN jako WireGuard, HTTP/3). Služba naslouchá na TCP, na UDP nebo na obou.
Každý naslouchající port jsou dveře do Vašeho serveru. Za každými dveřmi je software, který může obsahovat chyby. Souhrn všech dveří dostupných zvenčí se nazývá Vaše útočná plocha. Čím menší, tím lépe: server s webem potřebuje zvenčí jen porty 22, 80 a 443.
Co naslouchá: ss
Příkaz ss (socket statistics) ukazuje, co na Vašem serveru naslouchá. S volbami -t (TCP), -u (UDP), -l (jen naslouchající), -p (který program) a -n (čísla, ne názvy):
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))Nejdůležitější je sloupec Local Address: adresa, na které program naslouchá.
| Adresa | Význam |
|---|---|
0.0.0.0 | Všechny IPv4 adresy serveru, tedy i veřejná adresa: dostupné zvenčí (pokud to nezastaví firewall) |
[::] | Všechny IPv6 adresy: totéž pro IPv6 |
127.0.0.1 nebo [::1] | Pouze samotný server (loopback): zvenčí nikdy nedostupné |
127.0.0.53, 127.0.0.54 | Také loopback; zde naslouchá lokální pomocník DNS ze systemd-resolved |
192.0.2.10 | Pouze tato jedna adresa |
V příkladu výše je MariaDB v pořádku: naslouchá na 127.0.0.1, takže se k ní dostanou jen programy na samotném serveru (Váš web). Redis však naslouchá na 0.0.0.0:6379. Pokud firewall není správně nastavený, dostane se k němu celý internet. Přesně o tomto druhu chyby je tato lekce.
Naslouchání na správné adrese
Databáze, cache nebo administrační panel by téměř nikdy neměly být dostupné zvenčí. První a nejlepší obranou je, že služba naslouchá pouze na loopbacku. Firewall (lekce 5.2) je druhá vrstva; ten může být omylem vypnutý nebo se nemusí uplatnit (například u Dockeru, lekce 9.3).
Kde se to nastavuje, se liší podle programu:
| Program | Nastavení | Soubor (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 a protected-mode yes | /etc/redis/redis.conf |
Balíčky Debianu a Ubuntu tyto služby ve výchozím stavu nastavují na localhost. Chyba většinou vznikne, když někdo postupuje podle návodu, který říká "nastavte bind-address na 0.0.0.0, abyste se mohli připojit zvenčí". Pokud se chcete k databázi připojit sami ze svého notebooku, použijte SSH tunel (lekce 2.3): port zůstane zavřený a dostane se k němu jen ten, kdo přijde přes SSH.
Po změně službu restartujte a znovu se podívejte pomocí ss -tulpn.
Otevřený, zavřený a filtrovaný
Při pohledu zvenčí může být port ve třech stavech:
- Otevřený (open): něco naslouchá a spojení se podaří.
- Zavřený (closed): nic nenaslouchá, nebo firewall aktivně odmítá. Server okamžitě pošle zpět "ne" (u TCP paket RST). Spojení hned selže s hlášením "Connection refused" (spojení odmítnuto).
- Filtrovaný (filtered): firewall paket potichu zahodí. Spojení visí až do vypršení časového limitu (time-out).
Pro Vaši databázi jsou zavřený i filtrovaný stav v pořádku: nikdo se k ní nedostane. Rozdíl Vám říká jen proč: filtrovaný téměř vždy znamená, že to zastavuje Váš firewall.
Pohled zvenčí
ss ukazuje, co na serveru naslouchá, ale ne to, co je dostupné zvenčí. Mezi tím je ještě firewall a u Vašeho poskytovatele někdy i síťový firewall. Jedinou skutečnou kontrolou je proto: podívejte se zvenčí, z jiného počítače.
Z vlastního počítače (ne ze samotného serveru, protože tam byste šli přes loopback) to pro jeden port zvládnete 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!Ve Windows totéž udělá PowerShell pomocí Test-NetConnection 192.0.2.10 -Port 6379. Skener portů jako nmap dokáže prověřit více portů najednou; takový skener používejte pouze na vlastním serveru.
Nezapomeňte na IPv6. Častou chybou je firewall, který má pravidla jen pro IPv4, zatímco služba naslouchá i na [::]. Otestujte proto i IPv6 adresu: nc -6 -vz -w 3 2001:db8::10 6379.
Proč je to tak důležité
Váš server je skenován od první minuty. Vyhledávače zařízení a služeb na internetu i boti zločinců neustále zkoušejí všechny IPv4 adresy na známých portech. Otevřený Redis bez hesla, cluster Elasticsearch nebo MongoDB bez řízení přístupu se najde během krátké doby. Úniky dat kvůli otevřeným databázím a otevřeným vyhledávacím clusterům se pravidelně objevují ve zprávách a téměř vždy jde přesně o tuto chybu: služba určená pro interní použití naslouchala na všech adresách.
Také na port SSH někdo klepe celý den. To je normální a se SSH klíči (lekce 2.2) a fail2ban (lekce 5.3) to není problém.
Kontrola v kurzu
V úkolu k této lekci kurzovní program zvenčí zkontroluje pět pevně daných databázových portů Vašeho serveru: 3306 (MySQL/MariaDB), 5432 (PostgreSQL), 6379 (Redis), 9200 (Elasticsearch/OpenSearch) a 27017 (MongoDB). Program pouze zkouší, zda se naváže spojení, neposílá žádná data a nikam se nepřihlašuje. Jiné porty neskenuje. Kontroly přicházejí z IP adresy uvedené v úkolu, takže je můžete rozpoznat ve vlastním logu. Jednu adresu lze kontrolovat jen několikrát za hodinu.
Na AlmaLinux a Rocky Linux
ss funguje stejně. Soubory služeb jsou na jiných místech (například /etc/my.cnf.d/ pro MariaDB, /var/lib/pgsql/data/postgresql.conf pro PostgreSQL). Kromě toho může SELinux zablokovat službu, která chce naslouchat na neobvyklém portu; to pak uvidíte v journalctl (lekce 6.2), nikoli v ss.
Shrnutí
- Každý naslouchající port jsou dveře; zvenčí nechte otevřené jen to, co je opravdu potřeba (většinou 22, 80 a 443).
sudo ss -tulpnukazuje, který program naslouchá na jaké adrese a jakém portu.0.0.0.0a[::]znamenají "všechny adresy",127.0.0.1a[::1]znamenají "pouze samotný server". Databáze, cache a vyhledávací clustery patří na loopback.- Zavřený i filtrovaný stav jsou pro databázi v pořádku; otevřený je chyba.
- Vždy kontrolujte zvenčí, pro IPv4 i IPv6, protože
ssfirewall nevidí.
Kvíz
Úkol
Úkol Z5.1: Databázové porty uzavřené zvenčí. Spusťte na serveru sudo ss -tulpn a zjistěte, na jakých adresách Vaše služby naslouchají. Potom nechte kurzovní program zvenčí ověřit, že porty 3306, 5432, 6379, 9200 a 27017 Vašeho serveru nejsou dostupné, pro IPv4 a (pokud má Váš server záznam AAAA) pro IPv6. Vyplňte také, které služby u Vás naslouchají na 0.0.0.0 nebo [::]. Program se pouze připojí k těmto pěti portům a nic neposílá.
