Alcuni link in questa pagina sono link di affiliazione: se ti registri tramite questi link, il sito riceve una commissione senza costi aggiuntivi per te. Prezzi e consigli non cambiano.
Qualcuno ti passa la password di root di una macchina che gira da anni. Serve siti reali, nessuno ricorda come è stata configurata, e chi l’ha configurata non c’è più.
La tentazione è fare subito la cosa grande: ricostruirla, migrarla, containerizzarla. Fai prima la cosa piccola. Un’ora, cinque domande, e saprai se la macchina è un fastidio o un’emergenza.
Questo è l’audit che abbiamo fatto su una macchina del genere la settimana scorsa, con quello che è emerso davvero. Ogni scoperta qui sotto è reale, e nessuna era visibile dall’esterno.
1. Cosa è in ascolto, e cosa pensa il firewall?
Queste due risposte vanno sempre confrontate, mai lette separatamente. La prima è la verità sulla macchina; la seconda è quello che qualcuno, una volta, intendeva fare.
ss -tlnp # every listening TCP socket, with the process
iptables -L INPUT -n --line-numbers
La nostra scoperta, ed è quella da rubare da questo articolo: il firewall aveva una allowlist accurata per la porta del pannello di amministrazione, tre subnet fidate, scritta da qualcuno che sapeva cosa stava facendo. Quattro righe sopra c’era un ACCEPT generico per la stessa porta da 0.0.0.0/0, aggiunto in seguito.
iptables valuta in ordine e si ferma al primo match. La allowlist, dal momento in cui quella riga è stata aggiunta, non aveva mai permesso niente di meno che a chiunque. Il login amministrativo era aperto a internet da anni dietro una regola che, a un’occhiata distratta, sembrava una restrizione.
Leggi le tue regole dall’alto in basso, con i numeri di riga, e chiediti cosa fa match per primo. Un elenco di regole è un programma, non un insieme.
2. Chi usa davvero la cosa che stai per chiudere?
L’abitudine più utile di tutto l’audit. Prima di chiudere qualsiasi percorso, leggi il suo log di accesso e conta gli utenti reali.
# top talkers against one path, last 10k lines
grep -h 'phpmyadmin' /var/log/nginx/*access* | awk '{print $1}' \
| sort | uniq -c | sort -rn | head
Due delle nostre scoperte sono uscite direttamente da qui:
- Un phpMyAdmin del 2017, raggiungibile da internet, su un server web il cui PHP non aveva più patch a monte. Il log mostrava 201 richieste da un indirizzo e 38 da un altro, entrambi scanner che percorrevano una wordlist. Nessuna sessione umana nella finestra osservata.
- proftpd in esecuzione, in chiaro, senza TLS.
xferlogera vuoto da giugno. Le uniche connessioni erano tentativi di loginanonymousda una botnet.
Entrambi sono stati chiusi in pochi minuti, senza rischio di rompere il flusso di lavoro di nessuno, perché i log dimostravano che non c’era alcun flusso di lavoro. Se i log avessero mostrato sessioni quotidiane da un IP d’ufficio, la risposta sarebbe stata una allowlist e una conversazione, non uno spegnimento.
La regola: non chiudere mai un servizio sulla convinzione che nessuno lo usi. Chiudilo sulla prova che nessuno lo usa. Le due cose sembrano identiche fino a quando chiama l’ufficio fatturazione.
3. Non restare chiuso fuori
Tutto in questa sezione è lavoro sul firewall su una macchina a cui accedi solo tramite quel firewall. Due precauzioni, entrambe economiche.
Arma un ripristino automatico prima di confermare qualsiasi cosa. Un timer che ripristina il ruleset noto-buono in dieci minuti, da annullare a mano solo dopo aver confermato di riuscire ancora a entrare:
iptables-save > /root/iptables.good
echo 'iptables-restore < /root/iptables.good' | at now + 10 minutes
Applica la modifica, apri una nuova sessione SSH da un altro punto, e solo allora annulla il job con atrm. Testare sulla sessione che hai già aperta non prova niente: una connessione già stabilita sopravvive a regole che bloccano quelle nuove.
Poi falla sopravvivere a un riavvio, che è un passaggio separato e quello che si dimentica sempre:
service iptables save # or: netfilter-persistent save
systemctl is-enabled iptables
La nostra si riavviava secondo una pianificazione settimanale di cui non sapevamo nulla. L’irrobustimento era ancora lì dopo, perché le regole erano state salvate, e sapevamo che era ancora lì perché abbiamo controllato dopo il riavvio invece di darlo per scontato.
4. Cosa si rinnova da solo, e cosa sembra soltanto farlo?
Il killer silenzioso. Su questa macchina, il rinnovo TLS era un job dentro un control panel la cui licenza era scaduta due mesi prima. Il cron di rinnovo è morto con la licenza. Quattro siti stavano già fallendo l’handshake TLS da cinque giorni prima che l’audit lo scoprisse, e altri sette erano in programma per scadere entro tre settimane.
# every scheduled job on the box, in one pass
crontab -l; ls -l /etc/cron.*/ /etc/cron.d/; systemctl list-timers --all
Leggi tutto, incluse le righe commentate, perché ti dicono cosa girava prima. E cerca i duplicati: abbiamo disabilitato un cron di rinnovo e solo a un secondo passaggio abbiamo trovato un secondo, stesso job, ora diversa, quattro righe più sotto.
Riprendere in mano il rinnovo è un lavoro breve anche su una distro a fine vita - lo abbiamo descritto in acme.sh su un server dove certbot non si installa.
5. Cosa è installato che nessuno usa?
Le macchine legacy accumulano runtime. La nostra aveva undici build PHP separate, fino alla 5.2. La domanda interessante non è cosa è installato ma cosa è collegato:
grep -rhoE 'php[0-9]+' /etc/nginx/conf.d/*.conf /etc/httpd/conf.d/*.conf \
| sort | uniq -c | sort -rn
Otto siti erano sulla 7.4, tre sulla 8.0, e ogni build più vecchia era peso morto. Quel singolo comando ha cambiato il piano di migrazione: una macchina che sembra aver bisogno di una piattaforma di hosting che supporti PHP 5.2 in realtà ha bisogno di 7.4 e 8.x, cioè di qualcosa di moderno.
Un audit non riguarda solo cosa chiudere. Riguarda anche scoprire che la parte spaventosa del lavoro non esiste.
Cosa ha comprato un’ora
Quattro scoperte su una macchina: una allowlist che permetteva a chiunque, uno strumento di amministrazione di nove anni esposto agli scanner, un demone FTP che non serviva nessuno, e un rinnovo dei certificati morto da due mesi con quattro siti già giù.
Niente di tutto questo ha richiesto una ricostruzione. Niente ha richiesto una finestra di manutenzione. Tre delle quattro cose sono state risolte nella stessa ora, e la quarta - la distro stessa a fine vita - è l’unica scoperta onesta che non si può correggere con una patch, ed è esattamente per questo che appartiene al piano di migrazione e non al lavoro di oggi.
Se l’audit ti manda a caccia di una macchina sostitutiva, abbiamo confrontato le opzioni con prezzi reali in Miglior VPS per il self-hosting nel 2026, e raccontato quattro anni su un solo provider nella nostra recensione di Hetzner Cloud.