5. modulis · 5.1
Porti un klausošie pakalpojumi
5. modulis: Tīkla aizsardzība · Lasīšanas laiks: 10 min.
Mācīšanās mērķis: Pēc šīs nodarbības Jūs varēsiet redzēt, kuri pakalpojumi klausās Jūsu serverī un uz kādas adreses, izskaidrot atšķirību starp 0.0.0.0 un 127.0.0.1, kā arī no ārpuses pārbaudīt, ko jebkurš internetā redz no Jūsu servera.
Pamatjēdzieni: ports, TCP un UDP, klausīšanās, ss -tulpn, 0.0.0.0 un [::], 127.0.0.1 un [::1], bind-address, atvērts, slēgts un filtrēts, uzbrukuma virsma, skeneri
IP adrese ar 65.535 durvīm
Jūsu serverim ir IP adrese, piemēram, 192.0.2.10 un 2001:db8::10. Uz šīs adreses vienlaikus var būt sasniedzamas vairākas programmas, katra uz sava porta: tas ir skaitlis no 1 līdz 65.535. Programma, kas pieņem savienojumus, klausās uz porta. Daži zināmi piemēri:
| Ports | Protokols | Pakalpojums |
|---|---|---|
| 22 | TCP | SSH |
| 80 | TCP | http (tīmekļa serveris) |
| 443 | TCP un UDP | https (UDP priekš HTTP/3) |
| 25 | TCP | pasts starp pasta serveriem (SMTP) |
| 3306 | TCP | MySQL un MariaDB |
| 5432 | TCP | PostgreSQL |
| 6379 | TCP | Redis |
TCP ir protokols savienojumiem, kuriem dati jānogādā uzticami (tīmeklis, SSH, datubāzes). UDP ir paredzēts ātrām atsevišķām paketēm (DNS, VPN, piemēram, WireGuard, HTTP/3). Pakalpojums klausās uz TCP, UDP vai abiem.
Katrs klausošais ports ir durvis uz Jūsu serveri. Aiz katrām durvīm ir programmatūra, kurā var būt kļūdas. Visu no ārpuses sasniedzamo durvju kopumu sauc par Jūsu uzbrukuma virsmu. Jo mazāka, jo labāk: serverim ar tīmekļa vietni no ārpuses vajag tikai 22, 80 un 443.
Kas klausās: ss
Komanda ss (socket statistics) parāda, kas klausās Jūsu serverī. Ar opcijām -t (TCP), -u (UDP), -l (tikai klausošie), -p (kura programma) un -n (skaitļi, nevis nosaukumi):
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))Svarīgākā kolonna ir Local Address: adrese, uz kuras programma klausās.
| Adrese | Nozīme |
|---|---|
0.0.0.0 | Visas servera IPv4 adreses, tātad arī publiskā adrese: sasniedzams no ārpuses (ja vien to neaptur ugunsmūris) |
[::] | Visas IPv6 adreses: tas pats IPv6 gadījumā |
127.0.0.1 vai [::1] | Tikai pats serveris (loopback): no ārpuses nekad nav sasniedzams |
127.0.0.53, 127.0.0.54 | Arī loopback; šeit klausās systemd-resolved lokālais DNS palīgs |
192.0.2.10 | Tikai šī viena adrese |
Iepriekš redzamajā piemērā ar MariaDB viss ir kārtībā: tā klausās uz 127.0.0.1, tātad tai var piekļūt tikai programmas pašā serverī (Jūsu vietne). Taču Redis klausās uz 0.0.0.0:6379. Ja ugunsmūris nav pareizi iestatīts, tam var piekļūt viss internets. Tieši par šādu kļūdu ir šī nodarbība.
Klausīšanās uz pareizās adreses
Datubāzei, kešatmiņai vai pārvaldības panelim gandrīz nekad nevajadzētu būt sasniedzamiem no ārpuses. Pirmā un labākā aizsardzība ir tā, ka pakalpojums klausās tikai uz loopback. Ugunsmūris (nodarbība 5.2) ir otrais slānis; tas var nejauši būt izslēgts vai nedarboties (piemēram, ar Docker, nodarbība 9.3).
Kur to iestatīt, atkarīgs no programmas:
| Programma | Iestatījums | Fails (Debian/Ubuntu) |
|---|---|---|
| MariaDB/MySQL | bind-address = 127.0.0.1 | /etc/mysql/mariadb.conf.d/50-server.cnf |
| PostgreSQL | listen_addresses = 'localhost' | /etc/postgresql/<versija>/main/postgresql.conf |
| Redis | bind 127.0.0.1 -::1 un protected-mode yes | /etc/redis/redis.conf |
Debian un Ubuntu pakotnes šos pakalpojumus pēc noklusējuma jau iestata uz localhost. Visbiežāk kļūda rodas, ja kāds seko pamācībai, kurā teikts "iestatiet bind-address uz 0.0.0.0, lai savienotos no ārpuses". Ja Jūs paši vēlaties piekļūt datubāzei no sava klēpjdatora, izmantojiet SSH tuneli (nodarbība 2.3): ports paliek slēgts, un piekļūt var tikai tas, kurš ienāk caur SSH.
Pēc izmaiņām restartējiet pakalpojumu un vēlreiz pārbaudiet ar ss -tulpn.
Atvērts, slēgts un filtrēts
No ārpuses skatoties, portam var būt trīs stāvokļi:
- Atvērts (open): kaut kas klausās, un savienojums izdodas.
- Slēgts (closed): nekas neklausās, vai ugunsmūris aktīvi atsaka. Serveris uzreiz atbild ar "nē" (TCP gadījumā ar RST paketi). Savienojums uzreiz neizdodas ar ziņojumu "Connection refused".
- Filtrēts (filtered): ugunsmūris klusi izmet paketi. Savienojums karājas līdz noildzei (time-out).
Jūsu datubāzei gan slēgts, gan filtrēts stāvoklis ir labs: neviens nevar tai piekļūt. Atšķirība Jums pasaka tikai kāpēc: filtrēts gandrīz vienmēr nozīmē, ka to aptur Jūsu ugunsmūris.
Skatīties no ārpuses
ss parāda, kas klausās serverī, bet ne to, kas ir sasniedzams no ārpuses. Starp tiem vēl ir ugunsmūris, un pakalpojumu sniedzējam dažkārt arī tīkla ugunsmūris. Tāpēc vienīgā īstā pārbaude ir: skatieties no ārpuses, no cita datora.
No sava datora (nevis no paša servera, jo tad Jūs izmantojat loopback) to var izdarīt ar nc (netcat) vienam portam:
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 sistēmā PowerShell to pašu dara ar Test-NetConnection 192.0.2.10 -Port 6379. Portu skeneris, piemēram, nmap, var pārbaudīt vairākus portus vienlaikus; izmantojiet šādu skeneri tikai savam serverim.
Neaizmirstiet par IPv6. Bieža kļūda ir ugunsmūris, kuram ir noteikumi tikai IPv4, kamēr pakalpojums klausās arī uz [::]. Tāpēc pārbaudiet arī IPv6 adresi: nc -6 -vz -w 3 2001:db8::10 6379.
Kāpēc tas ir tik svarīgi
Jūsu serveris tiek skenēts jau no pirmās minūtes. Meklētājprogrammas interneta ierīcēm un pakalpojumiem, kā arī noziedznieku boti nepārtraukti pārbauda visas IPv4 adreses uz zināmiem portiem. Atvērts Redis bez paroles, Elasticsearch klasteris vai MongoDB bez piekļuves kontroles tiek atrasts ļoti īsā laikā. Datu noplūdes atvērtu datubāzu un atvērtu meklēšanas klasteru dēļ regulāri nonāk ziņās, un gandrīz vienmēr iemesls ir tieši šī kļūda: pakalpojums, kas bija paredzēts iekšējai lietošanai, klausījās uz visām adresēm.
Arī pie SSH porta klauvē visu dienu. Tas ir normāli, un ar atslēgām (nodarbība 2.2) un fail2ban (nodarbība 5.3) tā nav problēma.
Kursa pārbaude
Šīs nodarbības uzdevumā kursa programma no ārpuses pārbauda piecus noteiktus Jūsu servera datubāzu portus: 3306 (MySQL/MariaDB), 5432 (PostgreSQL), 6379 (Redis), 9200 (Elasticsearch/OpenSearch) un 27017 (MongoDB). Programma tikai mēģina izveidot savienojumu, nesūta nekādus datus un nekur nepiesakās. Citus portus tā neskenē. Pārbaudes nāk no IP adreses, kas norādīta uzdevumā, lai Jūs tās varētu atpazīt savā žurnālā. Vienu adresi var pārbaudīt tikai dažas reizes stundā.
AlmaLinux un Rocky Linux
ss darbojas tāpat. Pakalpojumu faili atrodas citās vietās (piemēram, /etc/my.cnf.d/ MariaDB, /var/lib/pgsql/data/postgresql.conf PostgreSQL). Turklāt SELinux var apturēt pakalpojumu, kas vēlas klausīties uz neparasta porta; to tad redzēsiet journalctl (nodarbība 6.2), nevis ss.
Kopsavilkums
- Katrs klausošais ports ir durvis; no ārpuses atstājiet atvērtu tikai to, kas patiešām nepieciešams (parasti 22, 80 un 443).
sudo ss -tulpnparāda, kura programma klausās uz kādas adreses un kāda porta.0.0.0.0un[::]nozīmē "visas adreses",127.0.0.1un[::1]nozīmē "tikai pats serveris". Datubāzēm, kešatmiņām un meklēšanas klasteriem jāklausās uz loopback.- Datubāzei gan slēgts, gan filtrēts stāvoklis ir labs; atvērts ir kļūda.
- Vienmēr pārbaudiet no ārpuses, gan IPv4, gan IPv6, jo
ssneredz ugunsmūri.
Tests (quiz)
Uzdevums
Uzdevums Z5.1: Datubāzu porti slēgti no ārpuses. Palaidiet sudo ss -tulpn savā serverī un noskaidrojiet, uz kādām adresēm klausās Jūsu pakalpojumi. Pēc tam ļaujiet kursa programmai no ārpuses pārbaudīt, ka Jūsu servera porti 3306, 5432, 6379, 9200 un 27017 nav sasniedzami, gan IPv4, gan (ja Jūsu serverim ir AAAA ieraksts) IPv6. Norādiet arī, kuri Jūsu pakalpojumi klausās uz 0.0.0.0 vai [::]. Programma tikai izveido savienojumu ar šiem pieciem portiem un neko nesūta.
