La prima esecuzione di Lynis su un VPS appena creato dà di solito qualcosa attorno a 60 e un lungo elenco di suggerimenti in cui non si sa da dove cominciare. La buona notizia: 80-85 sono il lavoro di una serata, e la maggior parte dei passaggi non è cosmetica ma davvero utile. La cattiva: gli ultimi quindici punti sono irraggiungibili su una macchina virtuale in affitto, e inseguirli è un errore.

Che cosa mostra l’indice e che cosa no

L’indice di hardening è il rapporto ponderato fra test superati e totale, non una percentuale di sicurezza. Lynis esegue circa trecento test e produce due elenchi distinti: warnings, che sembrano problemi reali, e suggestions, cioè ciò che si potrebbe migliorare. Cominci sempre dagli avvisi; di solito sono pochi.

Cento punti non esistono: alcune raccomandazioni presuppongono scelte fatte all’installazione del sistema (partizioni separate per /home, /tmp e /var), altre richiedono un accesso al bootloader che un VPS non ha, altre ancora si contraddicono. E confrontare il proprio indice con quello altrui non serve a nulla: Lynis toglie punti per ciò che gira sulla macchina. Ogni servizio attivo è una porta aperta in più, una configurazione propria e una dozzina di nuovi suggerimenti, ed è per questo che i valori alti si trovano soprattutto dove non gira nulla oltre a SSH. Per un server di lavoro con sito, database e posta, 85 è un buon risultato.

Eseguire come root

sudo lynis audit system

Senza sudo Lynis salta tutti i test che richiedono file di sistema e riporta un indice più basso, non perché il server sia scadente ma perché i controlli non si sono visti. Il rapporto finisce in /var/log/lynis-report.dat, il registro leggibile in /var/log/lynis.log.

Ogni riga dell’output comincia con un identificatore di test come SSH-7408 o KRNL-6000. Con quell’identificatore si trovano sia la spiegazione sia il modo di disattivare un test: ne ricordi la forma, tutto il resto ruota attorno ad essa.

Che cosa muove davvero il numero

SSH (SSH-7408). Il blocco più pesante: un solo test verifica una dozzina di parametri insieme. Non modifichi tutto il sshd_config, metta un file a parte così che un aggiornamento del pacchetto non cancelli il suo lavoro:

sudo tee /etc/ssh/sshd_config.d/10-hardening.conf <<'EOF'
PermitRootLogin no
PasswordAuthentication no
MaxAuthTries 3
MaxSessions 2
X11Forwarding no
AllowTcpForwarding no
ClientAliveInterval 300
ClientAliveCountMax 2
LogLevel VERBOSE
TCPKeepAlive no
EOF
sudo sshd -t && sudo systemctl reload ssh

sshd -t prima di ricaricare il servizio è obbligatorio: un errore nella configurazione con la sessione aperta la lascerà fuori. E prima di mettere PasswordAuthentication no, si accerti che la chiave funzioni davvero, da un secondo terminale aperto.

Parametri del kernel (KRNL-6000). Il test verifica una ventina di valori sysctl. Un file per loro:

sudo tee /etc/sysctl.d/99-hardening.conf <<'EOF'
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
kernel.sysrq = 0
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.all.log_martians = 1
EOF
sudo sysctl --system

Strumenti mancanti. Buona parte dei suggerimenti si riduce a «installi ciò che non c’è»: auditd (registro degli eventi di sistema), aide (integrità dei file), debsums (integrità dei pacchetti), unattended-upgrades (aggiornamenti di sicurezza automatici), sysstat e acct (contabilità dei processi), un antivirus. Ognuno chiude uno o due suggerimenti, ma li installi non per i punti: senza di essi dopo un incidente non ricostruirà nulla.

Piccolezze con un buon rapporto sforzo/risultato. umask 027 in /etc/login.defs; la scadenza delle password nello stesso file; i banner /etc/issue e /etc/issue.net; i compilatori leggibili solo da root (chmod 700 /usr/bin/gcc). Sui banner, con franchezza: alla sicurezza non aggiungono nulla, sono una formalità giuridica, ma un punto lo danno.

Una trappola in login.defs

Modificare umask con una sostituzione di riga tramite sed lascia spesso più righe UMASK nel file. Lynis allora non considera il valore, e il test AUTH-9328 resta rosso benché l’impostazione sembri fatta. Verifichi dopo la modifica:

grep -c '^UMASK' /etc/login.defs

Ne deve essere esattamente una. Lo stesso vale per qualsiasi altro parametro di quel file.

Falsi positivi e come metterli a tacere correttamente

Alcuni avvisi non riguardano affatto il suo server. Un esempio reale: sul VPS di un grande provider il test PKGS-7388 segnala che non è stato trovato un repository di sicurezza, semplicemente perché i repository sono descritti in formato deb822 con un riferimento a un file di mirror, mentre Lynis cerca la riga consueta. Gli aggiornamenti di sicurezza, però, arrivano perfettamente.

Questo si mette a tacere non cancellando righe dal rapporto ma con un profilo. I file di profilo hanno estensione .prf (non .prof: lì si perde facilmente mezz’ora), e le sue regole vanno in /etc/lynis/custom.prf:

skip-test=PKGS-7388
skip-test=KRNL-5788

Una regola: accanto a ogni riga ci vuole un commento sul perché il test viene saltato. Fra sei mesi non ricorderà se è stato disattivato perché non si applica o perché sistemarlo era una seccatura, e la differenza fra questi due casi è tutta la questione.

Che cosa non fare

Non insegua la cifra. L’indice si gonfia facilmente disattivando i test scomodi, e oltre un certo livello quella è l’unica via, solo che il server non diventa più sicuro. È utile altro: fissare il proprio valore e sorvegliarne le variazioni. Un indice che cala dopo un aggiornamento o dopo una modifica di configurazione fatta da altri è un segnale molto più prezioso della sua grandezza assoluta.

Proprio per questo conviene eseguire Lynis su pianificazione e non una volta sola, conservando i rapporti per avere con che cosa confrontare. Come appare tutto riunito su una pagina lo mostra la dimostrazione qui sotto: l’indice, l’elenco degli avvisi con i loro identificatori di test e ciò che è cambiato dall’esecuzione precedente.