I permessi in Linux rispondono alla domanda «chi può leggere questo file». AppArmor ne pone un’altra: «che cosa è consentito fare a questo programma». La differenza si vede durante un’intrusione. Una web shell gira con l’utente del server web ed eredita tutti i suoi permessi, cioè la lettura di mezzo sistema. Un profilo AppArmor limita il processo all’elenco di ciò che gli serve per lavorare, e un tentativo di leggere /etc/shadow o di avviare /bin/bash finisce con un rifiuto, indipendentemente dai permessi dell’utente.
Che cosa è già attivo
sudo aa-status
L’output risponde a tre domande: quanti profili sono caricati, quanti di essi sono in modalità enforce e complain, e quali processi girano senza alcun profilo. Su un Ubuntu tipico ci saranno alcune decine di profili, ma quasi tutti per utilità come man e tcpdump. I servizi chiave — nginx, Apache, PHP-FPM — di solito mancano dall’elenco dei processi confinati.
Tre modalità da distinguere:
- enforce: le regole si applicano, tutto il superfluo è vietato;
- complain: le violazioni vengono solo registrate, nulla viene bloccato. È la modalità di messa a punto;
- unconfined: non c’è profilo, il programma gira senza restrizioni.
La parte più utile dell’output di aa-status è l’ultima: i processi in ascolto sulla rete e non limitati da nulla. È l’elenco da cui cominciare.
Gli strumenti
sudo apt install apparmor-utils
Senza quel pacchetto i comandi aa-complain, aa-enforce e aa-logprof nel sistema non esistono, benché AppArmor funzioni.
Come attivare un profilo senza fermare il servizio
L’ordine è fondamentale. Un profilo messo subito in enforce vieterà al servizio, con alta probabilità, qualcosa di necessario, e smetterà di funzionare; di norma non subito, ma in un’operazione rara come un caricamento di file o l’invio di posta.
La sequenza corretta:
sudo aa-complain /etc/apparmor.d/usr.sbin.nginx
Una settimana di funzionamento in quella modalità, coprendo tutti gli scenari eccezionali: un backup, un aggiornamento, il caricamento di file grandi. Poi l’esame di ciò che si è accumulato:
sudo aa-logprof
Il comando scorre le violazioni registrate e chiede per ciascuna se consentirla. Qui serve attenzione: consenta ciò che appartiene davvero al lavoro del servizio, e non tutto di seguito, altrimenti otterrà un profilo che consente tutto e il senso va perduto.
E solo allora:
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx
Dove vedere i rifiuti
Tutte le violazioni finiscono nel journal del kernel:
sudo journalctl -k | grep -i apparmor
sudo grep 'apparmor="DENIED"' /var/log/audit/audit.log
Il secondo file esiste se auditd è installato, e con esso i record sono nettamente più dettagliati. Un record di rifiuto mostra il nome del profilo, l’operazione richiesta e il percorso a cui si accedeva; basta per capire se correggere il profilo o rallegrarsi dello scatto.
Un sintomo vale la pena ricordarlo: un servizio si comporta in modo strano — non legge una configurazione, non scrive in una cartella, non apre un socket — mentre nei suoi registri compare un errore di «permesso negato» con permessi palesemente corretti. È quasi sempre AppArmor, e la prima cosa da fare è guardare il journal del kernel.
Una misura pratica, non teorica
Un profilo per PHP-FPM o nginx si ripaga in modo concreto. Con il processo confinato, una web shell arrivata sul sito non può né leggere i file di sistema, né avviare un interprete, né scrivere fuori dalle cartelle consentite. Un sito violato resta un sito violato invece di trasformarsi in accesso all’intera macchina, ed è proprio quel passaggio a costituire la parte maggiore del danno.
Un ordine ragionevole di adozione: prima un profilo per ciò che guarda a internet (server web, PHP-FPM), poi per i database, quindi secondo necessità. Non serve attivare tutto in una volta, e un insieme universale già pronto non esiste: un profilo dipende da dove vivono i suoi file.
Che cosa verificare con regolarità
I profili tornano allo stato non confinato più spesso di quanto sembri: un aggiornamento di pacchetto può sostituire un file di profilo, un debug manuale lascia un servizio in complain, e un servizio nuovo arriva senza alcun profilo. Due cifre sono utili: quanti profili sono in enforce e quanti processi di rete sono senza restrizioni. Una variazione dell’una o dell’altra merita di essere conosciuta. Come appare riunito su una pagina lo mostra la dimostrazione qui sotto.