L'auditing è il monitoraggio e la registrazione delle azioni selezionate del database dell'utente. Viene in genere utilizzato per indagare su attività sospette o monitorare e raccogliere dati su attività specifiche del database. Ad esempio, l'amministratore del database può raccogliere statistiche su quali tabelle vengono aggiornate, quante operazioni vengono eseguite o quanti utenti simultanei si connettono in determinati momenti.
In questo post del blog tratteremo gli aspetti fondamentali dell'auditing dei nostri sistemi di database open source, in particolare MySQL, MariaDB, PostgreSQL e MongoDB. Questo articolo è rivolto agli ingegneri DevOps che generalmente hanno meno esperienza o esposizione nelle best practice di conformità all'audit e una buona governance dei dati quando gestiscono l'infrastruttura principalmente per i sistemi di database.
Verifica dichiarazione
Controllo istruzione MySQL
MySQL ha il registro delle query generali (o general_log), che fondamentalmente registra ciò che sta facendo mysqld. Il server scrive le informazioni in questo registro quando i client si connettono o si disconnettono e registra ogni istruzione SQL ricevuta dai client. Il registro delle query generali può essere molto utile durante la risoluzione dei problemi, ma non è realmente creato per il controllo continuo. Ha un grande impatto sulle prestazioni e dovrebbe essere abilitato solo durante brevi intervalli di tempo. Esistono altre opzioni per utilizzare invece le tabelle performance_schema.events_statements* o il plug-in di controllo.
Controllo delle istruzioni PostgreSQL
Per PostgreSQL, puoi abilitare log_statment su "all". I valori supportati per questo parametro sono none (off), ddl, mod e all (tutte le istruzioni). Per "ddl", registra tutte le istruzioni di definizione dei dati, come le istruzioni CREATE, ALTER e DROP. Per "mod", registra tutte le istruzioni DDL, oltre alle istruzioni di modifica dei dati come INSERT, UPDATE, DELETE, TRUNCATE e COPY FROM.
Probabilmente devi configurare i parametri correlati come log_directory, log_filename, logging_collector e log_rotation_age, come mostrato nel seguente esempio:
log_directory = 'pg_log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_statement = 'all'
logging_collector = on
log_rotation_age = 10080 # 1 week in minutes
Le modifiche di cui sopra richiedono un riavvio di PostgreSQL, quindi si prega di pianificare attentamente prima di applicare al proprio ambiente di produzione. È quindi possibile trovare i registri correnti nella directory pg_log. Per PostgreSQL 12, la posizione è in /var/lib/pgsql/12/data/pg_log/ . Si noti che i file di registro tendono a crescere molto nel tempo e potrebbero consumare lo spazio su disco in modo significativo. Puoi anche usare log_rotation_size invece se hai uno spazio di archiviazione limitato.
Controllo delle dichiarazioni MongoDB
Per MongoDB, ci sono 3 livelli di registrazione che possono aiutarci a controllare le istruzioni (operazioni o operazioni nel termine MongoDB):
-
Livello 0 - Questo è il livello predefinito del profiler in cui il profiler non raccoglie dati. Il mongod scrive sempre operazioni più lunghe della soglia slowOpThresholdMs nel proprio registro.
-
Livello 1 - Raccoglie i dati di profilazione solo per operazioni lente. Per impostazione predefinita, le operazioni lente sono quelle inferiori a 100 millisecondi. È possibile modificare la soglia per le operazioni "lente" con l'opzione di runtime slowOpThresholdMs o il comando setParameter.
-
Livello 2 - Raccoglie i dati di profilazione per tutte le operazioni del database.
Per registrare tutte le operazioni, impostare db.setProfilingLevel(2, 1000), dove dovrebbe profilare tutte le operazioni con operazioni che richiedono più tempo dei millisecondi definiti, in questo caso è 1 secondo (1000 ms) . La query da cercare nella raccolta di profili di sistema per tutte le query che hanno richiesto più di un secondo, ordinate per timestamp decrescente sarà. Per leggere le operazioni, possiamo utilizzare la seguente query:
mongodb> db.system.profile.find( { millis : { $gt:1000 } } ).sort( { ts : -1 } )
Inoltre, esiste il progetto Mongotail, che semplifica il processo di profilazione delle operazioni con uno strumento esterno invece di interrogare direttamente la raccolta profili.
Tenere presente che non è consigliabile eseguire il controllo completo delle istruzioni nei server di database di produzione poiché introduce comunemente un impatto significativo sul servizio di database con un enorme volume di registrazione. Il modo consigliato consiste nell'utilizzare invece un plug-in di audit del database (come mostrato più in basso), che fornisce un modo standard per produrre registri di audit spesso richiesti per conformarsi alle certificazioni governative, finanziarie o ISO.
Auditing privilegi per MySQL, MariaDB e PostgreSQL
Il controllo dei privilegi verifica i privilegi e il controllo di accesso agli oggetti del database. Il controllo degli accessi garantisce che gli utenti che accedono al database siano identificati in modo positivo e possano accedere, aggiornare o eliminare i dati a cui hanno diritto. Quest'area è comunemente trascurata dall'ingegnere DevOps che rende l'eccessivo privilegio un errore comune durante la creazione e la concessione di un utente di database.
Esempi di privilegio eccessivo sono:
-
Gli host di accesso degli utenti sono consentiti da una gamma molto ampia, ad esempio concedendo host host [email protected]' %', invece di un indirizzo IP individuale.
-
Privilegi amministrativi assegnati a utenti di database non amministrativi, ad esempio, viene assegnato un utente di database per l'applicazione con privilegio SUPER o RELOAD.
-
Mancanza di controllo delle risorse contro qualsiasi tipo di utilizzo eccessivo come Numero massimo di connessioni utente, Numero massimo di query all'ora o Numero massimo Connessioni all'ora.
-
Consenti a utenti di database specifici di accedere anche ad altri schemi.
Per MySQL, MariaDB e PostgreSQL, puoi eseguire il controllo dei privilegi tramite lo Schema delle informazioni interrogando le tabelle relative a concessione, ruolo e privilegi. Per MongoDB, utilizza la query seguente (richiede l'azione viewUser per altri database):
mongodb> db.getUsers( { usersInfo: { forAllDBs: true } } )
ClusterControl fornisce un bel riassunto dei privilegi assegnati a un utente del database. Vai su Gestisci -> Schemi e utenti -> Utenti e otterrai un rapporto sui privilegi degli utenti, insieme alle opzioni avanzate come Richiede SSL, Numero massimo di connessioni all'ora e così via.
ClusterControl supporta il controllo dei privilegi per MySQL, MariaDB e PostgreSQL sotto lo stesso utente interfaccia.
Controllo degli oggetti dello schema
Gli oggetti schema sono strutture logiche create dagli utenti. Esempi di oggetti schema sono tabelle, indici, viste, routine, eventi, procedure, funzioni, trigger e altri. Fondamentalmente oggetti che contengono dati o possono consistere solo in una definizione. Comunemente, si controllano le autorizzazioni associate agli oggetti dello schema per rilevare impostazioni di sicurezza scadenti e comprendere la relazione e le dipendenze tra gli oggetti.
Per MySQL e MariaDB, ci sono information_schema e performance_schema che possiamo usare per controllare sostanzialmente gli oggetti dello schema. Performance_schema è un po' approfondito nella strumentazione come suggerisce il nome. Tuttavia, MySQL include anche uno schema sys dalla versione 5.7.7, che è una versione intuitiva di performance_schema. Tutti questi database sono direttamente accessibili e interrogabili dai clienti.
Plugin/estensioni di audit del database
Il modo più consigliato per eseguire il controllo delle istruzioni è utilizzare un plug-in o un'estensione di controllo, creata appositamente per la tecnologia di database in uso. MariaDB e Percona hanno la propria implementazione del plug-in Audit, leggermente diversa dal plug-in Audit di MySQL disponibile in MySQL Enterprise. I record di controllo includono informazioni sull'operazione controllata, sull'utente che esegue l'operazione e sulla data e l'ora dell'operazione. I record possono essere archiviati in una tabella del dizionario dei dati, denominata traccia di controllo del database, o in file del sistema operativo, chiamata traccia di controllo del sistema operativo.
Per PostgreSQL, c'è pgAudit, un'estensione PostgreSQL che fornisce una registrazione dettagliata delle sessioni e/o degli audit degli oggetti tramite la funzione di registrazione standard di PostgreSQL. È fondamentalmente una versione migliorata della funzione log_statement di PostgreSQL con la possibilità di cercare e cercare facilmente i dati acquisiti per l'audit seguendo il registro di audit standard.
MongoDB Enterprise (a pagamento) e Percona Server for MongoDB (gratuito) includono una funzionalità di auditing per le istanze mongod e mongos. Con il controllo abilitato, il server genererà messaggi di controllo che possono essere registrati in syslog, console o file (formato JSON o BSON). Nella maggior parte dei casi, è preferibile accedere al file in formato BSON, dove l'impatto sulle prestazioni è inferiore a JSON. Questo file contiene informazioni su diversi eventi utente, inclusi autenticazione, errori di autorizzazione e così via. Consulta la documentazione di Auditing per i dettagli.
Tracce di controllo del sistema operativo
È anche importante configurare gli audit trail del sistema operativo. Per Linux, le persone userebbero comunemente auditd. Auditd è il componente dello spazio utente del sistema di auditing Linux ed è responsabile della scrittura dei record di audit sul disco. La visualizzazione dei registri viene eseguita con le utilità aussearch o aureport. La configurazione delle regole di controllo viene eseguita con l'utilità auditctl o modificando direttamente i file delle regole.
I seguenti passaggi di installazione sono la nostra pratica comune quando si configura qualsiasi tipo di server per l'utilizzo in produzione:
$ yum -y install audit # apt install auditd python
$ mv /etc/audit/rules.d/audit.rules /etc/audit/rules.d/audit.rules.ori
$ cd /etc/audit/rules.d/
$ wget https://gist.githubusercontent.com/ashraf-s9s/fb1b674e15a5a5b41504faf76a08b4ae/raw/2764bf0e9bf25418bb86e33c13fb80356999d220/audit.rules
$ chmod 640 audit.rules
$ systemctl daemon-reload
$ systemctl start auditd
$ systemctl enable auditd
$ service auditd restart
Si noti che il riavvio di auditd del servizio dell'ultima riga è obbligatorio perché audit non funziona molto bene quando si caricano le regole con systemd. Tuttavia, systemd è ancora necessario per monitorare il servizio auditd. Durante l'avvio, le regole in /etc/audit/audit.rules vengono lette da auditctl. Il demone di audit stesso ha alcune opzioni di configurazione che l'amministratore potrebbe voler personalizzare. Si trovano nel file auditd.conf.
La riga seguente è un output preso da un registro di controllo configurato:
$ ausearch -m EXECVE | grep -i 'password' | head -1
type=EXECVE msg=audit(1615377099.934:11838148): argc=7 a0="mysql" a1="-NAB" a2="--user=appdb1" a3="--password=S3cr3tPassw0rdKP" a4="-h127.0.0.1" a5="-P3306" a6=2D6553484F5720474C4F42414C205641524941424C4553205748455245205641524941424C455F4E414D4520494E20282776657273696F6E272C202776657273696F6E5F636F6D6D656E74272C2027646174616469722729
Come puoi vedere da quanto sopra, è facile individuare una password in chiaro per MySQL ("--password=S3cr3tPassw0rdKP") usando l'utilità ausearch catturata da auditd. Questo tipo di rilevamento e controllo è fondamentale per proteggere la nostra infrastruttura di database, dove una password in chiaro è inaccettabile in un ambiente protetto.
Pensieri finali
Il registro o il trail di controllo è un aspetto vitale che viene comunemente trascurato dagli ingegneri DevOps durante la gestione di infrastrutture e sistemi, per non parlare del sistema di database che è un sistema molto critico per archiviare dati sensibili e riservati. Qualsiasi esposizione o violazione dei tuoi dati privati può essere estremamente dannosa per l'azienda e nessuno vorrebbe che ciò accadesse nell'attuale era della tecnologia dell'informazione.