Na strežniku vsaka omrežna storitev sprejema povezave na svojih vratih: SSH na 22, spletni strežnik na 80 in 443, MariaDB na 3306. Katera vrata so trenutno odprta in kateri program jih zaseda, izveš z ukazom ss. Ta članek pokaže tudi, zakaj ni dovolj, da vrata na strežniku poslušajo: od zunaj so dosegljiva le, če jih prepusti tudi požarni zid.
Ukaze smo novembra 2026 preizkusili v sistemu AlmaLinux 10.2, na katerem so tekli nginx, MariaDB, Valkey, aplikacija Node.js in Docker 29.9, ter v sistemu Ubuntu 26.04 z nginx. Na lastnem KVM VPS je seznam dobro občasno pregledati: vsaka po nepotrebnem odprta vrata so še ena površina za napad.
Vrata, ki poslušajo: ss -tulpn
ss je del paketa iproute (v Ubuntuju in Debianu iproute2), nameščen je v vseh današnjih distribucijah.
sudo ss -tulpn
Stikala:
-t: TCP;-u: UDP;-l: le vtičnice, ki poslušajo (listening), brez vzpostavljenih povezav;-p: ime in PID programa, ki zaseda vrata (process);-n: izpiše številke, ne imen storitev (:22, ne:ssh).
-p programe drugih uporabnikov (na primer root ali mysql) pokaže le s sudo; brez njega stolpec Process ostane prazen. Če te zanimajo le vrata, zadošča ss -tuln tudi brez sudo in se prilega tudi ozkemu oknu:
V preizkusu je bil izpis sudo ss -tulpn (skrajšano):
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
udp UNCONN 0 0 127.0.0.1:323 0.0.0.0:* users:(("chronyd",pid=642,fd=4))
tcp LISTEN 0 80 0.0.0.0:3306 0.0.0.0:* users:(("mariadbd",pid=839,fd=20))
tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=1217,fd=6),...)
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1188,fd=7))
tcp LISTEN 0 511 127.0.0.1:6379 0.0.0.0:* users:(("valkey-server",pid=1190,fd=8))
tcp LISTEN 0 511 [::]:80 [::]:* users:(("nginx",pid=1217,fd=7),...)
Stolpci izpisa
| Stolpec | Pomen |
|---|---|
Netid |
protokol: tcp ali udp |
State |
pri TCP LISTEN (posluša); UDP nima povezave, zato je tam UNCONN |
Recv-Q, Send-Q |
pri vtičnici, ki posluša, število čakajočih povezav oziroma velikost čakalne vrste; pri vsakdanji uporabi ni pomembno |
Local Address:Port |
naslov in vrata, na katerih program posluša |
Peer Address:Port |
pri vtičnici, ki posluša, * (povezavo lahko pričakuje od kjer koli) |
Process |
ime programa, PID in datotečni deskriptor vtičnice (fd); le s stikalom -p |
Kaj pomeni naslov pred vrati?
Local Address pokaže, od kod je storitev dosegljiva:
| Naslov | Pomen |
|---|---|
0.0.0.0:80 |
posluša na vseh naslovih IPv4, dosegljivo tudi od zunaj (če požarni zid dovoli) |
[::]:80 |
posluša na vseh naslovih IPv6 |
*:3000 |
na vseh naslovih IPv4 in IPv6, z eno vtičnico (v preizkusu se je tako prikazala aplikacija Node.js) |
127.0.0.1:6379, [::1]:6379 |
dosegljivo le znotraj strežnika (localhost) |
127.0.0.53%lo:53 |
le na vmesniku loopback; v Ubuntuju tako posluša lokalni razreševalnik DNS systemd-resolved |
10.0.2.15:68 |
le na tem enem naslovu IP |
V preizkusu je Valkey privzeto poslušal le na naslovu 127.0.0.1, zato od zunaj ni dosegljiv, tudi če je požarni zid odprt. MariaDB pa je s paketom AlmaLinux 10 privzeto poslušal na naslovu 0.0.0.0:3306: če podatkovno bazo uporablja le spletna stran na strežniku, jo lahko z vrstico bind-address=127.0.0.1 v razdelku [mysqld] datoteke /etc/my.cnf.d/mariadb-server.cnf in ponovnim zagonom storitve omejiš na lokalni dostop (v preizkusu je ss nato kazal le še naslov 127.0.0.1:3306). Namestitev MariaDB opisuje ločen članek.
Filtriranje po vratih
sudo ss -tlnp 'sport = :80'
sudo ss -tlnp | grep ':3306 '
sport (source port) pomeni lokalna vrata. Pri grep se zaradi presledka za vrati :3306 ne ujema na primer z vrati :33060.
Vzpostavljene povezave
Brez -l, s filtrom po stanju, vidiš trenutno žive povezave, na primer kdo je povezan prek SSH:
sudo ss -tnp state established
ss -s da povzetek števila vtičnic po protokolih; veliko povezav timewait ali estab je na obremenjenem spletnem strežniku normalno, na mirnem strežniku pa je lahko sumljivo.
Kateri program zaseda vrata? lsof in fuser
lsof izpiše odprte datoteke, v Linuxu pa tudi omrežna vtičnica šteje za datoteko:
sudo lsof -nP -i :80
sudo lsof -nP -i -sTCP:LISTEN
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mariadbd 839 mysql 20u IPv4 9075 0t0 TCP *:3306 (LISTEN)
mariadbd 839 mysql 21u IPv6 9076 0t0 TCP *:3306 (LISTEN)
-n pusti naslove, -P pa vrata kot številke (brez njega se prikaže *:http). Na cloud image AlmaLinux 10 lsof ni bil nameščen (sudo dnf install lsof), na Ubuntu 26.04 pa je bil.
fuser (iz paketa psmisc, nameščen je bil v obeh sistemih) da le PID-e:
sudo fuser -v 80/tcp
fuser -k 80/tcp programe, ki zasedajo vrata, tudi ubije. Pri storitvi namesto tega ustavi storitev (glej spodaj), ker lahko systemd ubito storitev glede na nastavitev znova zažene.
netstat: stari ukaz
netstat je del paketa net-tools, ki ni bil nameščen niti na cloud image AlmaLinux 10 niti na Ubuntu 26.04. Če si ga navajen, ga lahko namestiš (sudo dnf install net-tools ali sudo apt install net-tools) in uporabljaš z istimi stikali:
sudo netstat -tulpn
Izpis je podoben, naslove IPv6 piše v obliki :::80. Brez sudo je v stolpcu PID/Program name le -. V novih skriptih je priporočen ss, ker je nameščen povsod.
Ustavitev storitve, ki zaseda vrata
ss -tulpn pokaže ime in PID programa. Katera storitev systemd ga je zagnala, povesta ps ali systemctl status:
ps -p 1217 -o pid,comm,unit
systemctl status 1217
Nato jo lahko ustaviš in izklopiš njen samodejni zagon:
sudo systemctl disable --now nginx
Upravljanje storitev podrobno opisuje članek o ukazu systemctl.
V Ubuntu 26.04 se pri vratih 22 poleg sshd pojavi tudi systemd (PID 1): tam SSH zažene aktivacija prek vtičnice (ssh.socket), vrata pa drži odprta tudi systemd. O nastavitvah SSH, med njimi o premiku na druga vrata, govori članek o varni nastavitvi strežnika SSH.
Address already in use: zasedena vrata
Če program poskuša odpreti vrata, ki jih že zaseda drug, se ne zažene. V preizkusu se nginx tako ni zagnal, ker je na vratih 80 poslušal drug program:
$ sudo journalctl -u nginx | grep bind
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Drugi programi to sporočijo s svojimi besedami (v Pythonu na primer OSError: [Errno 98] Address already in use). Kaj narediti:
- Poglej, kdo zaseda vrata:
sudo ss -tlnp 'sport = :80'alisudo lsof -nP -i :80. - Če gre za staro ali nepotrebno storitev, jo ustavi (
sudo systemctl disable --now apache2). Pogost primer je, da se Apache in nginx hkrati poskušata zagnati na vratih 80 ali da vrata zaseda vsebnik Docker. - Če potrebuješ oba, enega preusmeri na druga vrata.
Posluša, a ni dosegljivo? Požarni zid
ss pokaže le, da bi program sprejel povezavo. Ali je od zunaj res dosegljiv, odloči požarni zid. V preizkusu je nginx poslušal na naslovu 0.0.0.0:80, od zunaj pa ni odgovarjal, dokler firewalld ni dovolil storitve http; nato je bil takoj dosegljiv.
Preverjanje pravil požarnega zidu:
# AlmaLinux, Rocky Linux (firewalld)
sudo firewall-cmd --list-all
# Ubuntu, Debian (ufw)
sudo ufw status verbose
Na cloud image AlmaLinux 10 firewalld ni bil nameščen, na Ubuntu 26.04 je bil ufw nameščen, a izklopljen (Status: inactive). Kakšna je osnovna nastavitev na tvojem strežniku, vedno preveri. Nastavitev požarnega zidu prikazuje članek Kako nastavim požarni zid na svojem VPS?
Docker obide požarni zid
Docker objavljena vrata vsebnikov (-p 8081:80) odpre z lastnimi pravili. V preizkusu je bil vsebnik nginx, zagnan s stikalom -p 8081:80, dosegljiv od zunaj, čeprav je cona public v firewalld dovoljevala le SSH; hkrati nginx, ki je tekel neposredno na računalniku, na vratih 80 ni bil dosegljiv. V izpisu ss taka vrata zaseda program docker-proxy.
Če želiš vsebnik doseči le lokalno (na primer za obratnim proxyjem), ga veži na lokalni naslov:
docker run -d -p 127.0.0.1:8082:80 nginx:alpine
Takrat ss pokaže naslov 127.0.0.1:8082. Namestitev in osnove Dockerja opisuje članek o namestitvi Dockerja.
Preverjanje od zunaj: nc in nmap
Ali so vrata res dosegljiva, preveri z drugega računalnika (na primer s svojega). Preizkus znotraj strežnika požarnega zidu ne preizkusi.
nc -zv 203.0.113.10 80
nc -zv -w 3 203.0.113.10 3306
Ukaz nc v Ubuntuju (netcat-openbsd) ob uspešni povezavi izpiše Connection to ... 443 port [tcp/https] succeeded!, pri zaprtih vratih Connection refused, pri paketih, ki jih zavrže požarni zid, pa po -w 3 sekundah napako timed out. V AlmaLinux je nc v paketu nmap-ncat in da sporočilo Ncat: Connected to ... ali Ncat: Connection refused..
Več vrat hkrati preveri nmap:
nmap -Pn -p 22,80,443,3306 203.0.113.10
PORT STATE SERVICE
443/tcp open https
3306/tcp filtered mysql
open: vrata so dosegljiva, program sprejme povezavo;closed: računalnik odgovori, a na vratih nič ne posluša;filtered: odgovora ni bilo, pakete verjetno zavrže požarni zid.
Tako preverjaj le svoj strežnik: skeniranje vrat tujih računalnikov brez dovoljenja lahko velja za zlorabo. Druga orodja za iskanje omrežnih napak (ping, traceroute, curl) predstavlja članek o iskanju omrežnih napak.
Povzetek
| Naloga | Ukaz |
|---|---|
| Vrata, ki poslušajo, s programi | sudo ss -tulpn |
| Vrata, ki poslušajo, brez sudo | ss -tuln |
| Preverjanje enih vrat | sudo ss -tlnp 'sport = :80' |
| Kdo zaseda vrata? | sudo lsof -nP -i :80 |
| Žive povezave | sudo ss -tnp state established |
| Stara oblika | sudo netstat -tulpn (net-tools) |
| Katera storitev? | systemctl status PID |
| Pravila požarnega zidu | sudo firewall-cmd --list-all ali sudo ufw status verbose |
| Je dosegljivo od zunaj? | nc -zv IP PORT ali nmap -Pn -p PORT IP (z drugega računalnika) |
