Un server si configura una volta e poi vive per conto suo. Un mese dopo alcuni pacchetti aspettano l’aggiornamento, il certificato è arrivato a tre settimane dalla scadenza, dopo l’installazione di qualcosa di estraneo nella configurazione SSH è comparsa una riga in più, e il jail che dovrebbe sorvegliare gli accessi si è fermato senza che nessuno se ne accorgesse. Niente di tutto questo grida. Tutto semplicemente smette, in silenzio, di essere vero.
Qui sotto dodici cose che vale la pena controllare con regolarità, con i comandi. Il giro richiede una quindicina di minuti. L’ordine va da ciò attraverso cui si entra a ciò che si rompe da solo.
SSH: cinque righe
Da guardare non è il file ma la configurazione effettiva: si compone di /etc/ssh/sshd_config, dell’intera cartella sshd_config.d e dei valori predefiniti della compilazione.
sudo sshd -T | grep -iE 'permitrootlogin|passwordauthentication|permitemptypasswords|maxauthtries|x11forwarding'
Quello che vogliamo vedere: permitrootlogin no, passwordauthentication no, permitemptypasswords no, maxauthtries a 3–4 e x11forwarding no. Le prime tre sono la porta; le ultime due i suoi cardini — un tetto ai tentativi per connessione e un inoltro grafico di cui un server non ha alcun uso.
Due avvertenze, due modi facili di chiudersi fuori. Primo: non disattivate l’accesso con password e quello di root prima di aver verificato che la vostra chiave funziona, in una sessione separata e senza chiudere quella in corso. Se state leggendo questo collegati come root con una password, quelle due righe chiuderanno fuori proprio voi.
Secondo: l’ordine dei file. OpenSSH prende il primo valore che incontra per un parametro, e i file in sshd_config.d si leggono in ordine alfabetico. Le immagini cloud di solito ci lasciano un 50-cloud-init.conf, che avrà la meglio sul vostro file se lo avete chiamato per esempio 90-hardening.conf. Le impostazioni proprie vanno con un numero più basso — 00- oppure 10-. E il risultato si verifica con sshd -T, non rileggendo il file.
Firewall: un controllo
sudo ufw status verbose
Qui va ricordato che l’output mostra intenzioni, non risultati. Una regola può stare nell’elenco e non chiudere nulla: UFW stesso è disattivato, la porta è servita da qualcosa pubblicato da Docker (che scrive le proprie regole in iptables sotto UFW), oppure il traffico raggiunge il server per un’altra strada. Conviene quindi confrontare l’elenco delle regole con ciò che davvero è in ascolto verso l’esterno:
sudo ss -tulpn | grep -v '127.0.0.1\|::1'
fail2ban: due controlli
Non basta che il servizio sia in esecuzione: serve anche un jail funzionante per SSH.
sudo fail2ban-client status
sudo fail2ban-client status sshd
Il guaio più frequente qui è un jail muto. Su Debian 12 e sulle Ubuntu recenti /var/log/auth.log può non esistere affatto: rsyslog non è installato e le registrazioni vivono solo in journald. Un jail con il logpath di serie allora parte, si dichiara attivo e non banna mai nessuno. Si cura puntandolo al journal di systemd:
printf '[sshd]\nenabled = true\nbackend = systemd\n' | sudo tee /etc/fail2ban/jail.d/sshd-systemd.local
sudo systemctl restart fail2ban
Il segnale che permette di coglierlo senza frugare nelle configurazioni: in fail2ban-client status sshd le voci «Currently failed» e «Total failed» restano a zero mentre nel journal gli accessi falliti ci sono eccome.
Aggiornamenti: tre controlli
Separatamente: quanti pacchetti aspettano in tutto, quanti di questi riguardano la sicurezza e se il sistema chiede un riavvio dopo un aggiornamento del kernel.
sudo apt update
apt list --upgradable 2>/dev/null | grep -c -- '-security'
ls /var/run/reboot-required 2>/dev/null && echo 'serve un riavvio'
Il terzo controllo riguarda l’attivazione degli aggiornamenti di sicurezza automatici, perché i primi due non diventino un rito mensile:
systemctl status unattended-upgrades --no-pager
cat /etc/apt/apt.conf.d/20auto-upgrades
In quel file deve esserci un 1 su entrambe le righe. Se il pacchetto manca: sudo apt install unattended-upgrades && sudo dpkg-reconfigure -plow unattended-upgrades.
Certificati: un controllo
Un certificato Let's Encrypt vive novanta giorni, e il rinnovo funziona da solo esattamente fino al giorno in cui non funziona più. Da guardare non è il pannello del registrar, ma ciò che il server serve davvero:
echo | openssl s_client -connect localhost:443 -servername example.com 2>/dev/null | openssl x509 -noout -enddate
sudo certbot renew --dry-run
Il primo comando dà la data di scadenza del certificato servito per quel nome; il secondo verifica che il rinnovo andrà a buon fine senza aspettare la scadenza vera. Conviene passare in rassegna tutti i nomi che il server serve, non solo il dominio principale: quello che si dimentica è di regola il sottodominio aggiunto più tardi.
Disco: un controllo
df -h
df -i
Due comandi, perché lo spazio e i record dei file si esauriscono in modo indipendente. Sulla maggior parte dei server il secondo tocca il soffitto per primo: milioni di file minuscoli nelle sessioni PHP o nella cache dell’applicazione portano l’IUse% a 100 con gigabyte ancora liberi. Su entrambi i casi abbiamo un articolo a parte.
Che cosa non va in questo elenco
L’elenco è giusto, ma ha una proprietà: richiede che qualcuno se ne ricordi. Quindici minuti a settimana sono pochi, finché il server è uno solo e finché c’è un motivo. Dopo due mesi tranquilli il giro salta, e che il jail si è fermato lo si scopre dai log di qualcun altro.
Per questo abbiamo raccolto esattamente questi dodici controlli in un pannello gratuito a parte — Arcivéo FREE. Si installa con un comando, gira sul vostro server, non ci manda nulla e non richiede registrazione. Un raccoglitore parte da cron ogni cinque minuti e scrive le stesse cose in un database locale: accessi SSH e connessioni rifiutate, stato di UFW e fail2ban, aggiornamenti di sicurezza in attesa, scadenze dei certificati, spazio su disco. Lo storico è di sette giorni, l’interfaccia esiste in 34 lingue. Il prezzo è zero, anche su un server di lavoro: la licenza consente di installare il pannello su macchine proprie, comprese quelle aziendali, e non consente di rivenderlo né di offrirlo come servizio per server altrui.
Lo stack dell’edizione gratuita è modesto: installa e attiva UFW e fail2ban, e da lì in poi ne mostra lo stato. ModSecurity, Suricata, AIDE e gli altri moduli non ci sono, quelli appartengono alla versione a pagamento. Ma per smettere di portarsi in testa il giro settimanale basta. Come appaiono gli stessi dati sul pannello completo lo mostrano le pagine demo qui sotto.