Modul 5 · 5.1
Portar och tjänster som lyssnar
Modul 5: Skydda nätverket · Lästid: 10 minuter
Lärandemål: Efter den här lektionen kan du se vilka tjänster som lyssnar på din server och på vilken adress. Du kan förklara skillnaden mellan 0.0.0.0 och 127.0.0.1, och du kan kontrollera utifrån vad alla på internet ser av din server.
Nyckelbegrepp: port, TCP och UDP, lyssna, ss -tulpn, 0.0.0.0 och [::], 127.0.0.1 och [::1], bind-address, öppen, stängd och filtrerad, attackyta, skannrar
En IP-adress med 65.535 dörrar
Din server har en IP-adress, till exempel 192.0.2.10 och 2001:db8::10. På den adressen kan flera program vara nåbara samtidigt, vart och ett på en egen port: ett nummer från 1 till 65.535. Ett program som tar emot anslutningar lyssnar på en port. Några välkända:
| Port | Protokoll | Tjänst |
|---|---|---|
| 22 | TCP | SSH |
| 80 | TCP | http (webbserver) |
| 443 | TCP och UDP | https (UDP för HTTP/3) |
| 25 | TCP | e-post mellan e-postservrar (SMTP) |
| 3306 | TCP | MySQL och MariaDB |
| 5432 | TCP | PostgreSQL |
| 6379 | TCP | Redis |
TCP är protokollet för anslutningar där allt måste komma fram tillförlitligt (webb, SSH, databaser). UDP är till för snabba, fristående paket (DNS, VPN som WireGuard, HTTP/3). En tjänst lyssnar på TCP, UDP eller båda.
Varje port som lyssnar är en dörr in till din server. Bakom varje dörr finns programvara som kan innehålla fel. Alla dörrar som går att nå utifrån kallas tillsammans din attackyta. Ju mindre, desto bättre: en server med en webbplats behöver bara 22, 80 och 443 utifrån.
Se vad som lyssnar: ss
Kommandot ss (socket statistics) visar vad som lyssnar på din server. Med flaggorna -t (TCP), -u (UDP), -l (bara lyssnande), -p (vilket program) och -n (nummer, inte namn):
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))Den viktigaste kolumnen är Local Address: adressen som programmet lyssnar på.
| Adress | Betydelse |
|---|---|
0.0.0.0 | Alla IPv4-adresser på servern, alltså även den publika adressen: nåbar utifrån (om inte en brandvägg stoppar det) |
[::] | Alla IPv6-adresser: samma sak för IPv6 |
127.0.0.1 eller [::1] | Bara servern själv (loopback): aldrig nåbar utifrån |
127.0.0.53, 127.0.0.54 | Också loopback; här lyssnar den lokala DNS-hjälpen i systemd-resolved |
192.0.2.10 | Bara just den adressen |
I exemplet ovan är MariaDB i ordning: den lyssnar på 127.0.0.1, så bara program på servern själv (din webbplats) kommer åt den. Men Redis lyssnar på 0.0.0.0:6379. Om brandväggen inte är rätt inställd kommer hela internet åt den. Det är precis den sortens fel som den här lektionen handlar om.
Lyssna på rätt adress
En databas, en cache eller en adminpanel ska nästan aldrig vara nåbar utifrån. Det första och bästa skyddet är att tjänsten bara lyssnar på loopback. En brandvägg (lektion 5.2) är det andra lagret; den kan av misstag vara avstängd eller inte gälla (till exempel med Docker, lektion 9.3).
Var du ställer in det skiljer sig mellan program:
| Program | Inställning | Fil (Debian/Ubuntu) |
|---|---|---|
| MariaDB/MySQL | bind-address = 127.0.0.1 | /etc/mysql/mariadb.conf.d/50-server.cnf |
| PostgreSQL | listen_addresses = 'localhost' | /etc/postgresql/<version>/main/postgresql.conf |
| Redis | bind 127.0.0.1 -::1 och protected-mode yes | /etc/redis/redis.conf |
Paketen i Debian och Ubuntu ställer redan in de här tjänsterna på localhost som standard. Det går oftast fel när någon följer en guide som säger "sätt bind-address till 0.0.0.0 för att ansluta utifrån". Vill du själv nå databasen från din laptop, använd då en SSH-tunnel (lektion 2.3): porten förblir stängd, och bara den som kommer in via SSH kommer åt den.
Efter en ändring startar du om tjänsten och kontrollerar igen med ss -tulpn.
Öppen, stängd och filtrerad
Sett utifrån kan en port vara i tre lägen:
- Öppen: något lyssnar och anslutningen lyckas.
- Stängd (closed): ingenting lyssnar, eller så nekar en brandvägg aktivt. Servern skickar direkt tillbaka ett "nej" (för TCP ett RST-paket). En anslutning misslyckas direkt med "Connection refused".
- Filtrerad (filtered): en brandvägg slänger paketet i tysthet. Anslutningen hänger tills den når en time-out.
För din databas är både stängd och filtrerad bra: ingen kommer åt den. Skillnaden säger dig bara varför: filtrerad betyder nästan alltid att din brandvägg stoppar trafiken.
Kontrollera utifrån
ss visar vad som lyssnar på servern, men inte vad som är nåbart utifrån. Där emellan finns en brandvägg, och hos din leverantör ibland även en nätverksbrandvägg. Den enda riktiga kontrollen är därför: titta utifrån, från en annan dator.
Från din egen dator (inte från servern själv, för då går du via loopback) kan du göra det med nc (netcat) för en enskild port:
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!På Windows gör PowerShell samma sak med Test-NetConnection 192.0.2.10 -Port 6379. En portskanner som nmap kan kontrollera fler portar på en gång; använd en sådan skanner bara på din egen server.
Glöm inte IPv6. Ett vanligt fel är en brandvägg som bara har regler för IPv4, medan tjänsten även lyssnar på [::]. Testa därför också IPv6-adressen: nc -6 -vz -w 3 2001:db8::10 6379.
Varför det här är så viktigt
Din server skannas från första minuten. Sökmotorer för enheter och tjänster på internet, och brottslingars botar, provar hela tiden alla IPv4-adresser på välkända portar. En öppen Redis utan lösenord, ett Elasticsearch-kluster eller en MongoDB utan åtkomstkontroll hittas inom kort tid. Dataläckor via öppna databaser och öppna sökkluster dyker regelbundet upp i nyheterna, och det handlar nästan alltid om exakt det här felet: en tjänst som var tänkt för internt bruk lyssnade på alla adresser.
Även SSH-porten får besök hela dagen. Det är normalt och inget problem med nycklar (lektion 2.2) och fail2ban (lektion 5.3).
Kurskontrollen
I uppgiften till den här lektionen kontrollerar kursprogrammet utifrån fem fasta databasportar på din server: 3306 (MySQL/MariaDB), 5432 (PostgreSQL), 6379 (Redis), 9200 (Elasticsearch/OpenSearch) och 27017 (MongoDB). Programmet provar bara om en anslutning kan upprättas, skickar inga data och loggar inte in någonstans. Det skannar inga andra portar. Kontrollerna kommer från IP-adressen som anges i uppgiften, så att du kan känna igen dem i din egen logg. En adress kan bara kontrolleras några gånger per timme.
På AlmaLinux och Rocky Linux
ss fungerar likadant. Tjänsternas filer ligger på andra ställen (till exempel /etc/my.cnf.d/ för MariaDB, /var/lib/pgsql/data/postgresql.conf för PostgreSQL). Dessutom kan SELinux stoppa en tjänst som vill lyssna på en ovanlig port; det ser du då i journalctl (lektion 6.2) och inte i ss.
Sammanfattning
- Varje port som lyssnar är en dörr; håll bara öppet utåt det som verkligen behövs (oftast 22, 80 och 443).
sudo ss -tulpnvisar vilket program som lyssnar på vilken adress och vilken port.0.0.0.0och[::]betyder "alla adresser",127.0.0.1och[::1]betyder "bara servern själv". Databaser, cachar och sökkluster hör hemma på loopback.- Stängd och filtrerad är båda bra för en databas; öppen är fel.
- Kontrollera alltid utifrån, för IPv4 och IPv6, eftersom
ssinte ser brandväggen.
Quiz
Uppgift
Uppgift Z5.1: Databasportar stängda utifrån. Kör sudo ss -tulpn på din server och ta reda på vilka adresser dina tjänster lyssnar på. Låt sedan kursprogrammet kontrollera utifrån att portarna 3306, 5432, 6379, 9200 och 27017 på din server inte är nåbara, för IPv4 och (om din server har en AAAA-post) IPv6. Fyll också i vilka tjänster som lyssnar på 0.0.0.0 eller [::] hos dig. Programmet ansluter bara till de fem portarna och skickar ingenting.
