5 modulis · 5.1
Prievadai ir klausančios paslaugos
5 modulis: Tinklo apsauga · Skaitymo laikas: 10 min.
Mokymosi tikslas: po šios pamokos galėsite matyti, kurios paslaugos klauso Jūsų serveryje ir kokiu adresu, paaiškinti skirtumą tarp 0.0.0.0 ir 127.0.0.1 bei iš išorės patikrinti, ką apie Jūsų serverį mato visi internete.
Pagrindinės sąvokos: prievadas, TCP ir UDP, klausymas, ss -tulpn, 0.0.0.0 ir [::], 127.0.0.1 ir [::1], bind-address, atviras, uždarytas ir filtruojamas, atakos paviršius, skeneriai
Vienas IP adresas su 65.535 durimis
Jūsų serveris turi IP adresą, pavyzdžiui, 192.0.2.10 ir 2001:db8::10. Tuo adresu vienu metu gali būti pasiekiamos kelios programos, kiekviena per savo prievadą (angl. port): skaičių nuo 1 iki 65.535. Programa, kuri priima ryšius, klauso prievade. Keli žinomi prievadai:
| Prievadas | Protokolas | Paslauga |
|---|---|---|
| 22 | TCP | SSH |
| 80 | TCP | http (žiniatinklio serveris) |
| 443 | TCP ir UDP | https (UDP skirtas HTTP/3) |
| 25 | TCP | paštas tarp pašto serverių (SMTP) |
| 3306 | TCP | MySQL ir MariaDB |
| 5432 | TCP | PostgreSQL |
| 6379 | TCP | Redis |
TCP yra protokolas ryšiams, kurių duomenys turi patikimai pasiekti tikslą (žiniatinklis, SSH, duomenų bazės). UDP skirtas greitiems pavieniams paketams (DNS, VPN, pavyzdžiui, WireGuard, HTTP/3). Paslauga klauso per TCP, UDP arba abu.
Kiekvienas klausantis prievadas yra durys į Jūsų serverį. Už kiekvienų durų yra programinė įranga, kurioje gali būti klaidų. Visos iš išorės pasiekiamos durys kartu vadinamos Jūsų atakos paviršiumi. Kuo jis mažesnis, tuo geriau: serveriui su svetaine iš išorės reikia tik 22, 80 ir 443.
Ką klauso serveris: ss
Komanda ss (socket statistics) parodo, kas klauso Jūsų serveryje. Su parinktimis -t (TCP), -u (UDP), -l (tik klausantys), -p (kuri programa) ir -n (skaičiai, o ne pavadinimai):
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))Svarbiausias stulpelis yra Local Address: adresas, kuriuo programa klauso.
| Adresas | Reikšmė |
|---|---|
0.0.0.0 | Visi serverio IPv4 adresai, taigi ir viešasis: pasiekiama iš išorės (nebent užkarda tai sustabdo) |
[::] | Visi IPv6 adresai: tas pats, tik IPv6 |
127.0.0.1 arba [::1] | Tik pats serveris (loopback): iš išorės niekada nepasiekiama |
127.0.0.53, 127.0.0.54 | Taip pat loopback; čia klauso vietinis systemd-resolved DNS pagalbininkas |
192.0.2.10 | Tik tas vienas adresas |
Aukščiau pateiktame pavyzdyje MariaDB sukonfigūruota tinkamai: ji klauso 127.0.0.1, todėl prie jos gali prisijungti tik programos pačiame serveryje (Jūsų svetainė). Tačiau Redis klauso 0.0.0.0:6379. Jei užkarda nustatyta netinkamai, prie jos gali prisijungti visas internetas. Būtent apie tokią klaidą ir yra ši pamoka.
Klausymas tinkamu adresu
Duomenų bazė, podėlis ar valdymo skydelis beveik niekada neturėtų būti pasiekiami iš išorės. Pirmoji ir geriausia apsauga yra tai, kad paslauga klauso tik loopback. Užkarda (pamoka 5.2) yra antrasis sluoksnis; ji gali būti netyčia išjungta arba negalioti (pavyzdžiui, naudojant Docker, pamoka 9.3).
Kur tai nustatoma, priklauso nuo programos:
| Programa | Nustatymas | Failas (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 ir protected-mode yes | /etc/redis/redis.conf |
Debian ir Ubuntu paketai šias paslaugas pagal numatytuosius nustatymus jau nukreipia į localhost. Dažniausiai problemos kyla, kai kas nors vadovaujasi instrukcija, kurioje sakoma "nustatykite bind-address į 0.0.0.0, kad galėtumėte jungtis iš išorės". Jei patys norite pasiekti duomenų bazę iš savo nešiojamojo kompiuterio, naudokite SSH tunelį (pamoka 2.3): prievadas lieka uždarytas, o prisijungti gali tik tas, kas jungiasi per SSH.
Atlikę pakeitimą, paleiskite paslaugą iš naujo ir dar kartą patikrinkite su ss -tulpn.
Atviras, uždarytas ir filtruojamas
Žiūrint iš išorės, prievadas gali būti vienos iš trijų būsenų:
- Atviras (open): kažkas klauso ir ryšys užmezgamas.
- Uždarytas (closed): niekas neklauso arba užkarda aktyviai atmeta. Serveris iškart atsako "ne" (TCP atveju RST paketu). Ryšys iškart nepavyksta su pranešimu "Connection refused".
- Filtruojamas (filtered): užkarda tyliai išmeta paketą. Ryšys kabo, kol baigiasi laukimo laikas (time-out).
Duomenų bazei tinka ir uždarytas, ir filtruojamas: niekas prie jos neprisijungia. Skirtumas parodo tik kodėl: filtruojamas beveik visada reiškia, kad ryšį sustabdo Jūsų užkarda.
Patikrinimas iš išorės
ss parodo, kas klauso serveryje, bet ne tai, kas pasiekiama iš išorės. Tarp jų dar yra užkarda, o pas paslaugų teikėją kartais ir tinklo užkarda. Todėl vienintelis tikras patikrinimas yra žiūrėti iš išorės, iš kito kompiuterio.
Iš savo kompiuterio (ne iš paties serverio, nes tada ryšys eina per loopback) vieną prievadą galite patikrinti su 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 sistemoje tą patį atlieka PowerShell su Test-NetConnection 192.0.2.10 -Port 6379. Prievadų skeneris, pavyzdžiui, nmap, gali patikrinti daugiau prievadų vienu metu; tokį skenerį naudokite tik savo serveriui.
Nepamirškite IPv6. Dažna klaida yra užkarda, turinti taisykles tik IPv4, nors paslauga klauso ir [::]. Todėl patikrinkite ir IPv6 adresą: nc -6 -vz -w 3 2001:db8::10 6379.
Kodėl tai taip svarbu
Jūsų serveris skenuojamas nuo pat pirmos minutės. Interneto įrenginių ir paslaugų paieškos sistemos bei nusikaltėlių robotai nuolat tikrina visus IPv4 adresus žinomuose prievaduose. Atvira Redis be slaptažodžio, Elasticsearch klasteris ar MongoDB be prieigos kontrolės randami labai greitai. Duomenų nutekėjimai dėl atvirų duomenų bazių ir atvirų paieškos klasterių reguliariai patenka į naujienas, ir beveik visada priežastis yra būtent ši klaida: vidiniam naudojimui skirta paslauga klausė visais adresais.
Į SSH prievadą taip pat beldžiamasi visą dieną. Tai įprasta ir su raktais (pamoka 2.2) bei fail2ban (pamoka 5.3) nėra problema.
Kurso patikrinimas
Šios pamokos užduotyje kurso programa iš išorės patikrina penkis nustatytus Jūsų serverio duomenų bazių prievadus: 3306 (MySQL/MariaDB), 5432 (PostgreSQL), 6379 (Redis), 9200 (Elasticsearch/OpenSearch) ir 27017 (MongoDB). Programa tik bando, ar užmezgamas ryšys, nesiunčia jokių duomenų ir niekur neprisijungia. Kitų prievadų ji neskenuoja. Patikrinimai atliekami iš užduotyje nurodyto IP adreso, todėl galėsite juos atpažinti savo žurnale. Vieną adresą galima patikrinti tik kelis kartus per valandą.
AlmaLinux ir Rocky Linux sistemose
ss veikia taip pat. Paslaugų failai yra kitose vietose (pavyzdžiui, /etc/my.cnf.d/ MariaDB, /var/lib/pgsql/data/postgresql.conf PostgreSQL). Be to, SELinux gali sustabdyti paslaugą, kuri nori klausyti neįprastame prievade; tai matysite journalctl (pamoka 6.2), o ne ss.
Santrauka
- Kiekvienas klausantis prievadas yra durys; iš išorės palikite atvira tik tai, ko tikrai reikia (dažniausiai 22, 80 ir 443).
sudo ss -tulpnparodo, kuri programa kokiu adresu ir kuriame prievade klauso.0.0.0.0ir[::]reiškia "visi adresai",127.0.0.1ir[::1]reiškia "tik pats serveris". Duomenų bazės, podėliai ir paieškos klasteriai turi klausyti loopback.- Duomenų bazei tinka ir uždarytas, ir filtruojamas; atviras yra klaida.
- Visada tikrinkite iš išorės, ir IPv4, ir IPv6, nes
ssnemato užkardos.
Testas (quiz)
Užduotis
Užduotis Z5.1: Duomenų bazių prievadai uždaryti iš išorės. Paleiskite sudo ss -tulpn savo serveryje ir išsiaiškinkite, kokiais adresais klauso Jūsų paslaugos. Tada leiskite kurso programai iš išorės patikrinti, kad Jūsų serverio prievadai 3306, 5432, 6379, 9200 ir 27017 nepasiekiami per IPv4 ir (jei Jūsų serveris turi AAAA įrašą) IPv6. Taip pat nurodykite, kurios Jūsų paslaugos klauso 0.0.0.0 arba [::]. Programa tik jungiasi prie tų penkių prievadų ir nieko nesiunčia.
