Corso Linux / Diagnosticare i problemi di connessione di rete passo per passo

Per diagnosticare una connessione Linux, controlla nell’ordine interfacce e indirizzi, instradamento, risoluzione dei nomi, connessione di trasporto e risposta dell’applicazione. Il solo successo o fallimento di ping non dimostra che Internet o un servizio web funzionino nel loro insieme.

Per interpretare indirizzi e route predefinite, consulta la lezione su indirizzi IP, DNS e porte. Se fallisce soltanto SSH (Secure Shell), verifica anche host, porta e chiavi nella lezione su SSH e trasferimento di file (in inglese).

L’ambiente di riferimento è una macchina virtuale con un’installazione ordinaria di Ubuntu 26.04 LTS o Rocky Linux 9. Container, Windows Subsystem for Linux (WSL) e altri rilasci possono differire per servizi e pacchetti. Prima di intervenire, prepara l’accesso alla console di recupero e annota le versioni seguendo la lezione sull’ambiente di prova in macchina virtuale (in inglese).

Registrare l’estensione del problema prima di modificare qualcosa

Annota computer di origine, nome di destinazione, porta, momento di inizio e messaggio d’errore esatto. Confronta un sito con altri siti, un client con un altro e, quando pertinente, IPv4 con IPv6, le due versioni di Internet Protocol. Registra eventuali differenze di VPN (rete privata virtuale), proxy e modifiche recenti. Prima di riavviare la rete di un server remoto, assicurati di avere una console o un altro percorso di gestione.

Controllare interfacce, indirizzi e route

ip -brief link
ip -brief address
ip route
ip -6 route

UP indica che l’interfaccia è abilitata dal punto di vista amministrativo; non prova che la destinazione sia raggiungibile. Esamina anche lo stato del collegamento, per esempio LOWER_UP, gli indirizzi previsti e la route applicabile. In una macchina virtuale controlla che la scheda di rete virtuale sia collegata e che la modalità NAT (traduzione degli indirizzi di rete) o bridge corrisponda al progetto. Non presumere che l’interfaccia si chiami eth0.

Dopo aver ottenuto l’indirizzo reale della destinazione, ip route get INDIRIZZO_IPV4_REALE mostra la route scelta, con interfaccia e indirizzo di origine e, se previsto, il prossimo nodo o next hop. Sostituisci il segnaposto con l’indirizzo numerico effettivo; per IPv6 usa ip -6 route get INDIRIZZO_IPV6_REALE. “Network is unreachable” suggerisce di esaminare l’instradamento, distinto dalla risoluzione dei nomi. La presenza di una route non prova che il prossimo nodo o la destinazione rispondano.

Questi comandi di interrogazione non cambiano indirizzi o route. ip e ss appartengono a iproute2; su immagini minime alcuni strumenti possono mancare. Verifica la disponibilità e le versioni nella VM: Git Bash su Windows non sostituisce questo ambiente Linux.

Usare ping come indizio di raggiungibilità

ping -c 3 127.0.0.1
ping -c 3 example.com

Il primo comando invia richieste Echo ICMP (Internet Control Message Protocol) al loopback, cioè alla macchina stessa; il secondo risolve il nome e invia richieste alla destinazione ottenuta. La prima prova non verifica il collegamento esterno. Se un dispositivo filtra ICMP, ping può fallire mentre il sito web rimane accessibile. Una risposta, a sua volta, non convalida la porta web, il certificato o la risposta HTTP (Hypertext Transfer Protocol). Limita le richieste a un numero ridotto e a una destinazione di prova autorizzata.

Separare gli errori di risoluzione dai problemi di connessione

getent ahosts example.com
curl -I -v --connect-timeout 5 --max-time 15 https://example.com/
printf "exit=%s\n" "$?"

Se getent non restituisce indirizzi, controlla la configurazione del servizio dei nomi. Non è una richiesta diretta soltanto al DNS (Domain Name System): può consultare /etc/hosts e altre fonti configurate. L’output dettagliato di curl aiuta a distinguere scelta dell’indirizzo, connessione, scambio TLS (Transport Layer Security) e gestione della risposta. Il comando usa HTTPS e -I invia una richiesta HEAD per ottenere le intestazioni; alcuni server rifiutano HEAD pur accettando GET. --connect-timeout 5 limita la fase di connessione, mentre --max-time 15 limita l’intera operazione.

