SSH: differenza tra connection refused e timeout
Capisci cosa indicano gli errori "Connection refused" e "Connection timed out", quale test eseguire e da quale rete per trovare subito il punto del problema.
Cosa significano "Connection refused" e "Connection timed out" in SSH
Un rifiuto della connessione SSH e un timeout della connessione SSH sono errori opposti, quindi la soluzione per uno non risolve mai l'altro. "Connection refused" significa che il pacchetto ha raggiunto il server e il kernel del server ha risposto che non c'è nulla in ascolto. "Connection timed out" significa che il pacchetto non ha raggiunto alcun dispositivo in grado di rispondere, quindi il client ha atteso e poi ha interrotto il tentativo. Il rifiuto indica un problema del servizio sul server. Il timeout indica un problema del percorso di rete a monte.
Leggete la riga esatta visualizzata dal client, perché la formulazione contiene già tutta la diagnosi.
ssh: connect to host 203.0.113.10 port 22: Connection refused
ssh: connect to host 203.0.113.10 port 22: Connection timed outIl tempo di risposta è il secondo indizio. Il rifiuto arriva subito, all'incirca nel tempo necessario per un'andata e ritorno. Il timeout richiede invece molti secondi prima di essere visualizzato, perché il client continua a ritrasmettere i pacchetti prima di arrendersi. macOS visualizza Operation timed out per la stessa condizione. Se il protocollo è ancora nuovo per voi, come funziona SSH e cosa fa sshd fornisce il contesto presupposto da questa guida.
Perché «Connection refused» è una buona notizia
Un rifiuto è un reset TCP (Transmission Control Protocol). Il client invia un pacchetto SYN alla porta 22. Il pacchetto attraversa Internet, arriva allo stack di rete del server e il kernel non trova alcun socket in ascolto su quella porta. Risponde quindi con un pacchetto RST (reset). Il client SSH converte questo RST nel messaggio Connection refused.
Quel pacchetto di risposta dimostra molte cose. L'indirizzo è corretto. L'host è acceso e il routing funziona. Nessun dispositivo lungo il percorso sta eliminando silenziosamente il traffico diretto a quella porta, perché dall'estremità remota è arrivata una risposta. Di conseguenza, tutte le cause rimanenti si trovano sul server.
sshdnon è in esecuzione perché non è riuscito ad avviarsi oppure non è mai stato abilitato.sshdè in ascolto su un'altra porta, in genere dopo una modifica di hardening.sshdè associato a un solo indirizzo, ad esempioListenAddress 127.0.0.1, quindi soltanto il server stesso può raggiungerlo.- Un firewall è configurato per rifiutare invece di eliminare i pacchetti, quindi invia l'RST al posto dell'host. L'azione
rejectdi ufw e una regola nftables che termina conreject with tcp resetproducono entrambe questo comportamento.
Esiste un altro caso che appare simile, ma non lo è: è stato inserito un indirizzo appartenente a un altro host attivo. Quell'host risponde al SYN, non ha SSH sulla porta 22 e rifiuta educatamente la connessione. Verificare l'indirizzo prima di trascorrere un'ora sul server sbagliato. Sapere che cosa sia realmente una porta in ascolto su Linux rende più rapida la lettura del resto di questa sezione.
Come risolvere l’errore Connection refused
Non puoi risolvere il problema tramite SSH, perché è proprio SSH a non funzionare. Apri la console Web o la console seriale del provider, accedi da lì, quindi esegui questi comandi nell’ordine indicato.
systemctl status ssh
sudo ss -tlnp
sudo sshd -T | grep -Ei '^(port|listenaddress|addressfamily)'systemctl status ssh usa il nome dell’unità in Ubuntu e Debian. In RHEL e nelle relative distribuzioni ricostruite, come AlmaLinux, l’unità è sshd. ss -tlnp elenca tutti i socket TCP in stato di ascolto insieme al processo che li possiede. È la fonte di verità: se nessuna riga menziona sshd, non c’è alcun processo in ascolto, indipendentemente da quanto indicato dal file di configurazione. sshd -T stampa la configurazione effettiva dopo l’unione di tutti i file Include. È qui che diventa visibile una porta dimenticata in /etc/ssh/sshd_config.d/.
Leggi con attenzione la colonna degli indirizzi. 0.0.0.0:22 indica tutti gli indirizzi IPv4 del server. [::]:22 indica tutti gli indirizzi IPv6. 127.0.0.1:22 indica solo l’interfaccia di loopback. Di conseguenza, ogni connessione remota viene rifiutata, mentre una connessione locale a ssh localhost funziona correttamente.
Se non c’è alcun processo in ascolto, avvia il servizio e leggi l’errore se l’avvio non riesce.
sudo sshd -t
sudo systemctl enable --now ssh
sudo journalctl -u ssh -n 50 --no-pagersshd -t analizza la configurazione e stampa il file e il numero di riga della direttiva errata senza modificare il servizio in esecuzione. Eseguilo prima di ogni riavvio, perché una configurazione rifiutata fa terminare sshd all’avvio e la connessione successiva viene rifiutata.
La trappola dell'attivazione tramite socket su Ubuntu
Ubuntu 24.04 include un'unità socket di systemd per OpenSSH. Quando l'unità è abilitata, systemd mantiene la porta in ascolto e avvia sshd per ogni connessione. In questo caso, Port 2222 in sshd_config non modifica nulla e il server continua a rispondere sulla porta precedente. Prima di modificare la configurazione, verificare quale modalità è attiva.
systemctl is-enabled ssh.socket
systemctl status ssh.socketSe il socket è abilitato, impostare la porta nell'unità socket anziché in sshd_config.
sudo systemctl edit ssh.socket[Socket]
ListenStream=
ListenStream=2222La riga ListenStream= vuota è necessaria perché le impostazioni delle liste di systemd vengono aggiunte a quelle già configurate. Se la si omette, il server resta in ascolto su entrambe le porte. Applicare la modifica con sudo systemctl daemon-reload e sudo systemctl restart ssh.socket, quindi verificare con sudo ss -tlnp che la nuova porta sia quella mantenuta in ascolto. Modificare la porta è un normale intervento di messa in sicurezza di SSH su un VPS ed è l'operazione che causa più spesso la perdita dell'accesso al server.
Perché «Connection timed out» significa che non ha risposto nulla
Un timeout significa assenza di risposta. Il client ha inviato un SYN e lo ha ritrasmesso più volte nell'arco di uno o due minuti, senza ricevere mai un pacchetto in risposta. Questo non dimostra nulla sul server, perché dal server non è arrivata alcuna risposta.
Il silenzio è esattamente ciò che produce una regola DROP, e lo scarto dei pacchetti è intenzionale. Un rifiuto segnala a chi esegue la scansione che l'host esiste. Per questo ufw e il firewall di rete di ogni provider cloud eliminano i pacchetti indesiderati senza inviare nulla in risposta. Il timeout è quasi sempre causato da un firewall che svolge il proprio compito su una porta che si voleva lasciare aperta.
- L'indirizzo è errato: un record DNS punta ancora a un server che è stato ricreato, oppure contiene un errore di battitura e risolve verso un indirizzo non utilizzato.
- L'host non è attivo: è spento oppure si trova nel corso di un riavvio. Anche una sospensione del provider per mancato pagamento appare identica dall'esterno.
- Il firewall dell'host scarta i pacchetti destinati alla porta 22, nella maggior parte dei casi perché
ufw enableè stato eseguito prima di definire qualsiasi regola di autorizzazione. - Un firewall del provider, posto davanti all'istanza, scarta il pacchetto e il sistema operativo non lo riceve.
- La rete locale blocca il traffico in uscita sulla porta 22, una situazione comune nelle reti aziendali e degli hotel.
Eseguire il test dal lato corretto della connessione
Questo è l'errore che fa perdere più tempo. Non è possibile diagnosticare la perdita di un pacchetto dall'interno del sistema a cui i pacchetti non arrivano. Se fosse possibile accedere per eseguire il comando, il problema non si presenterebbe. Tutti i comandi di questa sezione vengono eseguiti sul proprio computer.
getent hosts vps.example.com
ssh -G vps.example.com | grep -Ei '^(hostname|port|user)'
ssh -vvv -o ConnectTimeout=10 user@vps.example.com
nc -vz -w 5 203.0.113.10 22getent hosts mostra l'indirizzo che il computer utilizzerà effettivamente e consente di individuare in pochi secondi un record DNS obsoleto. ssh -G stampa le impostazioni applicate dal client dopo la lettura di ~/.ssh/config, quindi consente di rilevare un vecchio blocco Host che modifica senza evidenza l'hostname, la porta o l'utente. ssh -vvv mostra fino a che punto è arrivato il tentativo: l'ultima riga indica la connessione all'indirizzo, seguita da una lunga pausa, significa che si è verificato un timeout; una riga che riporta la versione remota di OpenSSH significa invece che TCP ha già avuto successo e che il problema effettivo riguarda l'autenticazione. In Windows, Test-NetConnection 203.0.113.10 -Port 22 in PowerShell sostituisce nc.
Testare la porta, non l'host. Un ping non riuscito non dimostra nulla, perché molti provider filtrano ICMP (internet control message protocol) sul perimetro della rete. Anche un ping riuscito non dimostra nulla, perché non fornisce informazioni sulla porta 22.
Cambiare quindi l'unica variabile che nessun comando può modificare al posto dell'utente: la rete. Ripetere il test utilizzando l'hotspot del telefono. Se la connessione riesce tramite hotspot ma non dalla postazione abituale, il blocco si trova sul proprio lato di Internet oppure l'indirizzo dell'ufficio è stato bloccato dal server.
Il firewall del provider, che non è visibile dal server
La maggior parte dei pannelli VPS offre un firewall di rete, talvolta chiamato security group o cloud firewall, che opera a monte dell'istanza e mantiene un proprio elenco di regole. ufw status sul server non può visualizzarlo. Per questo la frase «ma ho già consentito la porta 22» è così comune. Apri il pannello e controlla quell'elenco prima di modificare anche una sola regola sul server.
Un comando chiarisce la situazione e richiede l'accesso alla console. Avvialo sul server, quindi prova a connetterti dal laptop mentre è in esecuzione.
sudo tcpdump -ni any tcp port 22Se non compare nulla mentre il client tenta la connessione, i pacchetti vengono scartati prima di raggiungere il sistema operativo. Il problema è quindi nel firewall del provider o nel percorso verso l'host. Se arrivano pacchetti SYN e non parte alcuna risposta, il filtro è locale e dipende da ufw o nftables. Questo singolo test dimezza le possibili cause del timeout. Per questo vale la pena accedere alla console.
ordinamento di ufw, IPv6 e un ban applicato al proprio indirizzo
L'errore nell'ordinamento di ufw causa più esclusioni di qualsiasi altro problema descritto qui. sudo ufw enable applica immediatamente una policy predefinita che nega le connessioni in ingresso. Senza una regola SSH, la sessione corrente continua a funzionare grazie allo stato delle connessioni già stabilite, mentre ogni nuova connessione va in timeout. Prima consentire la connessione, poi abilitare ufw.
sudo ufw allow OpenSSH
sudo ufw status verboseIl profilo applicativo OpenSSH copre soltanto la porta 22. Se prevedi di spostare SSH sulla porta 2222, la regola necessaria è sudo ufw allow 2222/tcp. Aggiungila prima di modificare la porta, non dopo. L'insieme più ampio di regole è illustrato in nozioni di base sul firewall ufw per un VPS, mentre l'ordinamento corretto fa parte di cosa fare nei primi dieci minuti su un nuovo VPS.
IPv6 può causare un timeout difficile da diagnosticare. Se il nome host ha un record AAAA, il client prova prima IPv6. Di conseguenza, un server con regole IPv6 mancanti resta in attesa, mentre un tentativo diretto su IPv4 funziona. Verifica separatamente i due protocolli.
ssh -4 user@vps.example.com
ssh -6 user@vps.example.comSe -4 si connette e -6 no, il problema riguarda le regole IPv6 del server. aprire la stessa porta per IPv6 in ufw descrive la procedura.
Potresti anche aver bloccato il tuo stesso indirizzo. fail2ban monitora il log di autenticazione e inserisce una regola firewall per gli indirizzi che falliscono ripetutamente. Una chiave errata o uno script che ritenta in background può quindi bloccare l'intero indirizzo di un ufficio. Un ban che elimina i pacchetti appare come un timeout. Un ban che rifiuta la connessione restituisce invece No route to host. Dalla console:
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 198.51.100.24Aggiungere il proprio indirizzo a ignoreip fa parte di una configurazione funzionante di fail2ban su Ubuntu 24.04.
Errori che non corrispondono né a un rifiuto né a un timeout
No route to host indica che è tornato un messaggio ICMP di rete non raggiungibile. Il computer locale non ha una route verso quella rete oppure un dispositivo intermedio ha risposto con un rifiuto amministrativo, come quello inviato da una regola iptables REJECT.
Network is unreachable proviene dal computer locale. Non esiste alcuna route per quella famiglia di indirizzi. È la risposta usuale quando un hostname si risolve soltanto in un indirizzo IPv6 su una connessione disponibile solo tramite IPv4.
kex_exchange_identification: Connection closed by remote host indica che la connessione TCP è stata stabilita, ma il server l'ha chiusa prima del completamento dello scambio delle chiavi. La porta è aperta e sshd è in esecuzione. Controllate il carico del server, MaxStartups oppure un ban applicato mentre vi stavate connettendo.
Permission denied (publickey) indica che avete raggiunto la fase di autenticazione, ma che l'autenticazione non è riuscita. La rete e il firewall funzionano correttamente, quindi nulla di quanto descritto in questa guida è pertinente. Consultate invece risolvere l'errore Permission denied (publickey) in SSH.
Come rientrare nel server ed evitare un secondo blocco
Ogni provider VPS affidabile mette a disposizione una console che non dipende dalla rete del sistema guest: una console seriale oppure una schermata VNC basata su browser. Questa console è il percorso di ripristino per entrambi i rami di questa guida, perché continua a funzionare quando sshd è arrestato e quando una regola del firewall scarta tutto il traffico. Cercala nel pannello, accedi come root o come utente normale, quindi esegui i controlli indicati sopra. Se non hai mai impostato una password per root, la maggior parte dei pannelli consente di reimpostarla.
Se non è disponibile alcuna console, usa la modalità di ripristino del provider. Questa avvia un sistema di recupero minimale e monta il disco, consentendoti di modificare /etc/ssh/sshd_config o eliminare una regola del firewall offline, quindi riavviare il server.
Due accorgimenti evitano il blocco successivo. Mantieni aperta una seconda sessione SSH ogni volta che modifichi sshd o il firewall, perché questa sessione resta attiva grazie allo stato già stabilito mentre verifichi una nuova connessione. Inoltre, configura un annullamento automatico prima di applicare una modifica rischiosa al firewall.
sudo systemd-run --unit=ufw-rollback --on-active=10min /usr/sbin/ufw disable
sudo systemctl stop ufw-rollback.timerLa prima riga pianifica la disattivazione automatica di ufw dopo dieci minuti. Applica le nuove regole, apri una nuova sessione SSH per verificare che funzionino, quindi esegui la seconda riga per annullare il ripristino. Se invece perdi l'accesso, attendi dieci minuti: il firewall verrà disattivato automaticamente. Il server resterà senza filtraggio finché non riattiverai ufw, quindi usa questa procedura mentre sei davanti alla tastiera e non come configurazione permanente.
Ordine delle verifiche
- Leggi il testo dell’errore e osserva dopo quanto tempo compare.
Refused: accedi alla console e controllasudo ss -tlnpper verificare la presenza di un socket in ascolto, la relativa porta e l’indirizzo a cui è associato.Timed out: dal tuo computer verifica l’indirizzo, quindi controlla il firewall del provider nel pannello e infine il firewall dell’host sul server.- Se non compare nessuna delle due stringhe, esiste già una connessione TCP. Considera quindi il problema come una questione di autenticazione o di carico del server, non di rete.
FAQ
Perché SSH restituisce "Connection refused" quando sshd è in esecuzione?
Perché il rifiuto proviene dal socket, non dal servizio, e un sshd in esecuzione può comunque rifiutare la connessione. Apri la console del provider ed esegui sudo ss -tlnp. Un socket su 127.0.0.1:22 rifiuta ogni client remoto perché è associato soltanto al loopback. Un socket su un'altra porta rifiuta tutti i client che continuano a usare la porta 22. Se è attivato tramite socket systemd, la porta viene definita da ssh.socket e non da sshd_config; controlla quindi anche systemctl is-enabled ssh.socket. Anche una regola reject di ufw restituisce un rifiuto per conto dell'host, quindi consulta sudo ufw status verbose prima di trarre conclusioni.
Perché SSH va in timeout se ufw consente già la porta 22?
Perché un timeout indica che non è arrivata alcuna risposta e ufw non è l'unico firewall nel percorso. La maggior parte dei pannelli VPS esegue un firewall di rete davanti all'istanza, e il sistema operativo non vede i pacchetti scartati da quel firewall. Dalla console, esegui sudo tcpdump -ni any tcp port 22 e prova a connetterti dal laptop mentre il comando è in esecuzione. Se non arrivano pacchetti, il blocco è a monte, nel pannello. Se i pacchetti arrivano ma non parte alcuna risposta, il blocco è locale, in ufw o nftables.
Un ping non riuscito significa che il mio VPS è inattivo?
No. Molti provider filtrano ICMP al perimetro della rete, quindi un server che gestisce normalmente il traffico può ignorare ogni ping inviato. Anche un ping riuscito fornisce un'indicazione limitata, perché non dice nulla sull'apertura della porta 22. Verifica direttamente la porta con nc -vz -w 5 203.0.113.10 22 dal tuo computer oppure con Test-NetConnection 203.0.113.10 -Port 22 in PowerShell su Windows.
Ho cambiato la porta SSH e ora non si connette più nulla. Che cosa è successo?
Sono possibili due sequenze errate. Se il firewall non ha mai ricevuto una regola per la nuova porta, i tentativi sulla nuova porta vanno in timeout mentre la porta 22 restituisce un rifiuto. Per questo sudo ufw allow 2222/tcp deve essere eseguito prima di cambiare la porta, non dopo. Se il sistema usa l'attivazione tramite socket systemd per SSH, Port 2222 in sshd_config viene ignorato e systemd continua a mantenere la vecchia porta. Puoi verificarlo con systemctl is-enabled ssh.socket. Accedi tramite la console del provider, correggi il problema applicabile, quindi connettiti con ssh -p 2222 user@203.0.113.10 quando sudo ss -tlnp mostra il nuovo socket.