Corso Linux / Riprodurre guasti e verificare il ripristino con log e risposte HTTP
Per esercitarti nel ripristino, verifica prima un sistema funzionante in un ambiente isolato, introduci un solo guasto e ripristina la condizione modificata in base alle prove raccolte. Considera concluso il recupero solo quando tornano sia lo stato atteso del servizio sia la risposta visibile all’utente.
Prepara snapshot e console della VM di prova, nella lezione in inglese, e confronta prima e dopo ogni modifica seguendo la diagnosi basata sui log. Il riferimento è una VM ordinaria Ubuntu 26.04 LTS o Rocky Linux 9; container, WSL e altre versioni possono avere gestori dei servizi e pacchetti differenti.
Preparare il laboratorio e una condizione normale verificata
Servono il gestore utente di systemd, Python 3, curl, ss e gli strumenti di base per i file. Usa una VM di laboratorio e non cambiare Nginx, SSH, firewall o dischi di produzione. Controlla con ss -lnt che la porta loopback 18080 sia libera; se è occupata, scegli un’altra porta libera e sostituiscila in tutte le righe del laboratorio. Non fermare un servizio altrui per ottenere quella porta.
Con command -v python3 verifica il percorso effettivo: l’esempio usa /usr/bin/python3. Controlla inoltre che linux-course-recovery.service non sia già un’unità esistente, anche fra le unità utente disponibili, e che ~/linux-recovery-lab non contenga dati. Se un nome è già usato, scegli nomi nuovi e modifica tutti i riferimenti. Il server HTTP di sviluppo di Python resta vincolato a 127.0.0.1: non è destinato alla pubblicazione in produzione.
mkdir -p "$HOME/linux-recovery-lab/site" "$HOME/.config/systemd/user" &&
printf "recovery baseline\n" > "$HOME/linux-recovery-lab/site/index.html" &&
cat > "$HOME/.config/systemd/user/linux-course-recovery.service" <<'EOF' &&
[Unit]
Description=Laboratorio isolato di ripristino Linux
[Service]
Type=simple
WorkingDirectory=%h/linux-recovery-lab/site
ExecStart=/usr/bin/python3 -m http.server 18080 --bind 127.0.0.1
EOF
systemctl --user daemon-reload &&
systemctl --user start linux-course-recovery.service &&
systemctl --user is-active linux-course-recovery.service &&
curl --fail --max-time 5 http://127.0.0.1:18080/ &&
cp "$HOME/.config/systemd/user/linux-course-recovery.service" "$HOME/linux-recovery-lab/service.good"
La catena && impedisce di salvare la configurazione come buona se una fase precedente fallisce. Prima di introdurre guasti devi vedere active, la porta prevista e il corpo recovery baseline; service.good è la copia dell’unità funzionante. Il servizio non è stato abilitato per l’avvio automatico.
Type=simple non attende che Python abbia completato l’apertura della porta. Se la prima richiesta arriva troppo presto, controlla stato, journal e listener, poi ripeti la sola richiesta HTTP. Salva service.good con il comando cp mostrato solo dopo il successo di tutti i controlli; non rieseguire alla cieca il blocco di creazione sui file ormai esistenti. Se manca la condizione normale, risolvi percorso Python, sintassi dell’unità, directory di lavoro o conflitto di porta prima di proseguire.
Esperimento 1: introdurre un errore nel percorso eseguibile
Verifica prima che /nonexistent/course-python non esista davvero; se esiste, scegli un altro percorso inesistente e adegua la sostituzione. Il comando sed deve trovare esattamente la riga ExecStart prevista: se hai cambiato il percorso Python nel laboratorio, modifica anche il testo da cercare. Dopo sed controlla il contenuto del file prima di riavviare.
Esegui le righe una alla volta, osservando l’esito. Restart e status possono restituire errori attesi: prosegui con la raccolta del journal, anziché interpretare l’ultimo codice di uscita dell’intero blocco come esito di tutte le fasi.
sed -i 's@ExecStart=/usr/bin/python3 @ExecStart=/nonexistent/course-python @' "$HOME/.config/systemd/user/linux-course-recovery.service" &&
systemctl --user daemon-reload
systemctl --user restart linux-course-recovery.service
systemctl --user status linux-course-recovery.service --no-pager
journalctl --user -u linux-course-recovery.service --since "5 minutes ago" --no-pager
Ora l’unità punta a un eseguibile inesistente e non può restare attiva. Con Type=simple un comando di avvio può inizialmente risultare riuscito prima che il fallimento emerga nello stato successivo. Nel journal cerca il problema di esecuzione e lo stato 203/EXEC documentato da systemd; annota il messaggio effettivo. 203 indica un fallimento nell’esecuzione del processo, non prova da solo che il file sia inesistente: anche accesso e altri vincoli possono impedire l’esecuzione.
Registra l’orario della modifica e non attribuire al nuovo guasto tutte le righe degli ultimi cinque minuti: la finestra può includere prove precedenti. Il file dell’unità esiste, ma il suo processo non parte; questa evidenza indirizza verso la configurazione del servizio, senza richiedere modifiche alla rete.
Ripristinare l’unità e verificare nuovamente la pagina
cp "$HOME/linux-recovery-lab/service.good" "$HOME/.config/systemd/user/linux-course-recovery.service" &&
systemctl --user daemon-reload &&
systemctl --user reset-failed linux-course-recovery.service &&
systemctl --user start linux-course-recovery.service &&
systemctl --user is-active linux-course-recovery.service &&
curl --fail --max-time 5 http://127.0.0.1:18080/
Ripristini la copia buona, fai rileggere i file al gestore utente e avvii nuovamente il servizio. reset-failed può azzerare lo stato di fallimento e i contatori di limitazione degli avvii; non corregge una configurazione errata. Non usarlo per cancellare le prove prima di averle raccolte.
Conferma di nuovo stato, listener e lo stesso corpo alla stessa URL. Se curl arriva prima che il server ascolti, ispeziona lo stato e ripeti la sola richiesta dopo l’avvio; una risposta da un altro processo sulla stessa porta non è prova di recupero. Solo quando tutti i controlli concordano puoi dichiarare concluso questo esperimento.
Esperimento 2: confrontare HTTP 404 e connessione fallita
Esegui anche questo blocco una riga alla volta: alcuni errori sono il risultato atteso dell’esperimento. Prima della prova controlla che missing-resource non esista nella directory del sito e che la pagina normale funzioni. Dopo lo stop verifica che sia riuscito prima di interpretare la richiesta successiva.
curl -i --max-time 5 http://127.0.0.1:18080/missing-resource
systemctl --user stop linux-course-recovery.service
curl -i --connect-timeout 2 --max-time 5 http://127.0.0.1:18080/
ss -lnt
systemctl --user start linux-course-recovery.service
curl --fail --max-time 5 http://127.0.0.1:18080/
Il primo curl deve ricevere HTTP 404 dal server in esecuzione: il trasporto ha funzionato ma la risorsa non esiste. Senza --fail, curl può uscire con codice 0 anche in questo caso. Puoi ripetere quella richiesta aggiungendo --fail per confrontare l’esito: il codice previsto per un errore HTTP rilevato da questa opzione è 22.
Dopo lo stop non deve esserci un listener del laboratorio su 18080. La richiesta alla pagina normale fallisce allora nel trasporto, tipicamente con connessione rifiutata e codice curl 7, anziché ricevere un 404. Registra il risultato effettivo; un timeout è un altro errore di trasporto e non ha necessariamente lo stesso codice. Se compare ancora una risposta HTTP, verifica quale processo stia ascoltando, senza assumere che lo stop sia riuscito.
Riavvia solo l’unità del laboratorio e verifica il ritorno di recovery baseline. Confronti così fallimento del processo, assenza di listener e risposta HTTP d’errore senza disattivare un firewall. Un controllo da loopback resta locale: non dimostra che un client remoto raggiunga il servizio.
Registrare una sola modifica e le prove del recupero
| Voce | Prove da conservare |
|---|---|
| Condizione normale | Unità attiva, porta in ascolto, pagina prevista |
| Modifica | Solo percorso ExecStart oppure arresto del servizio |
| Evidenza | Orario, codice di uscita, journal, HTTP e socket |
| Ripristino | Copia buona dell’unità oppure avvio del servizio |
| Nuova verifica | Stessa URL, stessa porta e corpo previsto |
| Prevenzione | Controllo di sintassi e percorsi prima del deploy, più verifica funzionale |
Non riempire il disco di sistema, non bloccare SSH e non cancellare file a caso in questo esercizio. Prove più invasive richiedono una VM clonata distinta, spazio delimitato, console verificata e backup. Lo scopo è imparare a passare dalle osservazioni al ripristino con una sola modifica controllata, mantenendo una via di recupero.
Fermare il laboratorio e rimuovere solo la sua unità
Conserva prima le prove necessarie. I comandi seguenti riguardano soltanto l’unità creata per questo laboratorio; i nomi devono corrispondere a quelli scelti all’inizio.
systemctl --user stop linux-course-recovery.service &&
systemctl --user reset-failed linux-course-recovery.service &&
rm -- "$HOME/.config/systemd/user/linux-course-recovery.service" &&
systemctl --user daemon-reload &&
ss -lnt
La catena interrompe la pulizia se una fase fallisce: leggi il messaggio prima di continuare e non allargare la rimozione ad altre unità. Verifica che la porta loopback 18080 del laboratorio non sia più in ascolto. La directory di lavoro contiene ancora pagina statica e copia buona dell’unità: esaminala e rimuovi separatamente solo questi file con il gestore dei file, quando non servono più. Mantieni le registrazioni degli altri servizi utente.