Nel manuale ufficiale di curl, lo stato 6 indica l’impossibilità di risolvere l’host, 7 un errore di connessione, 28 un timeout e 60 un problema di verifica del certificato. Leggi anche il messaggio preciso: un timeout, per esempio, non identifica da solo il componente responsabile. Disabilitare la verifica con -k non corregge il certificato, il nome del server o l’orologio.

Per impostazione predefinita curl può terminare con stato zero anche dopo una risposta HTTP 404 o 500. Se gli errori HTTP devono produrre uno stato di fallimento, valuta --fail-with-body nelle versioni che lo supportano, oppure --fail. Quest’ultimo normalmente restituisce 22 per risposte HTTP da 400 in su e non mostra il corpo della risposta. Leggi separatamente codice HTTP e stato d’uscita. Il printf deve seguire subito curl: $? riguarda il comando appena terminato. Prima di condividere l’output dettagliato, oscura cookie, intestazioni sensibili e indirizzi privati.

Controllare sul server indirizzi e porte in ascolto

ss -lnt
ss -lnu
sudo ss -lntp

Esegui questi controlli sul server che offre il servizio. -n mantiene numerici indirizzi e porte, -t seleziona TCP (Transmission Control Protocol), -u UDP (User Datagram Protocol) e -p richiede i processi associati. Le informazioni sui processi possono dipendere dai privilegi; usa sudo soltanto se sei autorizzato. La lista dei socket del client non descrive quelli del server remoto.

Un servizio in ascolto soltanto su 127.0.0.1:8080 è accessibile direttamente dalla stessa macchina. 0.0.0.0:8080 indica tutte le interfacce IPv4; non garantisce che firewall e percorso consentano l’accesso. Il fatto che [::]:8080 accetti anche IPv4 dipende dalle opzioni del socket e dalle impostazioni di sistema, come descritto nel riferimento del kernel per bindv6only. Un socket UDP associato a una porta non equivale a una connessione TCP in stato LISTEN e non prova che le richieste ricevano risposta.

Applicare una sola modifica sostenuta dalle osservazioni

Osservazione Controllare prima
Falliscono anche le richieste locali Stato del servizio, configurazione e socket in ascolto
Accesso locale riuscito, remoto fallito Indirizzo di bind, firewall dell’host e regole di sicurezza cloud
Connessione riuscita, errore di certificato Nome del server, catena dei certificati e orologio
Risposta HTTP di errore Log del server web o dell’applicazione e percorso richiesto

Registra il valore originale, modifica un solo elemento e ripeti la stessa prova dallo stesso client verso indirizzo e porta identici. Se non funziona, ripristina il valore prima di provare un’altra ipotesi. In questo modo conservi confronti utili e riduci la possibilità di introdurre un secondo guasto. Le voci della tabella indicano dove indagare, non una diagnosi già dimostrata.

Per distinguere un errore HTTP senza dipendere da un sito esterno, verifica che nella VM siano presenti python3 e curl, installandoli tramite il gestore dei pacchetti se necessario. L’installazione modifica il sistema; le interrogazioni precedenti no. Apri un terminale dedicato ed esegui il server seguente, lasciandolo attivo. Crea una cartella temporanea vuota e pubblicala soltanto sul loopback. Se la porta 18080 è occupata, scegli una porta libera e modifica entrambi i comandi.

lab=$(mktemp -d "$HOME/linux-http-check.XXXXXX") &&
python3 -m http.server 18080 --bind 127.0.0.1 --directory "$lab"

Dopo l’avvio del server, apri un altro terminale nella stessa VM ed esegui:

curl --fail --show-error --connect-timeout 2 --max-time 5 http://127.0.0.1:18080/missing-file
printf "exit=%s\n" "$?"

Con la cartella vuota, curl segnala HTTP 404 e stampa exit=22: la connessione TCP e la risposta HTTP sono arrivate, ma manca il file richiesto. Con --fail il corpo della pagina d’errore viene soppresso. Se un proxy intercetta anche il loopback, controlla la sua configurazione: per questa prova locale puoi aggiungere --noproxy 127.0.0.1 a curl, senza modificare le impostazioni globali.

Ferma il server con Ctrl+C nel suo terminale, quindi ripeti la richiesta dall’altro terminale. Se non esiste più un processo in ascolto, normalmente curl restituisce exit=7; se l’ambiente lascia scadere il tentativo, può comparire 28. Controlla subito lo stato e verifica che un altro server non abbia occupato la stessa porta. Nel terminale originale, dopo l’arresto, puoi rimuovere soltanto la cartella di prova ancora vuota con rmdir -- "$lab". Il server HTTP incluso in Python serve per questa prova locale, non come server di produzione.

Documentazione ufficiale