Zoznam otvorených portov je zoznamom ciest k serveru. Všetko ostatné — firewally, WAF, detekcia prienikov — sú nadstavby nad ním. Preto kontrola „čo u mňa počúva“ stojí v každom audite na prvom mieste a práve ona najčastejšie prináša nepríjemný výsledok: polovicu nájdeného neotvoril nikto z vás, ale inštalačný skript nejakého balíka.

Čítame výstup

sudo ss -tulpn

Prepínače: t — TCP, u — UDP, l — len počúvajúce, p — proces, n — bez prevodu čísel na názvy. Bez sudo bude stĺpec s procesom prázdny a zmysel sa stráca.

Pozerať sa treba na stĺpec Local Address:Port a rozdiel je tam zásadný:

  • 127.0.0.1:3306 — služba je dostupná len zo samotného stroja. To je dobre;
  • 0.0.0.0:3306 — zo všetkých adries IPv4, teda z internetu. To treba preveriť;
  • [::]:3306 — to isté pre IPv6. Samostatný riadok, na ktorý sa pravidelne zabúda;
  • 203.0.113.25:443 — na konkrétnej adrese, obvykle vedome.

Ďalej pri každom riadku s 0.0.0.0 alebo [::] položíte jedinú otázku: má sa sem cudzí človek dostať? Pre 80 a 443 je odpoveď áno. Pre takmer všetko ostatné nie.

Obvyklé nálezy

Redis, port 6379. Najnebezpečnejší možný riadok. V predvolenom stave Redis nevyžaduje heslo a jeho príkazy umožňujú zapísať súbor na disk — teda cudzí kľúč do authorized_keys. Medzi objavením Redisu na verejnej adrese a jeho zneužitím uplynú hodiny, niekedy menej. Overte bind 127.0.0.1 a protected-mode yes v konfigurácii.

Memcached, 11211/UDP. Aj keď vnútri nie je nič cenné, váš server sa stane zosilňovačom cudzích útokov — a sťažnosti prídu od poskytovateľa hostingu.

MySQL a PostgreSQL, 3306 a 5432. Heslo je, ale hádanie prebieha nepretržite a verzie databáz sa aktualizujú menej často, než by mali. Von nie sú potrebné takmer nikdy: aplikácia je na tom istom stroji a na prácu stačí SSH tunel.

Elasticsearch 9200, MongoDB 27017. Historicky bez predvolenej autentifikácie. Verejné inštancie týchto služieb sú stálym zdrojom správ o únikoch.

API Dockeru, 2375. Otvorený riadiaci port Dockeru je root na stroji úplne bez hesla. Objavuje sa obvykle po experimentoch so vzdialeným prístupom k Dockeru.

Ovládacie panely a phpMyAdmin na svojich portoch: 8080, 8083, 10000. Nejde o to, že by sa nikdy nesmeli otvárať, ale práve ony na seba sťahujú hlavný prúd pokusov.

Opravovať na úrovni služby, nie firewallu

Pokušenie zatvoriť každý nález pravidlom UFW je pochopiteľné, ale je to druhá línia, nie prvá. Pravidlo možno omylom zmazať, firewall na chvíľu vypnúť pri ladení a Docker publikuje porty úplne mimo UFW. Nastavenie väzby v konfigurácii služby toto všetko prežije:

  • MySQL/MariaDB — bind-address = 127.0.0.1;
  • PostgreSQL — listen_addresses = 'localhost';
  • Redis — bind 127.0.0.1 ::1;
  • Docker Compose — publikovanie ako "127.0.0.1:5432:5432".

Firewall sa pridáva navrch ako poistka, nie namiesto toho.

Nájsť proces, keď neviete, čo to je

ss ukáže názov a pid. Ďalej:

sudo systemctl status <pid>
sudo lsof -i :8080

Prvý príkaz pomenuje jednotku systemd, ku ktorej proces patrí — obvykle to stačí na pochopenie, čo to je a či je potrebné. Neznámy proces počúvajúci na vysokom porte a spustený mimo systémových adresárov — napríklad z /tmp alebo /dev/shm — už nie je otázkou konfigurácie, ale dôvodom na samostatné vyšetrovanie.

Kontrola zvonka je povinná

ss odpovedá na otázku „čo počúva“, nie „kam sa dá dostať“. Medzi tým stojí firewall, NAT a pravidlá poskytovateľa. Jedinú poctivú odpoveď dá skenovanie z iného stroja:

nmap -Pn -p- 203.0.113.25
nmap -Pn -p- -6 2001:db8::1

Druhý príkaz nevynechávajte: adresu IPv6 má takmer každý VPS, pravidlá pre ňu sa píšu zvlášť a služba počúva na oboch verziách protokolu súčasne.

Toto nie je jednorazová kontrola

Zoznam otvorených portov sa mení sám. Nainštalovali ste balík — priniesol službu a otvoril port. Aktualizovali ste panel — obnovil predvolené nastavenie. Spustili ste kontajner — publikoval port mimo firewallu. Jednorazová kontrola odpovedá za dnešok a za nič viac.

Hodnota netkvie v samotnom zozname, ale v jeho zmenách: nový port, ktorý včera nebol, je krátky a veľmi výrečný signál. Práve tak sa naň oplatí pozerať — ako na snímku s históriou, nie ako na výstup ss reprodukovaný z pamäte. Ukážková stránka nižšie ukazuje presne to.