Server Debian e Ubuntu in emergenza: checklist operativa rapida per VPS

Server Debian e Ubuntu in emergenza: checklist operativa rapida per VPS

Il 3 luglio 2025, alle 14:20 di un giovedì pomeriggio, mi è arrivata una chiamata dal titolare di una PMI marchigiana che gestisce un gestionale web custom in PHP 8.2 per coordinare la logistica di quattro magazzini. Il VPS era un Hetzner CX31 - 4 vCPU, 8 GB di RAM, 80 GB NVMe - con Debian 12 Bookworm, Nginx, PHP-FPM e MySQL 8.0. Il sito era irraggiungibile da circa venti minuti, gli operatori di magazzino non potevano processare le spedizioni, e l'unica informazione che il titolare aveva era "non va più niente". Nessun messaggio di errore, nessun monitoring attivo, nessun tecnico interno. Solo un VPS che aveva smesso di rispondere.

In trentasei minuti ho identificato il problema (disco pieno al 100% per un log MySQL non ruotato da otto mesi che aveva raggiunto i 71 GB), liberato spazio, riavviato i servizi e ripristinato l'operatività. Ho potuto farlo così rapidamente perché uso sempre la stessa checklist - sette fasi, stesso ordine, stessi comandi - che ho costruito e affinato su una quindicina di emergenze reali negli ultimi tre anni. In questo articolo ti consegno quella checklist nella sua forma operativa, con i comandi esatti, le spiegazioni del perché ogni passaggio è in quell'ordine e non in un altro, e i casi reali in cui ciascuna fase mi ha salvato ore di debug.

Stai cercando un Consulente Informatico esperto per gestire emergenze sulla tua infrastruttura VPS? Nel mio profilo professionale trovi l'esperienza concreta su Hetzner, OVH, Contabo, Digital Ocean e Aruba. Contattami per una consulenza diretta.

Perché serve una checklist strutturata e non "andare a intuito"?

Quando un server è giù e il business è fermo, la pressione spinge a reagire istintivamente: riavviare tutto, cancellare file a caso, disinstallare pacchetti. Sono tutte azioni che ho visto fare - e tutte hanno peggiorato la situazione. Un riavvio cieco su un server con disco pieno non risolve nulla e può corrompere il database. Cancellare file senza sapere cosa sono può rimuovere dati di produzione. Disinstallare pacchetti a caldo può rompere dipendenze.

La checklist che uso è basata sul USE method (Utilization, Saturation, Errors) di Brendan Gregg - un framework sistematico per la diagnosi delle performance su sistemi Linux che analizza ogni risorsa (CPU, memoria, disco, rete) lungo tre dimensioni: quanto è utilizzata, quanto è satura, e se ci sono errori. L'ho adattato al contesto specifico delle emergenze VPS su Debian e Ubuntu, dove il 90% dei problemi ricade in quattro categorie: disco pieno, servizio crashato, load anomalo e compromissione di sicurezza.

Fase 1: il triage in 60 secondi - capire cosa sta succedendo

Il primo minuto serve a ottenere un quadro generale senza toccare nulla. Se riesci a connetterti via SSH, esegui questi cinque comandi in sequenza. Se SSH non risponde, usa la console VNC del pannello del provider (Hetzner Cloud Console, OVH KVM, Digital Ocean Recovery Console).

# 1. Da quanto è su la macchina e qual è il carico
uptime

# 2. Errori kernel recenti (OOM killer, disk errors, segfault)
dmesg -T | tail -30

# 3. Uso disco per filesystem
df -hT

# 4. Uso memoria reale (non contare il buffer/cache)
free -h

# 5. Servizi in errore
systemctl --failed

Questi cinque comandi ti danno, in meno di dieci secondi, le informazioni per decidere quale delle fasi successive affrontare per prima. L'output di uptime ti dice da quanto il server è acceso e se il load average è anomalo (su un VPS 4 vCPU, un load average sopra 8 è preoccupante). Il dmesg ti rivela se il kernel ha dovuto killare processi per mancanza di memoria (OOM killer) o se ci sono errori hardware. Il df -hT ti mostra immediatamente se un filesystem è al 100%. Il free -h ti dice se la RAM è esaurita. I servizi in stato failed da systemctl ti indicano cosa è crashato.

