Modul 5 · 5.1
Porte og lyttende tjenester
Modul 5: Afskærm netværket · Læsetid: 10 minutter
Læringsmål: Efter denne lektion kan du se, hvilke tjenester der lytter på din server og på hvilken adresse, forklare forskellen mellem 0.0.0.0 og 127.0.0.1 og tjekke udefra, hvad alle på internettet kan se af din server.
Centrale begreber: port, TCP og UDP, lytte, ss -tulpn, 0.0.0.0 og [::], 127.0.0.1 og [::1], bind-address, åben, lukket og filtreret, angrebsflade, scannere
En IP-adresse med 65.535 døre
Din server har en IP-adresse, for eksempel 192.0.2.10 og 2001:db8::10. På den adresse kan flere programmer være tilgængelige på samme tid, hver på sin egen port: et tal fra 1 til 65.535. Et program, der modtager forbindelser, lytter på en port. Et par kendte:
| Port | Protokol | Tjeneste |
|---|---|---|
| 22 | TCP | SSH |
| 80 | TCP | http (webserver) |
| 443 | TCP og UDP | https (UDP til HTTP/3) |
| 25 | TCP | mail mellem mailservere (SMTP) |
| 3306 | TCP | MySQL og MariaDB |
| 5432 | TCP | PostgreSQL |
| 6379 | TCP | Redis |
TCP er protokollen til forbindelser, der skal komme pålideligt frem (web, SSH, databaser). UDP er til hurtige, løse pakker (DNS, VPN'er som WireGuard, HTTP/3). En tjeneste lytter på TCP, UDP eller begge.
Hver lyttende port er en dør ind til din server. Bag hver dør sidder software, der kan indeholde fejl. Alle de døre, der kan nås udefra, kaldes din angrebsflade. Jo mindre, jo bedre: en server med et website har kun brug for 22, 80 og 443 udefra.
Se hvad der lytter: ss
Kommandoen ss (socket statistics) viser, hvad der lytter på din server. Med valgmulighederne -t (TCP), -u (UDP), -l (kun lyttende), -p (hvilket program) og -n (tal, ikke navne):
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 vigtigste kolonne er Local Address: adressen, som programmet lytter på.
| Adresse | Betydning |
|---|---|
0.0.0.0 | Alle serverens IPv4-adresser, altså også den offentlige adresse: kan nås udefra (medmindre en firewall stopper det) |
[::] | Alle IPv6-adresser: det samme for IPv6 |
127.0.0.1 eller [::1] | Kun selve serveren (loopback): kan aldrig nås udefra |
127.0.0.53, 127.0.0.54 | Også loopback; her lytter den lokale DNS-hjælper fra systemd-resolved |
192.0.2.10 | Kun den ene adresse |
I eksemplet ovenfor er MariaDB i orden: den lytter på 127.0.0.1, så kun programmer på selve serveren (dit website) kan komme til den. Men Redis lytter på 0.0.0.0:6379. Hvis firewallen ikke er sat rigtigt op, kan hele internettet komme til den. Det er præcis den slags fejl, denne lektion handler om.
Lyt på den rigtige adresse
En database, en cache eller et administrationspanel skal næsten aldrig kunne nås udefra. Det første og bedste forsvar er, at tjenesten kun lytter på loopback. En firewall (lektion 5.2) er det andet lag; den kan ved et uheld være slået fra eller ikke gælde (for eksempel med Docker, lektion 9.3).
Hvor du indstiller det, afhænger af programmet:
| Program | Indstilling | 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/<versie>/main/postgresql.conf |
| Redis | bind 127.0.0.1 -::1 og protected-mode yes | /etc/redis/redis.conf |
Pakkerne fra Debian og Ubuntu sætter allerede disse tjenester til localhost som standard. Det går som regel galt, når nogen følger en vejledning, der siger "sæt bind-address til 0.0.0.0 for at forbinde udefra". Vil du selv kunne komme til databasen fra din bærbare, så brug en SSH-tunnel (lektion 2.3): porten forbliver lukket, og kun den, der kommer ind via SSH, kan komme til den.
Efter en ændring genstarter du tjenesten og kigger igen med ss -tulpn.
Åben, lukket og filtreret
Set udefra kan en port være tre ting:
- Åben: noget lytter, og forbindelsen lykkes.
- Lukket (closed): intet lytter, eller en firewall afviser aktivt. Serveren sender straks et "nej" tilbage (ved TCP en RST-pakke). En forbindelse fejler med det samme med "Connection refused".
- Filtreret (filtered): en firewall smider pakken stille væk. Forbindelsen hænger, indtil der kommer en time-out.
For din database er lukket og filtreret begge gode: ingen kommer ind. Forskellen fortæller dig kun hvorfor: filtreret betyder næsten altid, at din firewall stopper det.
Kig udefra
ss viser, hvad der lytter på serveren, men ikke hvad der kan nås udefra. Der sidder nemlig en firewall imellem, og hos din udbyder nogle gange også en netværksfirewall. Den eneste rigtige kontrol er derfor: kig udefra, fra en anden computer.
Fra din egen computer (ikke fra selve serveren, for så går du via loopback) kan du gøre det med nc (netcat) for én 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 det samme med Test-NetConnection 192.0.2.10 -Port 6379. En portscanner som nmap kan undersøge flere porte på én gang; brug kun sådan en scanner på din egen server.
Glem ikke IPv6. En almindelig fejl er en firewall, der kun har regler for IPv4, mens tjenesten også lytter på [::]. Test derfor også IPv6-adressen: nc -6 -vz -w 3 2001:db8::10 6379.
Hvorfor det er så vigtigt
Din server bliver scannet fra første minut. Søgemaskiner for enheder og tjenester på internettet og kriminelles bots afprøver hele tiden alle IPv4-adresser på kendte porte. En åben Redis uden adgangskode, en Elasticsearch-klynge eller en MongoDB uden adgangskontrol bliver fundet på kort tid. Datalæk på grund af åbne databaser og åbne søgeklynger er jævnligt i nyhederne, og det handler næsten altid om præcis denne fejl: en tjeneste, der var tænkt til intern brug, lyttede på alle adresser.
Også SSH-porten får besøg hele dagen. Det er normalt og ikke et problem med nøgler (lektion 2.2) og fail2ban (lektion 5.3).
Kursets kontrol
I opgaven til denne lektion kontrollerer kursusprogrammet udefra fem faste databaseporte på din server: 3306 (MySQL/MariaDB), 5432 (PostgreSQL), 6379 (Redis), 9200 (Elasticsearch/OpenSearch) og 27017 (MongoDB). Programmet prøver kun, om der kan oprettes en forbindelse, sender ingen data og logger ikke ind nogen steder. Det scanner ingen andre porte. Kontrollerne kommer fra den IP-adresse, der står i opgaven, så du kan genkende dem i din egen log. En adresse kan kun kontrolleres et par gange i timen.
På AlmaLinux og Rocky Linux
ss virker på samme måde. Tjenesternes filer ligger andre steder (for eksempel /etc/my.cnf.d/ for MariaDB, /var/lib/pgsql/data/postgresql.conf for PostgreSQL). Derudover kan SELinux stoppe en tjeneste, der vil lytte på en usædvanlig port; det ser du så i journalctl (lektion 6.2) og ikke i ss.
Opsummering
- Hver lyttende port er en dør; hold kun det åbent udefra, som virkelig er nødvendigt (som regel 22, 80 og 443).
sudo ss -tulpnviser, hvilket program der lytter på hvilken adresse og hvilken port.0.0.0.0og[::]betyder "alle adresser",127.0.0.1og[::1]betyder "kun selve serveren". Databaser, caches og søgeklynger hører til på loopback.- Lukket og filtreret er begge gode for en database; åben er forkert.
- Kontrollér altid udefra, for både IPv4 og IPv6, for
sskan ikke se firewallen.
Quiz
Opgave
Opgave Z5.1: Databaseporte lukket udefra. Kør sudo ss -tulpn på din server, og find ud af, hvilke adresser dine tjenester lytter på. Lad derefter kursusprogrammet kontrollere udefra, at portene 3306, 5432, 6379, 9200 og 27017 på din server ikke kan nås, for IPv4 og (hvis din server har en AAAA-record) IPv6. Udfyld også, hvilke tjenester der hos dig lytter på 0.0.0.0 eller [::]. Programmet opretter kun en forbindelse til de fem porte og sender ingenting.
