VPS compromesso: cosa fare senza ripulirlo
VPS compromesso? Isolalo dal firewall del provider, crea uno snapshot del disco come prova, ruota ogni chiave e ricostruisci tutto da un'immagine pulita.
Non ripulire un VPS compromesso
Se il tuo VPS è stato compromesso, la decisione più importante viene prima di eseguire qualsiasi comando. Non tentare di ripulire la macchina. Isolala presso il provider, crea uno snapshot del disco come prova, ruota tutte le credenziali che conteneva, quindi ricostruisci l'ambiente su un server nuovo usando sorgenti di cui ti fidi.
Non puoi dimostrare che un rootkit sia stato rimosso, perché gli strumenti che dovrebbero dimostrarlo sono sotto il controllo dell'attaccante.
Questo è l'argomento principale. Ecco il meccanismo alla base. Un attaccante che ha ottenuto l'accesso a root può sostituire ps in modo che un determinato process ID non compaia mai nel suo output. Una riga in /etc/ld.so.preload carica il codice dell'attaccante in ogni programma collegato dinamicamente sul sistema, quindi ls, ss e find restituiscono tutti informazioni falsificate nello stesso modo. Un kernel module caricabile può nascondere i file a livello inferiore rispetto alle system call, quindi anche un binario appena scaricato vede un disco integro. Elimini il miner, il grafico della CPU scende e il server torna silenzioso. Anche il silenzio è un comportamento compatibile con un backdoor funzionante.
La ricostruzione costa meno di quanto possa sembrare. Un VPS tipico comprende una serie limitata di package, una directory di configurazione e un data set, quindi la ricostruzione è un'attività finita, con un termine preciso. Cercare ogni modifica effettuata dall'attaccante è un'attività senza un termine definito e non porta mai a una prova.
Confermare che si tratti realmente di una compromissione
Molti server segnalati come violati non lo sono. Migliaia di tentativi di accesso SSH falliti al giorno sono rumore di fondo di Internet, perché ogni indirizzo IPv4 pubblico viene sottoposto a scansioni continue. Un output di lastb pieno di tentativi root e admin indica che gli scanner hanno trovato la porta. Non significa che qualcuno sia riuscito ad accedere.
Questi segnali invece indicano qualcosa:
- Un accesso riuscito che non sai giustificare, ad esempio
Accepted password for root from 203.0.113.7. - Una chiave in
authorized_keysche non hai aggiunto. - Una segnalazione di abuso del tuo provider relativa a traffico in uscita dal server.
- Un processo al 100% di CPU con un nome copiato da un thread del kernel. I miner installati tramite socket Redis e Docker esposti vengono spesso segnalati con nomi come
kdevtmpfsiekinsing. - Connessioni in uscita verso indirizzi che nessuno dei tuoi servizi utilizza.
La contraffazione del nome di un thread del kernel può essere verificata rapidamente. I veri thread del kernel vengono visualizzati tra parentesi quadre e non hanno un eseguibile associato; per questo sudo ls -l /proc/<pid>/exe restituisce No such file or directory quando viene eseguito su di essi. Se un processo visualizzato come [kworker/0:2] ha un collegamento exe che punta a un elemento sotto /tmp, si tratta di un normale programma utente che utilizza il nome di un thread del kernel.
Esegui questi controlli tenendo presente che il server potrebbe fornire informazioni falsificate. Sono sufficienti per stabilire che c’è un problema. Non sono sufficienti per stabilire che non c’è alcun problema.
Interrompi la rete presso il provider, non dall'interno del server
L'isolamento viene prima di tutto, perché ogni operazione successiva è inutile finché qualcun altro mantiene una shell attiva. Consultare i log, ruotare le chiavi e ripristinare i dati non serve se un attaccante ancora attivo li sta monitorando.
Esegui questa operazione nel pannello di controllo del provider, usando il firewall di rete che opera al di fuori del sistema operativo. Blocca il traffico in ingresso e in uscita e mantieni disponibile la console web come modalità di accesso. Le regole applicate a quel livello restano attive indipendentemente da ciò che accade sul disco.
Ci sono due motivi per non eseguire questa operazione dall'interno del server. Un firewall configurato all'interno di un kernel compromesso viene applicato dallo stesso kernel, e root può svuotare le regole nftables con la stessa facilità con cui puoi aggiungerle. Inoltre, sudo ip link set enp1s0 down tramite SSH interrompe prima di tutto la tua sessione, impedendoti di accedere a una macchina che stavi ancora esaminando.
Blocca il traffico in uscita oltre a quello in ingresso. Una reverse shell avvia una connessione dal server verso l'attaccante, quindi un blocco applicato solo al traffico in ingresso lascia perfettamente attiva una connessione già stabilita. Se il provider offre soltanto regole per il traffico in ingresso, le alternative rimaste sono scollegare l'interfaccia di rete oppure arrestare l'istanza.
Non riavviare ancora. Verifica prima se esiste /var/log/journal. Se la directory non è presente, journald scrive in /run/log/journal, che risiede in memoria; un riavvio eliminerebbe quindi le tracce dell'intrusione. Al riavvio scompaiono anche i processi in esecuzione e le relative righe di comando sono spesso le prove più chiare che sarà possibile ottenere.
Crea uno snapshot del disco prima di modificare qualsiasi cosa
In questo caso, snapshot e backup hanno funzioni diverse. Lo snapshot che crei ora è una copia del disco compromesso: costituisce la tua prova ed è l'unico elemento che ti consente di tornare indietro se sovrascrivi qualcosa per errore. I backup precedenti sono il percorso di ripristino. Se il pannello del provider usa i due termini in modo impreciso, leggi prima come gli snapshot VPS differiscono dai backup reali, perché le regole di conservazione e il comportamento del ripristino non sono gli stessi.
Crea lo snapshot dal pannello del provider prima di effettuare nuovamente l'accesso. Uno snapshot a sistema attivo è coerente con un arresto improvviso: acquisisce il disco nello stato in cui si trovava in quell'istante, come se venisse scollegata l'alimentazione. Per la raccolta delle prove è sufficiente. Assegna un nome che impedisca a chiunque di ripristinarlo per errore. Un nome esplicito come COMPROMISED-do-not-restore-2026-08-12 è il livello di prudenza corretto. Conservalo fino al termine dell'indagine e alla chiusura di eventuali ticket per abuso aperti con il provider.
Come accedere quando SSH non è disponibile
Ci sono due possibilità, entrambe nel pannello del provider. La console web (VNC o seriale) si collega alla macchina come se si inserisse una tastiera. Funziona quando sshd è inattivo, quando il firewall è configurato in modo errato e quando l'attaccante ha modificato la porta SSH. Esegue l'autenticazione tramite una password locale; per un server che accetta solo chiavi potrebbe quindi essere necessario reimpostare prima la password di root, affinché la console sia utilizzabile.
La modalità di ripristino è l'opzione migliore. Avvia un piccolo sistema live con il disco collegato ma senza eseguire il sistema installato, quindi i comandi vengono eseguiti in un ambiente affidabile: il kernel compromesso e i binari compromessi non sono in esecuzione. Monta il disco in sola lettura.
lsblk -f
sudo mkdir -p /mnt/victim
sudo mount -o ro /dev/vda1 /mnt/victimSe lsblk mostra volumi LVM (logical volume manager) invece di una partizione semplice, attivali prima con sudo vgchange -ay, quindi monta il dispositivo visualizzato sotto /dev/mapper/.
Non eseguire chroot nel disco montato per esplorarne il contenuto. chroot esegue i binari dell'attaccante con i tuoi permessi e annulla l'intero motivo per cui hai avviato la modalità di ripristino.
Raccogliere le evidenze ancora attendibili
Eseguire questi comandi dalla modalità di ripristino, con il disco montato in sola lettura su /mnt/victim. Iniziare dagli accessi, perché consentono di datare l'intrusione. Tutto il resto è più semplice quando si dispone di un intervallo temporale.
sudo grep -aE 'Accepted (password|publickey)' /mnt/victim/var/log/auth.log
sudo last -f /mnt/victim/var/log/wtmp
sudo lastb -f /mnt/victim/var/log/btmp
sudo journalctl -D /mnt/victim/var/log/journal -u ssh --since "2026-07-01"L'assenza di /var/log/auth.log non è di per sé sospetta. Alcune immagini Ubuntu attuali vengono distribuite senza rsyslog, quindi sshd scrive solo nel journal, come indicato dalla riga journalctl -D. È invece importante rilevare un'interruzione in log altrimenti continui oppure un file di log troncato a zero byte. La cancellazione dei log è comune e di solito viene eseguita in modo approssimativo.
Controllare quindi gli account e le chiavi.
sudo find /mnt/victim/root /mnt/victim/home -name 'authorized_keys*' -exec ls -l {} +
sudo awk -F: '$3 == 0 {print $1}' /mnt/victim/etc/passwd
sudo lsattr /mnt/victim/root/.ssh/authorized_keysLa riga awk stampa ogni account con user ID 0. Qualsiasi valore diverso da root in quell'output indica un secondo account root. Il pattern find corrisponde intenzionalmente anche a authorized_keys2, perché OpenSSH legge per impostazione predefinita entrambi i nomi dei file e il secondo è facile da trascurare. Se lsattr stampa un i nell'elenco degli attributi, il file è immutabile: un attaccante imposta quel flag per fare in modo che il tentativo di eliminare la sua chiave fallisca con Operation not permitted, inducendo un amministratore stanco a credere che la modifica sia stata applicata.
La persistenza si nasconde in pochi punti, quindi controllarli tutti.
sudo ls -lt /mnt/victim/etc/systemd/system
sudo ls -l /mnt/victim/etc/cron.d /mnt/victim/var/spool/cron/crontabs
sudo cat /mnt/victim/etc/ld.so.preload
sudo grep -rnE 'curl|wget|base64|/dev/tcp' /mnt/victim/etc/update-motd.d /mnt/victim/etc/rc.local /mnt/victim/root/.bashrc /mnt/victim/root/.profile/etc/ld.so.preload non esiste in un normale sistema Ubuntu o Debian. Pertanto No such file or directory è il risultato corretto e qualsiasi contenuto richiede attenzione. Un file di login che convoglia l'output di base64 -d in una shell indica lo stesso problema: una configurazione legittima non deve nascondere il proprio contenuto.
Costruire la cronologia usando il tempo di modifica dell'inode, non il tempo di modifica del file.
sudo find /mnt/victim -xdev -newerct '2026-08-01' -type f -printf '%TF %TT %p\n' | sorttouch imposta il tempo di modifica su qualsiasi valore scelto dall'attaccante, quindi il mtime può essere alterato facilmente. Il tempo di cambiamento (ctime) viene aggiornato a ogni modifica dell'inode e touch non può spostarlo indietro. Per questo -newerct produce un elenco più attendibile dei file scritti di recente. Non è comunque una prova, perché root può modificare l'orologio di sistema o scrivere direttamente sul dispositivo a blocchi.
Controllare l'integrità dei pacchetti richiede un solo comando, con una precisazione. Su un sistema in esecuzione, sudo dpkg --verify stampa una riga per ogni file appartenente a un pacchetto il cui checksum non corrisponde più, indicando 5 nella colonna del checksum. sudo debsums -ac svolge la stessa funzione includendo i file di configurazione, quando è installato il pacchetto debsums. Interpretare il risultato in una sola direzione. Un /usr/sbin/sshd modificato è un'evidenza reale. Un report pulito non dimostra nulla, perché lo stesso account root che ha sostituito il binario può riscrivere gli elenchi dei checksum in /var/lib/dpkg/info/. Gli strumenti di scansione dei rootkit, come rkhunter e chkrootkit, seguono la stessa regola: un rilevamento fornisce informazioni, mentre un'esecuzione senza rilevamenti non dimostra che il sistema sia integro.
Copiare fuori dal server ciò che è stato raccolto prima di eseguire operazioni distruttive.
sudo tar --ignore-failed-read -C /mnt/victim -czf /root/evidence-2026-08-12.tgz \
var/log etc root/.ssh root/.bash_history home
sha256sum /root/evidence-2026-08-12.tgzAnnotare l'hash in un luogo esterno al server. Se il caso dovesse diventare una richiesta di risarcimento assicurativo o una denuncia alla polizia, poter dimostrare che l'archivio non è cambiato dalla raccolta fa la differenza tra un'evidenza e una semplice cartella di file. Durante un'indagine è normale eliminare accidentalmente dei dati. Lo snapshot e questo archivio consentono di gestire l'errore. Annullare in seguito un rm errato è molto più difficile di quanto ci si aspetti, come spiegato in recuperare i file eliminati con rm -rf.
Individuare la via di accesso
Una ricostruzione che non chiude la via di accesso porta a una nuova compromissione, spesso entro pochi giorni, perché la scansione che ha individuato il server la prima volta continua senza interruzioni. Quattro vie di accesso spiegano la maggior parte delle compromissioni di un singolo server.
Accesso SSH con password. Una riga Accepted password for root proveniente da un indirizzo che non riconosci è già una risposta sufficiente. Controlla PasswordAuthentication in /etc/ssh/sshd_config e in tutti i file sotto /etc/ssh/sshd_config.d/. sshd usa il primo valore che trova per una direttiva; la riga Include si trova all'inizio del file principale su Ubuntu, quindi un file di configurazione aggiunto in seguito prevale silenziosamente sull'impostazione modificata più avanti nel file.
Un servizio pubblicato senza autenticazione. Redis sulla porta 6379, l'API Docker sulla porta 2375, un database associato a 0.0.0.0 invece che a 127.0.0.1. Docker è la sorpresa più comune. La pubblicazione della porta di un container inserisce regole DNAT (destination network address translation) valutate prima delle chain di ufw, quindi ufw status può indicare una porta come bloccata mentre il container sottostante risponde a tutta Internet. Comprendi questo comportamento prima della ricostruzione: perché le porte pubblicate da Docker bypassano ufw illustra l'ordine delle regole e la correzione.
Un'applicazione web non aggiornata. Cerca nel log degli accessi del web server, in corrispondenza del timestamp sospetto più antico, una richiesta POST verso un percorso di upload o amministrazione. Cerca poi nella document root file con un orario di modifica corrispondente. Un file PHP estraneo in una directory di upload è il risultato tipico.
Una credenziale esposta. Una chiave inserita in un repository, un token incollato in una chat, un file .env pubblicato come file statico da un web server configurato in modo errato. L'automazione rende facile commettere questo errore, ed è un motivo per tenere i secret fuori dagli agenti AI e dai relativi file di configurazione.
Se, dopo tutti questi controlli, non riesci a identificare la via di accesso, presumi che sia stata esposta una credenziale e considera pubblici tutti i secret conservati dalla macchina.
Ruota ogni credenziale che la macchina poteva vedere
Esegui la rotazione dopo aver isolato la rete, mai prima. Se ruoti le credenziali mentre l’attaccante dispone ancora di una connessione, gli consegni semplicemente i nuovi secret.
- Ogni chiave privata SSH archiviata sul server, oltre a ogni account esterno che considerava attendibile la chiave pubblica corrispondente.
- Qualsiasi chiave inoltrata al sistema con
ssh -A. L’agent forwarding lascia un socket in/tmpe root su quella macchina può usarlo per autenticarsi come te ovunque la chiave sia accettata, finché la sessione resta aperta. - I token API nei file
.env, nelle righeEnvironment=di systemd, nella configurazione CI e nelle credenziali dei provider. - Le password dei database e gli account applicativi che le usano.
- Le chiavi private TLS (transport layer security) detenute dal server. Emetti nuovamente il certificato e revoca quello precedente.
- La password dell’account di hosting, attivando l’autenticazione a due fattori. Quel pannello può ricreare server, creare snapshot e aprire console su ogni server di tua proprietà, quindi costituisce il vero perimetro di sicurezza.
- Qualsiasi password digitata in una sessione shell su quell’host mentre era compromesso, perché root può registrare una sessione del terminale mentre si svolge.
Se una password presente su quella macchina viene usata anche altrove, cambiala anche negli altri sistemi. Il riutilizzo delle password è il modo in cui un VPS compromesso porta alla compromissione di un account email.
La checklist per la ricostruzione
- Crea un nuovo server da un'immagine pulita della distribuzione. Non usare lo snapshot del sistema compromesso né un ripristino dell'intero filesystem root.
- Installa i pacchetti dai repository della distribuzione. Non copiare mai un binario dal vecchio disco.
- Ripristina solo i dati, usando un backup datato prima della prima evidenza presente nella timeline. Dump del database, upload e stato dell'applicazione. Lascia
/etc,/usre i vecchi file delle unità fuori dal nuovo sistema. - Inserisci manualmente i secret ruotati. Non copiare il vecchio
.env. - Esamina i contenuti Web ripristinati per individuare i file aggiunti durante la finestra dell'intrusione, prima di pubblicarli di nuovo.
- Applica l'hardening prima di esporre il server: SSH con sole chiavi, un account operativo non-root, un firewall in ingresso con criterio default-deny e nessun servizio pubblicato oltre quanto necessario. Segui i primi dieci minuti su un nuovo VPS, poi metti in sicurezza SSH correttamente e infine aggiungi fail2ban su Ubuntu 24.04 per ridurre il rumore dei tentativi di accesso. Assegna a ogni servizio un account con privilegi minimi dedicato, così il prossimo punto d'appoggio non sarà un accesso root.
- Spegni il vecchio server e conserva il suo snapshot finché l'indagine e ogni ticket relativo a un abuso non saranno chiusi.
- Correggi il sistema di backup. Se il passaggio 3 si è basato su ipotesi, la lezione reale è che la cronologia dei backup era troppo breve per risalire a prima dell'intrusione. I backup versionati su un server esterno, con conservazione prolungata, forniscono un punto di ripristino integro per il futuro: backup restic su un VPS offre entrambe le funzionalità.
Se non puoi datare l'intrusione, non puoi scegliere un backup sicuro. In questo caso ripristina solo i dati che puoi ispezionare visivamente: un dump SQL che puoi leggere o una directory di immagini di cui puoi elencare i file. Considera sospetto tutto ciò che è eseguibile e reinstallalo dai repository.
Cosa significa la segnalazione di abuso del tuo host
La maggior parte delle persone scopre che il proprio server è stato compromesso dal provider, non dal monitoraggio interno. I provider rilevano il traffico in uscita: tentativi di forza bruta SSH contro altre reti, spam sulla porta 25 oppure la partecipazione a un attacco di riflessione. Il ticket contiene normalmente timestamp, porte e un campione dei flussi, oltre a una scadenza espressa in ore.
Rispondi alla segnalazione, anche se puoi soltanto comunicare che il server è stato isolato e verrà ricostruito. I provider instradano il traffico verso il null route o sospendono un server quando un ticket resta senza risposta, trasformando l’incidente in un’interruzione del servizio. Chiedi quindi le righe di log originali alla base della segnalazione. Questi timestamp sono stati registrati al di fuori della tua macchina, quindi sono l’unico elemento della cronologia che l’attaccante non poteva modificare. Spesso consentono di datare l’intrusione con maggiore precisione rispetto a qualsiasi informazione presente sul disco.
Un server cliente compromesso rientra nella normale attività di un host provider, e una gestione corretta dell’incidente non viene considerata negativamente. La questione più ampia di quanto sia sicuro il VPS hosting dipende soprattutto da ciò che configura il cliente. Questa è esattamente la parte che ora puoi rifare da zero.
Quando rivolgersi a un professionista
- Il server conteneva dati personali appartenenti ad altre persone. Ai sensi del GDPR (General Data Protection Regulation), una violazione dei dati personali deve essere notificata all'autorità di controllo senza ingiustificato ritardo e, quando è fattibile, entro 72 ore dal momento in cui se ne viene a conoscenza. Stabilire se questo termine ha iniziato a decorrere è un'attività legale, non di amministrazione dei sistemi.
- Erano coinvolti dati delle carte di pagamento. I circuiti delle carte richiedono un investigatore forense approvato e le proprie verifiche possono compromettere il caso.
- È presente una richiesta estorsiva oppure i dati sono stati cifrati.
- La macchina poteva raggiungere altre macchine: una rete interna, un hypervisor o un CI runner contenente credenziali di produzione. Un host compromesso in un gruppo costituisce un incidente che riguarda l'intero gruppo, fino a prova contraria.
- Sarà necessario che le evidenze siano utilizzabili per una richiesta di risarcimento assicurativo o per le forze dell'ordine. Fermarsi allo snapshot, acquisire un'immagine completa del disco e registrare chi lo ha gestito e quando.
Per un singolo VPS che esegue i propri servizi e non contiene dati di altre persone, la procedura descritta sopra copre l'intero intervento. Isolare il server presso il provider. Creare uno snapshot come evidenza. Raccogliere ciò che è ancora affidabile. Ruotare tutte le credenziali e tutti i secret. Ricostruire il sistema da zero in modo pulito.
FAQ
Posso ripulire un VPS compromesso invece di ricrearlo?
Non con sufficiente certezza, perché chiederesti al sistema compromesso di analizzare se stesso. Un ps sostituito può nascondere un processo, una riga in /etc/ld.so.preload può iniettare codice in ogni strumento con linking dinamico che esegui e un modulo del kernel può nascondere file a tutti i programmi contemporaneamente. Puoi trovare elementi sospetti, quindi un riscontro è significativo. Non puoi dimostrare che non esista altro, quindi un risultato pulito non è una garanzia. La ripulitura è difendibile solo se il server non contiene nulla di importante per te e accetti che possa essere compromesso di nuovo.
Devo spegnere un server compromesso o lasciarlo acceso?
Blocca prima la rete tramite il provider, quindi lascialo acceso abbastanza a lungo da acquisire uno snapshot e controllare i processi in esecuzione. Lo spegnimento distrugge l'elenco dei processi e cancella completamente il journal quando /var/log/journal non esiste, perché journald scrive quindi in memoria sotto /run. Spegnilo comunque se sta attaccando attivamente altre reti e non puoi bloccare il traffico in uscita. Interrompere il danno ha la precedenza sulla conservazione delle prove.
Come posso determinare quando l'attaccante è entrato?
Individua la prima riga Accepted password o Accepted publickey che non riesci a spiegare, in /var/log/auth.log o nel journal. Verificala confrontandola con un elenco delle date di modifica, find / -xdev -newerct 'YYYY-MM-DD' -type f, perché ctime è più difficile da falsificare rispetto a mtime. Confronta quindi entrambe con i timestamp presenti nel ticket di abuso del provider, registrati al di fuori della macchina e non modificabili dal sistema compromesso. Scegli un backup precedente alla prima di queste tre date. Se le date non coincidono, presumi che la compromissione sia precedente alla cronologia dei backup e ripristina soltanto i dati che puoi verificare.
I miei backup sono sicuri da ripristinare dopo una compromissione?
In genere i dati lo sono, dopo un'ispezione. I file di sistema, invece, non lo sono. Un backup eseguito dopo l'intrusione contiene la backdoor, quindi il ripristino dell'intero filesystem root ripristina anche l'accesso dell'attaccante. Controlla anche il repository dei backup: se le credenziali vi erano memorizzate sul server compromesso, la cronologia potrebbe essere stata eliminata o modificata. Questo è uno dei motivi per usare destinazioni di backup append-only o basate sul modello pull. Ripristina i dati delle applicazioni, quindi reinstalla il software dai repository della distribuzione.
Devo informare qualcuno che il mio VPS è stato compromesso?
Rispondi sempre alla notifica di abuso del provider. Per il resto, dipende dai dati presenti sulla macchina e dai relativi titolari. I dati personali appartenenti ad altre persone possono comportare un obbligo legale di notifica, come l'obbligo previsto dal GDPR di informare l'autorità di controllo entro 72 ore. Se sul server erano memorizzate credenziali degli utenti, informa gli utenti affinché possano cambiare le password anche negli altri servizi. Se le chiavi presenti sul server autorizzavano l'accesso a sistemi di terze parti, ad esempio un code host o un account cloud, informa i relativi provider affinché possano verificare eventuali usi impropri. Un server destinato esclusivamente all'uso personale e privo di dati appartenenti ad altre persone non comporta obblighi oltre alla risposta al ticket di abuso.