Seznam otevřených portů je seznamem cest k serveru. Vše ostatní — firewally, WAF, detekce průniků — jsou nadstavby nad ním. Proto kontrola „co u mě naslouchá“ stojí v každém auditu na prvním místě a právě ona nejčastěji přináší nepříjemný výsledek: polovinu nalezeného neotevřel nikdo z vás, ale instalační skript nějakého balíčku.
Čteme výstup
sudo ss -tulpn
Přepínače: t — TCP, u — UDP, l — jen naslouchající, p — proces, n — bez převodu čísel na názvy. Bez sudo bude sloupec s procesem prázdný a smysl se ztrácí.
Dívat se je třeba na sloupec Local Address:Port a rozdíl je tam zásadní:
127.0.0.1:3306— služba je dostupná jen ze samotného stroje. To je dobře;0.0.0.0:3306— ze všech adres IPv4, tedy z internetu. To je třeba prověřit;[::]:3306— totéž pro IPv6. Samostatný řádek, na který se pravidelně zapomíná;203.0.113.25:443— na konkrétní adrese, obvykle vědomě.
Dále u každého řádku s 0.0.0.0 nebo [::] položíte jedinou otázku: má se sem cizí člověk dostat? Pro 80 a 443 je odpověď ano. Pro téměř vše ostatní ne.
Obvyklé nálezy
Redis, port 6379. Nejnebezpečnější možný řádek. Ve výchozím stavu Redis nevyžaduje heslo a jeho příkazy umožňují zapsat soubor na disk — tedy cizí klíč do authorized_keys. Mezi objevením Redisu na veřejné adrese a jeho zneužitím uplynou hodiny, někdy méně. Ověřte bind 127.0.0.1 a protected-mode yes v konfiguraci.
Memcached, 11211/UDP. I když uvnitř není nic cenného, váš server se stane zesilovačem cizích útoků — a stížnosti přijdou od poskytovatele hostingu.
MySQL a PostgreSQL, 3306 a 5432. Heslo je, ale hádání probíhá nepřetržitě a verze databází se aktualizují méně často, než by měly. Ven nejsou potřeba téměř nikdy: aplikace je na témže stroji a k práci stačí SSH tunel.
Elasticsearch 9200, MongoDB 27017. Historicky bez výchozí autentizace. Veřejné instance těchto služeb jsou stálým zdrojem zpráv o únicích.
API Dockeru, 2375. Otevřený řídicí port Dockeru je root na stroji zcela bez hesla. Objevuje se obvykle po experimentech se vzdáleným přístupem k Dockeru.
Ovládací panely a phpMyAdmin na svých portech: 8080, 8083, 10000. Nejde o to, že by se nikdy nesměly otevírat, ale právě ony na sebe stahují hlavní proud pokusů.
Opravovat na úrovni služby, ne firewallu
Pokušení zavřít každý nález pravidlem UFW je pochopitelné, ale je to druhá linie, ne první. Pravidlo lze omylem smazat, firewall na chvíli vypnout při ladění a Docker publikuje porty zcela mimo UFW. Nastavení vazby v konfiguraci služby tohle všechno přežije:
- MySQL/MariaDB —
bind-address = 127.0.0.1; - PostgreSQL —
listen_addresses = 'localhost'; - Redis —
bind 127.0.0.1 ::1; - Docker Compose — publikování jako
"127.0.0.1:5432:5432".
Firewall se přidává navrch jako pojistka, ne místo toho.
Najít proces, když nevíte, co to je
ss ukáže název a pid. Dále:
sudo systemctl status <pid>
sudo lsof -i :8080
První příkaz pojmenuje jednotku systemd, k níž proces patří — obvykle to stačí k pochopení, co to je a zda je potřeba. Neznámý proces naslouchající na vysokém portu a spuštěný mimo systémové adresáře — například z /tmp nebo /dev/shm — už není otázkou konfigurace, ale důvodem k samostatnému vyšetřování.
Kontrola zvenčí je povinná
ss odpovídá na otázku „co naslouchá“, ne „kam se dá dostat“. Mezi tím stojí firewall, NAT a pravidla poskytovatele. Jedinou poctivou odpověď dá skenování z jiného stroje:
nmap -Pn -p- 203.0.113.25
nmap -Pn -p- -6 2001:db8::1
Druhý příkaz nevynechávejte: adresu IPv6 má téměř každý VPS, pravidla pro ni se píší zvlášť a služba naslouchá na obou verzích protokolu současně.
Tohle není jednorázová kontrola
Seznam otevřených portů se mění sám. Nainstalovali jste balíček — přinesl službu a otevřel port. Aktualizovali jste panel — obnovil výchozí nastavení. Spustili jste kontejner — publikoval port mimo firewall. Jednorázová kontrola odpovídá za dnešek a za nic víc.
Hodnota netkví v samotném seznamu, ale v jeho změnách: nový port, který včera nebyl, je krátký a velmi výmluvný signál. Právě tak se na něj vyplatí dívat — jako na snímek s historií, ne jako na výstup ss reprodukovaný z paměti. Ukázková stránka níže ukazuje přesně to.