Come verificare se una porta è aperta su Linux
Scopri cosa è davvero in ascolto con ss e prova la porta dall'esterno con nc o nmap. Capisci perché una porta bloccata resta in attesa e una chiusa rifiuta subito.
Verificare se una porta è aperta su Linux: scegliere prima la domanda corretta
Per verificare se una porta è aperta su Linux, stabilire prima quale domanda si sta ponendo, perché il termine «aperta» ha un significato diverso a seconda del punto da cui si esegue il controllo. Sul server stesso, una porta è aperta quando un processo è associato a quella porta ed è in attesa. Da un altro computer, una porta è aperta quando un pacchetto raggiunge quel processo e riceve una risposta. Se non arriva alcuna risposta, la domanda reale è quale dispositivo abbia eliminato il pacchetto. sudo ss -ltnp risponde alla prima domanda. nc -z o nmap rispondono alla seconda. I contatori del firewall e tcpdump rispondono alla terza.
Eseguire il controllo sbagliato può far perdere un intero pomeriggio. Un test eseguito sul server non attraversa mai il firewall di rete del provider, perché quel filtro si trova all'esterno del server. Se i numeri di porta sono ancora poco familiari, come funzionano porte e socket su Linux illustra il modello presupposto dal resto di questa guida.
Che cosa è in ascolto su questo server? Leggere l'output di ss
ss è incluso in iproute2, quindi è presente in ogni distribuzione attuale. netstat proviene da net-tools, che Ubuntu non installa più per impostazione predefinita da anni; per questo netstat -tulpn spesso restituisce netstat: command not found. Impara ss ed evita questo problema.
sudo ss -ltnp-l mostra solo i socket in ascolto. -t limita l'elenco a TCP. -n visualizza i numeri invece di risolvere i nomi, quindi il comando restituisce subito il risultato. -p indica il processo proprietario e richiede root: senza sudo la colonna Process è vuota per ogni processo che non appartiene all'utente corrente. Sostituisci -t con -u per visualizzare UDP.
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=612,fd=14))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=921,fd=3))
LISTEN 0 511 127.0.0.1:8080 0.0.0.0:* users:(("node",pid=1442,fd=19))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=921,fd=4))La colonna Local Address è determinante ed è quella che spesso viene trascurata.
0.0.0.0:22indica ogni indirizzo IPv4 del computer, quindi il servizio è raggiungibile dall'esterno se il firewall lo consente.[::]:22indica la stessa cosa per IPv6.127.0.0.1:8080indica esclusivamente il loopback. Nulla al di fuori di questo computer può raggiungerlo.10.20.0.5:5432indica un solo indirizzo dell'interfaccia, senza gli altri. È comune nelle configurazioni di reti private.- Una colonna Process vuota indica di solito l'assenza di
sudo, non l'assenza del processo.
Per controllare una sola porta, applica il filtro all'interno di ss invece di usare grep sull'intero elenco:
sudo ss -ltnp 'sport = :8080'
sudo lsof -nP -iTCP:8080 -sTCP:LISTEN
sudo fuser 8080/tcpSe tutti e tre i comandi non restituiscono alcun output, nessun processo occupa quella porta. Il servizio è arrestato, non è riuscito ad avviarsi oppure è in ascolto altrove. Consulta systemctl status <unit> e journalctl -u <unit> -n 50 prima di modificare una sola regola del firewall.
Perché 127.0.0.1 in Local Address può costare un pomeriggio
Un socket associato a 127.0.0.1 non è raggiungibile da un altro host e nessuna modifica alle regole del firewall può cambiare questo comportamento. Il kernel instrada 127.0.0.0/8 soltanto sull’interfaccia di loopback e scarta come pacchetto martian un pacchetto con quell’indirizzo di destinazione che arriva da una scheda di rete reale. Di conseguenza, il processo è in esecuzione, ss mostra che è in ascolto, ufw allow 8080 segnala un esito positivo, ma la connessione dal laptop continua a non funzionare. Fallisce con un Connection refused immediato perché il pacchetto raggiunge l’indirizzo pubblico, non trova alcun socket in ascolto su quell’indirizzo e il kernel risponde con un reset TCP.
Molti programmi si associano intenzionalmente all’interfaccia di loopback. Per un database o un’interfaccia di amministrazione, questo è il valore predefinito corretto. Le opzioni corrette sono due. Modificare l’indirizzo di ascolto nella configurazione del programma (listen_addresses in postgresql.conf, bind in redis.conf oppure l’argomento host accettato dall’applicazione), quindi aprire il firewall. In alternativa, lasciare il servizio sulla loopback e raggiungerlo tramite un altro componente, ad esempio un reverse proxy nginx o un tunnel SSH dal laptop:
ssh -L 8080:127.0.0.1:8080 user@203.0.113.10Docker applica la stessa distinzione nel flag di pubblicazione. -p 8080:8080 associa 0.0.0.0 ed espone il container a Internet. -p 127.0.0.1:8080:8080 associa il servizio alla loopback e lo mantiene accessibile solo localmente.
Come verificare se una porta è aperta su Linux da un'altra macchina
Eseguire questo test da una rete diversa. Un test dal server dimostra soltanto che il percorso di loopback funziona. Anche una connessione al proprio IP pubblico dal server aggira il firewall di rete del provider, perché il filtro viene applicato all'esterno del VPS.
nc -zv -w 3 203.0.113.10 443-z si connette e chiude la connessione senza inviare dati. -w 3 interrompe il tentativo dopo tre secondi; questo flag è importante: senza un timeout, se un pacchetto viene scartato, il client continua a ritrasmettere il SYN per più di due minuti, prima che il kernel interrompa il tentativo. Un risultato positivo è simile al seguente:
Connection to 203.0.113.10 443 port [tcp/https] succeeded!Se lo strumento non è installato (nc: command not found), installare netcat-openbsd su Debian o Ubuntu oppure usare il reindirizzamento di rete integrato in bash, che non richiede alcun pacchetto:
timeout 3 bash -c '</dev/tcp/203.0.113.10/443' && echo open || echo "no answer"Questa sintassi è una funzionalità di bash, quindi eseguirla con bash. Su Debian e Ubuntu, /bin/sh è dash, che non supporta /dev/tcp e segnala che il percorso non esiste. Per un intervallo di porte, oppure quando si desidera che lo stato venga indicato esplicitamente, usare nmap sugli host di propria responsabilità:
sudo nmap -Pn -p 22,80,443 203.0.113.10
sudo nmap -Pn -p 1-1024 203.0.113.10-Pn salta il rilevamento dell'host. La maggior parte dei provider VPS scarta le richieste ICMP echo; senza -Pn, quindi, nmap considera l'host non disponibile e non esegue alcuna scansione. nmap stampa open quando qualcosa risponde e accetta la connessione, closed quando qualcosa risponde con un reset e filtered quando non arriva alcuna risposta. Per un servizio web, curl -sS -o /dev/null -w '%{http_code}\n' https://example.com distingue un problema di rete da un problema applicativo, perché un codice di stato dimostra che l'intero percorso ha funzionato.
Perché una porta bloccata resta in attesa mentre una porta chiusa rifiuta subito
Un rifiuto immediato. Il pacchetto ha raggiunto il computer e qualcosa ha risposto.
nc: connect to 203.0.113.10 port 443 (tcp) failed: Connection refusedQuella risposta precisa può avere due cause. Nessun processo è associato a quell'indirizzo e a quella porta, quindi il kernel ha risposto con un reset TCP, oppure una regola del firewall ha rifiutato il pacchetto con un reset o con un messaggio ICMP di porta irraggiungibile. Un rifiuto è una risposta definitiva e torna dopo un solo round trip.
Una pausa, poi un timeout. Qualcosa ha eliminato il pacchetto senza inviare alcuna risposta.
nc: connect to 203.0.113.10 port 443 (tcp) timed out: Operation now in progressÈ il comportamento di una regola DROP, ma anche di un firewall del provider o di un security group cloud. Il silenzio è il segnale caratteristico di un drop, perché il mittente non può distinguere un pacchetto eliminato da un host non raggiungibile.
Il sintomo indica dove cercare. Un rifiuto significa che i pacchetti attraversano correttamente la rete, quindi torna a ss -ltnp e controlla l'indirizzo di bind e il numero di porta. Un timeout significa che i pacchetti vengono eliminati, quindi esamina i firewall dall'esterno verso l'interno. rifiuto o timeout su SSH analizza la stessa distinzione per la porta 22, che è il caso in cui la maggior parte degli utenti la incontra.
ufw offre volutamente entrambi i comportamenti: ufw deny 8080 elimina i pacchetti e ufw reject 8080 invia un rifiuto. In nftables i due target sono drop e reject, mentre in iptables sono -j DROP e -j REJECT. Le policy predefinite prevedono quasi sempre un drop, perciò una regola mancante provoca un'attesa prolungata invece di un messaggio di errore.
Chi sta bloccando la porta? Procedi dall’esterno verso l’interno
sudo ufw status verbose
sudo iptables -L INPUT -n -v --line-numbers
sudo nft list rulesetI contatori -v sono la parte utile. Esegui il test nc dall’esterno, ripeti il comando iptables e cerca il contatore che è cambiato: la regola il cui conteggio dei pacchetti aumenta è quella che gestisce il tuo traffico. In questo modo sostituisci le ipotesi con dati verificabili.
Il test decisivo si esegue sul server, osservando il traffico di rete mentre ti connetti dall’esterno:
sudo tcpdump -ni any tcp port 8080Un SYN in ingresso senza il relativo SYN-ACK in uscita indica che il pacchetto ha raggiunto il tuo VPS, ma l’host lo ha bloccato. Il firewall del provider funziona, mentre le regole locali no. Nessun output indica invece che il pacchetto non è mai arrivato. In questo caso la causa è il firewall del provider, un security group oppure un indirizzo IP errato. Questa distinzione elimina gran parte delle verifiche.
Due livelli possono produrre risultati apparentemente impossibili. Il primo è IPv6: se il nome host ha un record AAAA, il client può connettersi tramite IPv6 mentre la regola copre soltanto IPv4. Prima di considerare valido uno dei due risultati, verifica ogni famiglia con nc -4 e nc -6. regole ufw e porte IPv6 su un VPS tratta questo caso. Il secondo è Docker: una porta pubblicata da un container risponde da Internet anche quando ufw status indica che la porta è negata, perché quei pacchetti vengono gestiti prima che la catena di ufw possa esaminarli. perché Docker pubblica le porte bypassando direttamente ufw descrive il meccanismo e la correzione, mentre le regole ufw da impostare su un nuovo VPS fornisce il set di base consigliato.
Perché le risposte UDP sono ambigue per progettazione
UDP non esegue un handshake, quindi una sonda non ha un’operazione il cui esito possa confermare il successo. nc -zu 203.0.113.10 53 termina con codice 0 non appena il pacchetto viene inviato, dimostrando soltanto che il computer locale lo ha trasmesso e non fornendo alcuna informazione sull’host remoto. Quando una porta UDP è chiusa, normalmente l’host risponde con un messaggio ICMP di porta irraggiungibile. Il kernel segnala questo errore a un socket connesso soltanto alla scrittura successiva, quindi una sonda costituita da un singolo pacchetto non lo rileva. I firewall eliminano spesso i pacchetti ICMP, rimuovendo anche questo indizio. Per questo nmap mostra open|filtered per la maggior parte delle porte UDP: l’assenza di risposta è esattamente ciò che producono sia un servizio attivo ma silenzioso sia una porta filtrata.
Testare UDP parlando il protocollo interessato. Un server DNS risponde a dig +short @203.0.113.10 example.com con un indirizzo oppure senza risposta. Un peer WireGuard mostra una riga latest handshake recente in sudo wg show. Quindi verificare l’arrivo dei pacchetti sul server:
sudo tcpdump -ni any udp port 51820Se i pacchetti compaiono mentre il client invia, significa che arrivano a destinazione; il problema riguarda quindi il servizio o la catena di input. Se non compare alcun pacchetto, significa che non sono mai arrivati.
Una checklist nell’ordine che consente di individuare più rapidamente il guasto
- Sul server, esegui
sudo ss -ltnp 'sport = :8080'. Se non viene restituito alcun output, nessun processo è in ascolto: correggi prima il servizio. - Se viene restituito un output, leggi la colonna Local Address.
127.0.0.1indica che l’accesso dall’esterno è impossibile finché non esegui un nuovo bind o non metti un proxy davanti al servizio. - Da un’altra rete, esegui
nc -zv -w 3 <public ip> 8080. - Un rifiuto ti riporta al passaggio 1. L’indirizzo, la porta o il computer non sono quelli previsti.
- Un timeout indica che i pacchetti vengono scartati. Avvia
sudo tcpdump -ni any tcp port 8080sul server e ripeti il test. - Se il pacchetto SYN arriva ma non torna alcuna risposta, il problema è nel firewall dell’host. In
sudo iptables -L INPUT -n -v, individua la regola il cui contatore aumenta. - Se il pacchetto SYN non arriva, il problema è nel firewall del provider, in un security group oppure nell’indirizzo IP errato.
FAQ
Come posso verificare quali porte sono aperte sul mio server Linux?
Esegui sudo ss -ltnp per TCP e sudo ss -lunp per UDP. Ogni riga corrisponde a un socket in ascolto. La colonna Local Address indica chi può raggiungerlo: 0.0.0.0 e [::] accettano connessioni da qualsiasi origine consentita dal firewall, mentre 127.0.0.1 accetta connessioni soltanto dalla macchina stessa. Per visualizzare la colonna Process servono privilegi root. Esegui quindi il comando con sudo, altrimenti la colonna resta vuota. ss fa parte di iproute2 ed è sempre installato. netstat fa parte di net-tools e in genere non è installato.
Perché ss mostra il servizio in ascolto, ma non riesco comunque a connettermi?
Le cause comuni sono due e un comando consente di distinguerle. Se Local Address è 127.0.0.1, il servizio è associato all'interfaccia loopback e non è raggiungibile da altri host, perché il kernel instrada quell'intervallo soltanto verso l'interfaccia loopback. Se invece è 0.0.0.0 e le connessioni continuano a non riuscire, esegui sudo tcpdump -ni any tcp port <port> sul server e prova a connetterti dall'esterno. Se arriva un SYN senza risposta, una regola del firewall locale lo sta scartando. Se non arriva nulla, il pacchetto viene bloccato prima di raggiungere il VPS, in genere dal firewall del provider o da un security group.
Qual è la differenza tra una connessione rifiutata e una connessione che va in timeout?
Un rifiuto è una risposta. Il pacchetto ha raggiunto l'host e ha ricevuto un TCP reset o un ICMP port unreachable. Questo significa che sull'indirizzo e sulla porta non è in ascolto alcun servizio oppure che una regola ha rifiutato la connessione. Un timeout è silenzio: una regola ha scartato il pacchetto senza inviare alcuna risposta, quindi il client ritenta fino a rinunciare. Un rifiuto indirizza il controllo verso il servizio e il relativo indirizzo di bind. Un timeout indirizza il controllo verso un firewall. Va verificato per primo il firewall più vicino alla rete esterna.
Come posso verificare se una porta UDP è aperta?
Non è possibile ottenere una risposta affidabile con un probe generico, perché UDP non esegue un handshake e un servizio silenzioso appare esattamente come un pacchetto scartato. nc -zu restituisce un esito positivo non appena invia il pacchetto e, per lo stesso motivo, nmap segnala open|filtered. Esegui invece un test usando il protocollo: dig +short @<host> example.com per DNS oppure sudo wg show per un peer WireGuard con un handshake recente. Per verificare che i pacchetti arrivino, esegui sudo tcpdump -ni any udp port <port> sul server mentre il client invia i pacchetti.
Posso ancora usare telnet host port per testare una porta?
Funziona per TCP e Escape character is '^]' indica che la connessione è stata accettata. Esci con Ctrl+] e quindi esegui quit. nc -z è uno strumento migliore per due motivi: telnet non è installato nella maggior parte delle immagini server attuali e nc consente di impostare un timeout con -w, oltre a restituire un codice di uscita verificabile in uno script. Se nessuno dei due strumenti è disponibile, timeout 3 bash -c '</dev/tcp/<host>/<port>' non richiede alcun pacchetto.