Premessa off-topic: il sottoscritto non solo è al suo primo articolo su Il Portalinux, ma è anche alla sua prima esperienza con un qualunque tipo di CMS e con X/HTML. Eventuali schifezze di formattazione sono quindi giustificate.
P.S.: WordPress, a malapena ti conosco, e già ti odio!!! Ora passiamo alle cose serie(!!!).
Avete mai abitato in un condominio? Avete presente la vecchia pettegola, che magari abita al piano terra, agli occhi della quale nessuno quindi può sfuggire, nè per le scale nè per l’ascensore? Quella che la mattina vi incontra e con sorriso sornione vi fà:
“Cchi occhiu stancu c’aviti…e cu era chidda bedda fhijjola cchi vinna mu vi trova ieri sira? Chidda chi caminava ‘nsema a vui, tutti i dui ‘mbriachi ‘na pezza, vattennu mura mura, versi i tri e nu quartu/tri e vinticinqua?”1
(Come faccia questa gente ad essere sveglia sia al mattino presto quando le persone serie vanno a lavoro, che a tarda notte quando il restante 90% della popolazione sotto i trenta torna a casa, rimane ancora un mistero!)
Insomma, la migliore alleata dell’amministratore di condominio.
Perfetto, allora l’analogia è semplice e calzante: il kernel è il condominio, voi siete l’amministratore, gli appartamenti/inquilini sono le syscall, gli ospiti sono i processi. E la vecchia? E la vecchia è audit! Che domande…
Audit è una funzionalità dei kernel 2.6.x che, su richiesta, monitora le chiamate di sistema al kernel, memorizzando sotto forma di log le informazioni desiderate sul chiamante, la chiamata, e l’oggetto della stessa.
Premetto che questa non vorrà essere una guida esaustiva all’utilizzo di audit, ma solo un articolo che possa portare a conoscenza dei più l’esistenza ed i concetti chiave di uno strumento che può far comodo anche in determinate situazioni dell’uso desktop, nonostante il suo target principale siano i sysadmin. Io ad esempio l’ho studiato un po’, per cercare di capire quale sia il processo che si ostina a modificare e riportare a default un file nella mia home che ho personalizzato. Vale la pena in questo caso, ancor più che in molti altri, ribadire l’importanza della lettura del man, che fornisce informazioni decentemente esaurienti sulle innumerevoli possibilità di configurazione.
Componenti in Userspace
Come ogni servizio in kernelspace, per poterlo utilizzare da utenti abbiamo bisogno di strumenti che girino in userspace. Il software che prenderemo in considerazione è audit di Red Hat, disponibile nei repo della maggior parte delle distribuzioni maggiori: per Arch Linux è reperibile tramite AUR, per Debian/Ubuntu col nome di auditd nei repo ufficiali (repo universe per ubuntu).
I principali tool presenti nel pacchetto sono 3:
- auditd, demone in ascolto su determinati elementi, in base alle regole impostate
- auditctl, tool per la gestione del sistema di monitoraggio, e la creazione di regole a runtime
- ausearch, strumento per la ricerca all’interno del log, tramite filtri
Ne sono presenti anche altri, ma per le nostre esigenze questi consentono di fare tutto abbastanza agevolmente.
Il procedimento per il monitoraggio tramite questo servizio è abbastanza lineare: si avvia il demone, si impostano le regole, e quando lo si ritiene opportuno si interroga il log per controllare eventuali voci che contemplino ciò su cui si vuole indagare.
Avvio e Configurazione del Demone
Il demone auditd si configura tramite il file /etc/audit/auditd.conf (l’avreste mai detto???), e per un uso sporadico e superficiale, le impostazioni di default vanno più che bene. La personalizzazione quindi è destinata solo a chi ha intenzione di farne un uso più intensivo (mica noi, che facciamo della zappa la nostra forma di sostentamento principe).
L’avvio del demone, vi stupirò, si ottiene con un semplice auditd start
(ovviamente dalla directory contenente il demone).
Se decideste di scrivere una nuova regola statica all’interno di “/etc/audit/audit.rules” mentre il demone è già in esecuzione, ricordatevi di riavviarlo con auditd restart
perchè questa venga utilizzata. (personalmente ho provato anche il semplice auditd reload, ma non ha funzionato)
Impostazione delle Regole
Questo passaggio è un buon 90% di tutto ciò che c’è da sapere. Innanzitutto, precisiamo che ci sono due modi per impostare le regole per audit: in maniera statica tramite “/etc/audit/audit.rules”, o a runtime tramite il tool auditctl. Le differenze nella sintassi da utilizzare tra i due metodi sono nulle. All’interno di “/etc/audit/audit.rules” infatti, bisognerà scrivere tutto ciò che si digiterebbe nel terminale utilizzando il metodo alternativo, fatta esclusione per il nome del comando “auditctl”.
Prendiamo ad esempio una regola, volutamente di media complessità, in modo da poter illustrare i parametri fondamentali che si possono utilizzare. In realtà non è molto utile (versione politically correct di “non serve a un c***o”).
auditctl -a exit,always -S open -F auid=510 -F path=/etc/shadow -F dir=/opt/ -F pid=1005 -F k=stringa_chiave -p warx
Se volessimo usarla all’interno di audit.rules anzichè lanciarla da terminale, aggiungeremmo al file
-a exit,always -S open -F auid=510 -F path=/etc/shadow -F dir=/opt/ -F pid=1005 -k stringa_chiave -p warx
Cominciamo con lo spiegare i vincoli che abbiamo posto al nostro monitoraggio:
-a exit,always
con lo switch -a è possibile specificare una coppia [list],[action] , alla quale il resto della regola viene assegnato.
Le liste possiamo considerarle come delle preimpostazioni di regole, in coda alle quali questo switch consente di aggiungere una nostra regola (il resto della riga). I valori comunemente utilizzati per la lista sono “exit” e “exclude”: il primo solleva l’evento all’uscita della syscall monitorata (a differenza, ad esempio, di “task” che generando l’evento all’avvio di una syscall, non sarà in grado di restituire valori per molte proprietà, non ancora definite in quel momento), mentre il secondo esclude dal log gli eventi che corrispondono ai parametri specificati nel resto della regola. Per gli altri (poco utilizzati) vi rimando al man.
Le azioni invece possono avere solo i valori [always] e [never] , rispettivamente:
si, solleva gli eventi
no, di questi proprio non me ne frega niente.
-S open
molto semplicemente si specifica quali syscall si vogliono monitorare, in questo caso ho messo solo open, ma si può specificare qualsiasi nome o numero di syscall. Oppure si può utilizzare “all” per…non indovinerete mai….
Il monitoraggio delle syscall può avere effetti parecchio degradanti sulla reattività di tutti i programmi, è consigliabile riuscire a condensare più monitoraggi possibili nella stessa regola (ove questo sia possibile ovviamente), e possibilmente limitarli alle porzioni di filesystem realmente interessanti.
-F
questo switch merita un discorso a parte: non ha un solo compito, ma piuttosto consente di rendere la regola più specifica in base al nome da cui è seguito, detto “campo”, cui a sua volta è possibile assegnare un valore. Va ripetuto per ogni campo utilizzato. Vediamone alcuni:
auid=
solleva eventi solo per syscall generate da processi con auid=510 (numero arbitrario, si mette quello che si vuole monitorare). Cos’è l’auid? È una roba che si inventa audit, un identificativo che rimane invariato anche dopo che l’utente ha “switchato” ad esempio con su o sudo modificando i propri UID e EUID. Siete sbronzi da far schifo e non volete che la vicina vi sgami? Ideona, fuori dal portone vi infilate nasone, baffi finti e parrucchino…ma lei vi sgama lo stesso: perchè vi controllava già prima che entraste, e vi ha fatto la foto mentre vi camuffavate. Questa vecchia diventa ogni giorno più inquietante! O.o
path=
controlla gli accessi al file specificato come argomento (/etc/shadow nel nostro caso). Si può anche decidere di limitare il monitoraggio a determinati tipi di accesso, tramite un altro switch che vedremo in seguito.
dir=
monitora la directory e tutte le sue sottodirectory
pid=
non voglio insultare la vostra intelligenza…
-k stringa_chiave
consente di marcare una regola con una parola chiave a scelta, in modo da poterle virtualmente raggruppare, come un tag. Ad esempio se avete impostato tante regole per uno stesso motivo, ed ora avete risolto il vostro problema e non vi servono più, se avrete avuto l’accortezza di marcarle tutte con la stessa parola chiave, potrete eliminarle in un colpo solo senza intaccare le altre. Questa opzione può essere passata anche come campo key= del parametro -F
Per tornare al nostro esempio, voi siete stati taggati dalla vecchia nella categoria “viziosi”. Se la categoria è molto affollata: o abitate in un quartiere malfamato, o la vicina è una tipa all’antica.
-p warx
specifica quali permessi devono avere le syscall su directory o file perchè vengano monitorate. Attenzione, non hanno nulla a che vedere con i permessi del file, questi indicano i permessi con la quale la syscall è stata richiamata.
Per intenderci, se apriamo un file in scrittura, la syscall open verrà passata con la richiesta di write, quindi sarà sollevato un evento solo se la vostra regola ha specificato anche l’argomento w del parametro -p. Gli altri stanno nell’ordine per
a attribute change, modifica di proprietario o permessi
r lettura
x esecuzione
anche questo parametro ha un equivalente utilizzabile come campo dello switch -F, parm=
I monitoraggi su file e directory sono anche chiamati “watches”, ed era uso alcuni anni fa effettuarli tramite lo switch -w /path/to/dir_or_file
, piuttosto che con il monitoraggio della syscall passando al parametro -F i relativi campi. Attualmente non vi è alcun vantaggio ad utilizzare -w /path/to/dir_or_file
, in quanto in maniera trasparente questo viene ormai trasformato dal demone stesso in -a always,exit -F path=/path/to/file
oppure -a always,exit -F dir=/path/path/to/dir
, ed inoltre lo switch -w accetta come ulteriori specializzazioni solo -p e -k.
Sono inoltre in contatto con un dev in mailing list, visto che provando ad usare -w, mi sono accorto che non vengono rilevate le modifiche al file effettuate tramite il redirect di una echo. Questo era un vecchio bug dovuto al fatto che il redirect da shell invia una syscall open con parametro creat, in modo da generare il file di sana pianta se questo non esistesse. Questo comportamento manda però al manicomio audit, che sminchia il rilevamento dell’inode. Dobbiamo ancora capire se sia un bug o una mia cappellata (molto probabile la seconda). L’esplicita lettura della syscall invece funziona perfettamente.
Per citare alcuni switch utili da passare ad aucitctl per la gestione delle regole, a differenza di quelli visti finora che servono per la loro creazione:
-l
elenca, una per linea, le regole impostate. Possiamo anche filtrarle tramite una key, se l’abbiamo assegnata.
-D
elimina TUTTE le regole impostate, oppure quelle contrassegnate da una chiave che può essergli passata come parametro.
Interrogazione del Log degli Eventi
La nostra vecchia osserva e annota tutto, ma per una massima efficienza ha messo a punto anche degli strumenti per una rapida consultazione del suo archivio di c***i degli altri. Uno di questi è ausearch.
Ausearch altro non fa che mostrarci il contenuto del log, fornendo delle utili manipolazioni per renderlo più leggibile e mirato agli eventi che ci interessano. Fra gli switch più utili troviamo:
-c nome_comando
restituisce solo i risultati associati al comando passatogli come parametro. In pratica solo gli eventi sollevati da quel comando.
-f nome_file
restituisce solo gli eventi correlati all’accesso ad un determinato file
-i
interpreta i valori numerici, restituendo direttamente la loro stringa corrispondente, ad esempio visualizzando al posto dell’UID numerico, il nome dell’utente. ATTENZIONE: la conversione viene effettuata al momento della query, non al sollevamento dell’evento. Ciò comporta che se all’esecuzione di ausearch -i, le associazioni [numero][nome] sono differenti rispetto a quando l’evento è stato sollevato, si avrà un’interpretazione errata. Se ad esempio abbiamo riavviato la sessione, o abbiamo cambiato utente, i risultati potrebbero essere fuorvianti.
-k chiave
filtra in base alla chiave (se abbiamo avuto l’accortezza di assegnarla).
Per tutto il resto c’è Mastercard man
Tenete presente che può rivelarsi utile passare, tramite il bootloader, il parametro audit=1 al kernel, per fare in modo che alcuni componenti che verrebbero normalmente avviati prima del servizio audit, non sfuggano al suo controllo.
Ricordo che il man fornisce queste pagine auditd.conf(5), ausearch(8), auditctl(8), audit.rules(7), ed altre ancora riferite a funzioni che non abbiamo preso in considerazione.
Vi consiglio inoltre vivamente di cambiare casa o di provare con la tecnica “pan-per-focaccia”: stringere un patto con gli altri condomini in modo da tenere sotto strettissima, ostentata ed ingombrante osservazione la vicina. Ciò potrebbe produrre una presa di coscienza in quest’ultima che la porterebbe a mitigare la sua invadenza, ma potrebbe altresì ingenerare un sentimento di sfida, fautore di una spirale di altrui-cazzismo che culminerebbe inevitabilmente nell’omicidio aggravato da futili motivi.
A voi la scelta.
- ha avuto ospiti ieri sera?