Nel caso della PMI marchigiana, df -hT ha mostrato immediatamente il problema: /dev/sda1 al 100%, 0 byte disponibili. Da quel momento sapevo esattamente dove guardare.

Fase 2: disco pieno - il problema più frequente e più sottovalutato

Il disco pieno è responsabile di almeno il 40% delle emergenze VPS che ho gestito. Quando il filesystem raggiunge il 100%, tutto si rompe a cascata: MySQL non può scrivere nel binlog e si ferma, PHP-FPM non può scrivere i file di sessione e restituisce 500, Nginx non può scrivere i log e rifiuta le connessioni. La diagnosi è rapida, la risoluzione richiede precisione.

# Trovare le directory più grandi (partendo dalla root)
du -xsh /* 2>/dev/null | sort -rh | head -10

# Tipicamente il colpevole è /var - scendere nel dettaglio
du -xsh /var/* 2>/dev/null | sort -rh | head -10

# Se è /var/log, trovare il file specifico
du -sh /var/log/* 2>/dev/null | sort -rh | head -5

# Controllare i file aperti ma cancellati (occupano spazio ma non visibili con du)
lsof +L1 2>/dev/null | awk '{print $7, $9}' | sort -rn | head -10

L'ultimo comando è fondamentale e spesso sconosciuto: se cancelli un file di log mentre il processo che lo scrive è ancora attivo, il file scompare dal filesystem ma lo spazio non viene liberato finché il processo non chiude il file descriptor. Questo è il motivo per cui rm da solo non basta - devi anche riavviare il servizio che scriveva quel file, oppure troncare il file senza cancellarlo con truncate -s 0 /path/to/file.

Nel caso marchigiano, il colpevole era /var/lib/mysql/mysql-bin.* - i binary log di MySQL che nessuno aveva configurato per la rotazione automatica. La soluzione immediata:

# Verificare quali binlog esistono
ls -lh /var/lib/mysql/mysql-bin.*

# In MySQL: rimuovere i binlog vecchi
mysql -u root -p -e "PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 3 DAY);"

# Impostare la retention automatica per il futuro
mysql -u root -p -e "SET GLOBAL binlog_expire_logs_seconds = 259200;"
# (3 giorni = 259200 secondi)

Ho documentato un caso simile ma con un file laravel.log da 87 GB nell'articolo sulla gestione strategica dei log - i log non ruotati sono il killer silenzioso dei VPS unmanaged.

Fase 3: servizi che non ripartono - diagnosi sistematica

Quando un servizio è down, il riflesso istintivo è systemctl restart. È sbagliato come prima azione: prima devi capire perché si è fermato, altrimenti il restart fallirà o il servizio crasherà di nuovo dopo pochi minuti.

# Stato dettagliato del servizio (include le ultime righe di log)
systemctl status nginx --no-pager -l
systemctl status php8.2-fpm --no-pager -l
systemctl status mysql --no-pager -l

# Log recenti del servizio specifico
journalctl -u nginx --since "1 hour ago" --no-pager | tail -50
journalctl -u mysql --since "1 hour ago" --no-pager | tail -50

# Verifica della configurazione PRIMA di riavviare
nginx -t                    # Nginx
php-fpm8.2 -t              # PHP-FPM
mysqld --validate-config    # MySQL 8.0+

Il nginx -t e il php-fpm8.2 -t sono passaggi critici: se la configurazione è rotta (un typo nel virtualhost, un pool FPM con path errato), il restart fallirà e ti troverai con un servizio né acceso né spento. Verificare la configurazione prima del restart è una regola che non violo mai.

Un pattern che vedo spesso su VPS con poca RAM (2-4 GB): MySQL va in OOM kill perché il buffer pool InnoDB è dimensionato per più memoria di quanta ne abbia la macchina. Il kernel uccide mysqld, PHP non riesce a connettersi al database e restituisce errori 500, Nginx è perfettamente funzionante ma serve pagine di errore. Il titolare vede "il sito non va" e pensa sia un problema di Nginx. La diagnosi reale è in dmesg:

# Cercare OOM killer nel kernel log
dmesg -T | grep -i "out of memory\|oom\|killed process"

# Se MySQL è stato killato per OOM, ridurre il buffer pool
# In /etc/mysql/mysql.conf.d/mysqld.cnf:
# innodb_buffer_pool_size = 256M  (su VPS con 4GB di RAM)
# poi: systemctl restart mysql

Se il tuo VPS ha 4 GB di RAM o meno e non hai uno swap file configurato, leggi l'articolo sulla configurazione dello swap su VPS Debian e Ubuntu - uno swap da 2-4 GB può fare la differenza tra un server che resta in piedi durante un picco di traffico e uno che crolla.

Fase 4: load anomalo - CPU, I/O o memoria?

Un load average alto non significa necessariamente che la CPU sia satura. Su Linux, il load average include anche i processi in attesa di I/O disco, quindi un VPS con disco lento può mostrare load 20 anche con CPU quasi scarica. Distinguere il tipo di carico è fondamentale per la diagnosi corretta.

# Vista d'insieme: CPU, I/O wait, swap, context switch
vmstat 1 5

# I/O disco per device (la colonna %util è la chiave)
iostat -xz 1 3

# Se non hai iostat installato:
apt install -y sysstat && iostat -xz 1 3

# Processi ordinati per I/O (richiede iotop)
apt install -y iotop && iotop -oP -d 2

L'output di vmstat ha due colonne decisive: wa (I/O wait) e si/so (swap in/swap out). Se wa è sopra il 20%, il collo di bottiglia è il disco. Se si e so sono entrambi sopra zero, il server sta facendo swap thrashing - la RAM è esaurita e il sistema sta spostando continuamente pagine tra RAM e disco, il che è catastroficamente lento. Se invece la colonna us (user CPU) è al 90%+ e wa è a zero, hai un processo che consuma tutta la CPU - tipicamente un loop infinito, un cryptominer o un import batch fuori controllo.

# Top 10 processi per CPU
ps aux --sort=-%cpu | head -11

# Top 10 processi per memoria
ps aux --sort=-%mem | head -11

# Se c'è un processo sospetto, ispezionarlo
ls -la /proc/PID/exe    # path del binario
cat /proc/PID/cmdline   # command line completa
ls -la /proc/PID/cwd    # directory di lavoro

Per una diagnosi più strutturata delle performance, nell'articolo sul monitoraggio IT proattivo ho descritto come implementare Prometheus e Grafana con il metodo RED per i servizi e USE per l'infrastruttura - il tipo di monitoring che trasforma le emergenze reattive in alert preventivi.

Fase 5: sospetto di compromissione - quick security check

Se durante le fasi precedenti noti processi sconosciuti, connessioni verso IP esterni anomali, file modificati in directory di sistema o utenti che non riconosci, non continuare con il troubleshooting applicativo: passa immediatamente al protocollo di sicurezza. Ho scritto un articolo dedicato alla gestione urgente di intrusioni su VPS con la procedura completa, ma ecco il quick check che eseguo sempre come parte della checklist di emergenza:

# Login SSH recenti riusciti (cercare IP non riconosciuti)
grep "Accepted" /var/log/auth.log | tail -20

# Utenti con shell interattiva
grep -E "/bash|/sh" /etc/passwd

# Crontab di tutti gli utenti (cercare entry sospette)
for u in $(cut -d: -f1 /etc/passwd); do
    crontab -u "$u" -l 2>/dev/null | grep -v "^#" | grep -v "^$" && echo "^^^ utente: $u"
done

# Connessioni di rete attive verso l'esterno
ss -tupn | grep ESTAB | grep -v "127.0.0.1"

# File modificati nelle ultime 24 ore in directory di sistema
find /etc /usr/local/bin /var/spool/cron -mtime -1 -type f -ls 2>/dev/null

Se uno di questi check rivela anomalie, fermati. Non riavviare servizi, non cancellare file. Salva le evidenze e segui il protocollo di incident response - la priorità diventa contenere l'attaccante, non ripristinare il servizio.

Fase 6: ripristino da backup - quando riparare costa più che ricominciare

Se la diagnosi rivela corruzione del filesystem, compromissione grave, o un problema applicativo talmente intrecciato che il debug richiederebbe più tempo del ripristino, la scelta corretta è ripartire da un backup pulito. La condizione necessaria, ovviamente, è avere un backup - e averlo testato.

# Se usi BorgBackup (la mia scelta per VPS)
borg list /path/to/repo                    # elencare i backup disponibili
borg extract /path/to/repo::NOME_ARCHIVIO  # estrarre

# Se usi un dump MySQL
mysql -u root -p < backup_YYYYMMDD.sql

# Verifica integrità del database dopo il ripristino
mysqlcheck -u root -p --all-databases --check

Il problema che trovo nel 70% delle PMI è che il backup esiste ma non è mai stato testato, oppure risiede sullo stesso disco del server di produzione - il che lo rende inutile in caso di guasto hardware o compromissione. Ho approfondito le strategie di backup per VPS unmanaged in un articolo dedicato, con BorgBackup verso storage offsite, retention policy e test di ripristino automatizzati.

Se non hai un backup utilizzabile e il filesystem è corrotto, le opzioni si riducono drasticamente: rescue mode del provider (Hetzner lo offre via Cloud Console), fsck sulla partizione smontata, e tentativo di recupero dei dati. Ho documentato anche questo scenario nell'articolo sul ripristino di filesystem corrotti su VPS.

Fase 7: hardening post-crisi e prevenzione

Ogni emergenza risolta senza un follow-up di prevenzione è un'emergenza che si ripeterà. Dopo aver riportato il server online, dedico sempre almeno mezza giornata a implementare le contromisure che avrebbero impedito il problema:

  • Disco pieno: configurare logrotate per tutti i log applicativi, impostare binlog_expire_logs_seconds in MySQL, aggiungere un alert su df che notifichi quando l'uso supera l'80%
  • OOM kill: dimensionare correttamente innodb_buffer_pool_size, configurare uno swap file, impostare vm.swappiness = 10 per ridurre l'aggressività dello swap
  • Servizio crashato: configurare il restart automatico in systemd con Restart=on-failure e RestartSec=5s, più un alert che notifichi quando il servizio viene riavviato
  • Compromissione: seguire la checklist di hardening completa - SSH solo a chiave, Fail2ban, firewall restrittivo, Lynis audit periodico

Il monitoring minimo che installo su ogni VPS dopo un'emergenza è composto da tre componenti: un cron che controlla lo spazio disco ogni ora e manda email sopra l'80%, un cron che verifica che i servizi critici rispondano (Nginx, PHP-FPM, MySQL) e manda email se non rispondono, e un backup giornaliero automatico verso storage offsite con verifica settimanale dell'integrità. Non è Prometheus con Grafana - quello arriva dopo, se il progetto lo giustifica. Ma questi tre controlli da soli avrebbero evitato l'80% delle emergenze che ho gestito.

Per nuovi clienti Hetzner, puoi ottenere €20.00 di credito gratuito utilizzando questo link con codice sconto - una scelta ideale per aziende europee che necessitano conformità GDPR e data center in Germania.

La differenza tra un VPS che ti tiene sveglio la notte e uno che gira senza pensieri non è il provider o l'hardware - è la preparazione. Una checklist operativa testata, un backup funzionante e un minimo di monitoring trasformano le emergenze da crisi aziendali a incidenti gestibili in meno di un'ora. Se il tuo VPS Debian o Ubuntu è in produzione senza nessuna di queste protezioni, la domanda non è se avrai un'emergenza, ma quando. E quando arriverà, sarà molto più costosa di quanto sarebbe costato prevenirla. Se vuoi mettere in sicurezza la tua infrastruttura prima che sia troppo tardi, contattami: è il tipo di intervento che ripaga l'investimento alla prima crisi evitata.

Ultima modifica: