Modul 5 · 5.1
Vrata in storitve, ki poslušajo
Modul 5: Zaščita omrežja · Čas branja: 10 minut
Učni cilj: Po tej lekciji boste znali ugotoviti, katere storitve poslušajo na Vašem strežniku in na katerem naslovu, pojasniti razliko med 0.0.0.0 in 127.0.0.1 ter od zunaj preveriti, kaj o Vašem strežniku vidijo vsi na internetu.
Ključni pojmi: vrata, TCP in UDP, poslušanje, ss -tulpn, 0.0.0.0 in [::], 127.0.0.1 in [::1], bind-address, odprta, zaprta in filtrirana vrata, napadalna površina, skenerji
En naslov IP s 65.535 vrati
Vaš strežnik ima naslov IP, na primer 192.0.2.10 in 2001:db8::10. Na tem naslovu je lahko hkrati dosegljivih več programov, vsak na svojih vratih (port): to je številka od 1 do 65.535. Program, ki sprejema povezave, posluša na vratih. Nekaj znanih vrat:
| Vrata | Protokol | Storitev |
|---|---|---|
| 22 | TCP | SSH |
| 80 | TCP | http (spletni strežnik) |
| 443 | TCP in UDP | https (UDP za HTTP/3) |
| 25 | TCP | pošta med poštnimi strežniki (SMTP) |
| 3306 | TCP | MySQL in MariaDB |
| 5432 | TCP | PostgreSQL |
| 6379 | TCP | Redis |
TCP je protokol za povezave, pri katerih morajo podatki zanesljivo prispeti (splet, SSH, podatkovne baze). UDP je namenjen hitrim posameznim paketom (DNS, VPN-ji, kot je WireGuard, HTTP/3). Storitev posluša na TCP, na UDP ali na obeh.
Vsaka vrata, na katerih nekaj posluša, so vhod v Vaš strežnik. Za vsakim vhodom je programska oprema, ki lahko vsebuje napake. Celoto vhodov, ki so dosegljivi od zunaj, imenujemo napadalna površina. Manjša kot je, tem bolje: strežnik s spletnim mestom od zunaj potrebuje samo vrata 22, 80 in 443.
Kaj posluša: ss
Ukaz ss (socket statistics) pokaže, kaj posluša na Vašem strežniku. Z možnostmi -t (TCP), -u (UDP), -l (samo vrata, ki poslušajo), -p (kateri program) in -n (številke namesto imen):
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))Najpomembnejši stolpec je Local Address: naslov, na katerem program posluša.
| Naslov | Pomen |
|---|---|
0.0.0.0 | Vsi naslovi IPv4 strežnika, torej tudi javni naslov: dosegljivo od zunaj (razen če to prepreči požarni zid) |
[::] | Vsi naslovi IPv6: enako za IPv6 |
127.0.0.1 ali [::1] | Samo strežnik sam (loopback): od zunaj nikoli dosegljivo |
127.0.0.53, 127.0.0.54 | Prav tako loopback; tukaj posluša lokalni pomočnik DNS storitve systemd-resolved |
192.0.2.10 | Samo ta en naslov |
V zgornjem primeru je MariaDB v redu: posluša na 127.0.0.1, zato do nje lahko dostopajo le programi na samem strežniku (Vaše spletno mesto). Redis pa posluša na 0.0.0.0:6379. Če požarni zid ni pravilno nastavljen, lahko do njega dostopa ves internet. Prav o takšni napaki govori ta lekcija.
Poslušanje na pravem naslovu
Podatkovna baza, predpomnilnik ali skrbniška plošča skoraj nikoli ne sme biti dosegljiva od zunaj. Prva in najboljša obramba je, da storitev posluša samo na loopbacku. Požarni zid (lekcija 5.2) je druga plast; ta je lahko pomotoma izklopljen ali pa ne velja (na primer pri Dockerju, lekcija 9.3).
Kje to nastavite, je odvisno od programa:
| Program | Nastavitev | Datoteka (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 in protected-mode yes | /etc/redis/redis.conf |
Paketi Debiana in Ubuntuja te storitve privzeto že nastavijo na localhost. Težave običajno nastanejo, ko nekdo sledi navodilom, ki pravijo "nastavite bind-address na 0.0.0.0, da se boste lahko povezali od zunaj". Če želite do podatkovne baze dostopati s svojega prenosnika, uporabite tunel SSH (lekcija 2.3): vrata ostanejo zaprta, do baze pa lahko pride le, kdor vstopi prek SSH.
Po spremembi storitev znova zaženite in ponovno preverite z ukazom ss -tulpn.
Odprta, zaprta in filtrirana vrata
Gledano od zunaj so lahko vrata v enem od treh stanj:
- Odprta (open): nekaj posluša in povezava uspe.
- Zaprta (closed): nič ne posluša ali pa požarni zid dejavno zavrača. Strežnik takoj vrne "ne" (pri TCP paket RST). Povezava takoj spodleti s sporočilom "Connection refused" (povezava zavrnjena).
- Filtrirana (filtered): požarni zid paket tiho zavrže. Povezava visi, dokler ne poteče čas (time-out).
Za Vašo podatkovno bazo sta zaprto in filtrirano stanje oba dobra: nihče ne pride do nje. Razlika Vam pove le, zakaj: filtrirano skoraj vedno pomeni, da promet ustavi Vaš požarni zid.
Pogled od zunaj
ss pokaže, kaj posluša na strežniku, ne pa tudi, kaj je dosegljivo od zunaj. Vmes je namreč še požarni zid, pri ponudniku včasih tudi omrežni požarni zid. Edino pravo preverjanje je zato: poglejte od zunaj, z drugega računalnika.
S svojega računalnika (ne s samega strežnika, saj bi šli tam prek loopbacka) lahko posamezna vrata preverite z ukazom 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!V sistemu Windows enako naredi PowerShell z ukazom Test-NetConnection 192.0.2.10 -Port 6379. Skener vrat, kot je nmap, lahko pregleda več vrat hkrati; tak skener uporabljajte samo na svojem strežniku.
Ne pozabite na IPv6. Pogosta napaka je požarni zid, ki ima pravila samo za IPv4, medtem ko storitev posluša tudi na [::]. Zato preizkusite tudi naslov IPv6: nc -6 -vz -w 3 2001:db8::10 6379.
Zakaj je to tako pomembno
Vaš strežnik je skeniran že od prve minute. Iskalniki naprav in storitev na internetu ter roboti kriminalcev neprestano preizkušajo vse naslove IPv4 na znanih vratih. Odprt Redis brez gesla, gruča Elasticsearch ali MongoDB brez nadzora dostopa so v kratkem času najdeni. Uhajanje podatkov zaradi odprtih podatkovnih baz in odprtih iskalnih gruč se redno pojavlja v novicah in skoraj vedno gre prav za to napako: storitev, namenjena notranji uporabi, je poslušala na vseh naslovih.
Tudi na vrata SSH nekdo trka ves dan. To je normalno in s ključi (lekcija 2.2) ter fail2ban (lekcija 5.3) ni težava.
Preverjanje v tečaju
Pri nalogi v tej lekciji program tečaja od zunaj preveri pet stalnih vrat podatkovnih baz na Vašem strežniku: 3306 (MySQL/MariaDB), 5432 (PostgreSQL), 6379 (Redis), 9200 (Elasticsearch/OpenSearch) in 27017 (MongoDB). Program le preizkusi, ali se vzpostavi povezava, ne pošilja podatkov in se nikamor ne prijavlja. Drugih vrat ne skenira. Preverjanja prihajajo z naslova IP, ki je naveden v nalogi, tako da jih lahko prepoznate v svojem dnevniku. Posamezen naslov je mogoče preveriti le nekajkrat na uro.
Na AlmaLinux in Rocky Linux
ss deluje enako. Datoteke storitev so na drugih mestih (na primer /etc/my.cnf.d/ za MariaDB, /var/lib/pgsql/data/postgresql.conf za PostgreSQL). Poleg tega lahko SELinux ustavi storitev, ki želi poslušati na nenavadnih vratih; to boste videli v journalctl (lekcija 6.2), ne pa v ss.
Povzetek
- Vsaka vrata, ki poslušajo, so vhod; od zunaj imejte odprto le tisto, kar je res potrebno (običajno 22, 80 in 443).
sudo ss -tulpnpokaže, kateri program posluša na katerem naslovu in katerih vratih.0.0.0.0in[::]pomenita "vsi naslovi",127.0.0.1in[::1]pa "samo strežnik sam". Podatkovne baze, predpomnilniki in iskalne gruče sodijo na loopback.- Zaprto in filtrirano stanje sta za podatkovno bazo oba dobra; odprto je napaka.
- Vedno preverite od zunaj, za IPv4 in IPv6, saj
ssne vidi požarnega zidu.
Kviz
Naloga
Naloga Z5.1: Vrata podatkovnih baz zaprta od zunaj. Na strežniku zaženite sudo ss -tulpn in ugotovite, na katerih naslovih poslušajo Vaše storitve. Nato naj program tečaja od zunaj preveri, da vrata 3306, 5432, 6379, 9200 in 27017 Vašega strežnika niso dosegljiva, za IPv4 in (če ima Vaš strežnik zapis AAAA) za IPv6. Vpišite tudi, katere storitve pri Vas poslušajo na 0.0.0.0 ali [::]. Program se poveže samo na teh pet vrat in ničesar ne pošilja.
