Sicurezza e DBMS: cosa bisogna ricordare quando si scelgono gli strumenti di sicurezza

Sicurezza e DBMS: cosa bisogna ricordare quando si scelgono gli strumenti di sicurezza

Mi chiamo Denis Rozhkov, sono il capo dello sviluppo software presso la società Gazinformservice, nel team di prodotto jatoba. La legislazione e i regolamenti aziendali impongono determinati requisiti per la sicurezza della conservazione dei dati. Nessuno vuole che terzi abbiano accesso a informazioni riservate, quindi le seguenti questioni sono importanti per qualsiasi progetto: identificazione e autenticazione, gestione dell'accesso ai dati, garanzia dell'integrità delle informazioni nel sistema, registrazione degli eventi di sicurezza. Voglio quindi parlare di alcuni punti interessanti riguardanti la sicurezza dei DBMS.

L'articolo è stato preparato sulla base di un discorso tenuto a @DatabasesMeetup, organizzato Mail.ru soluzioni cloud. Se non vuoi leggere puoi guardare:


L’articolo avrà tre parti:

  • Come proteggere le connessioni.
  • Cos'è un audit delle azioni e come registrare ciò che accade sul lato del database e connettersi ad esso.
  • Come proteggere i dati nel database stesso e quali tecnologie sono disponibili per questo.

Sicurezza e DBMS: cosa bisogna ricordare quando si scelgono gli strumenti di sicurezza
Tre componenti della sicurezza DBMS: protezione della connessione, controllo delle attività e protezione dei dati

Protezione delle tue connessioni

È possibile connettersi al database direttamente o indirettamente tramite applicazioni web. Di norma, l'utente aziendale, cioè la persona che lavora con il DBMS, interagisce con esso indirettamente.

Prima di parlare di protezione delle connessioni è necessario rispondere a domande importanti che determinano come saranno strutturate le misure di sicurezza:

  • Un utente aziendale equivale a un utente DBMS?
  • se l'accesso ai dati DBMS viene fornito solo tramite un'API controllata dall'utente o se si accede direttamente alle tabelle;
  • se il DBMS è allocato in un segmento protetto separato, chi interagisce con esso e come;
  • se vengono utilizzati pool/proxy e livelli intermedi, che possono modificare le informazioni su come viene creata la connessione e chi utilizza il database.

Vediamo ora quali strumenti si possono utilizzare per rendere sicure le connessioni:

  1. Utilizzare soluzioni di classe firewall per database. Un ulteriore livello di protezione aumenterà, come minimo, la trasparenza di ciò che accade nel DBMS e, al massimo, sarai in grado di fornire un'ulteriore protezione dei dati.
  2. Utilizza i criteri relativi alle password. Il loro utilizzo dipende da come è costruita la tua architettura. In ogni caso, una sola password nel file di configurazione di un'applicazione web che si connette al DBMS non è sufficiente per la protezione. Esistono numerosi strumenti DBMS che consentono di controllare se l'utente e la password richiedono l'aggiornamento.

    Puoi leggere ulteriori informazioni sulle funzioni di valutazione degli utenti qui, puoi anche trovare informazioni sui valutatori delle vulnerabilità di MS SQL qui

  3. Arricchire il contesto della sessione con le informazioni necessarie. Se la sessione è opaca, non capisci chi sta lavorando nel DBMS all'interno della sua struttura, puoi, nell'ambito dell'operazione eseguita, aggiungere informazioni su chi sta facendo cosa e perché. Queste informazioni possono essere visualizzate nell'audit.
  4. Configura SSL se non disponi di una separazione di rete tra il DBMS e gli utenti finali; non è in una VLAN separata. In questi casi, è imperativo proteggere il canale tra il consumatore e il DBMS stesso. Gli strumenti di sicurezza sono disponibili anche in open source.

In che modo ciò influirà sulle prestazioni del DBMS?

Diamo un'occhiata all'esempio di PostgreSQL per vedere come SSL influisce sul carico della CPU, aumenta i tempi e diminuisce il TPS e se consumerà troppe risorse se lo abiliti.

Caricare PostgreSQL utilizzando pgbench è un semplice programma per eseguire test delle prestazioni. Esegue ripetutamente una singola sequenza di comandi, possibilmente in sessioni di database parallele, quindi calcola la velocità media delle transazioni.

Test 1 senza SSL e utilizzando SSL — la connessione viene stabilita per ciascuna transazione:

pgbench.exe --connect -c 10 -t 5000 "host=192.168.220.129 dbname=taskdb user=postgres sslmode=require 
sslrootcert=rootCA.crt sslcert=client.crt sslkey=client.key"

vs

pgbench.exe --connect -c 10 -t 5000 "host=192.168.220.129 dbname=taskdb user=postgres"

Test 2 senza SSL e utilizzando SSL — tutte le transazioni vengono eseguite in un'unica connessione:

pgbench.exe -c 10 -t 5000 "host=192.168.220.129 dbname=taskdb user=postgres sslmode=require
sslrootcert=rootCA.crt sslcert=client.crt sslkey=client.key"

vs

pgbench.exe -c 10 -t 5000 "host=192.168.220.129 dbname=taskdb user=postgres"

Altre impostazioni:

scaling factor: 1
query mode: simple
number of clients: 10
number of threads: 1
number of transactions per client: 5000
number of transactions actually processed: 50000/50000

Risultati dei test:

 
NON SSL
SSL

Per ogni transazione viene stabilita una connessione

media di latenza
ms 171.915
ms 187.695

tps inclusa la creazione di connessioni
58.168112
53.278062

tps escluse le connessioni instaurate
64.084546
58.725846

CPU
24%
28%

Tutte le transazioni vengono eseguite in un'unica connessione

media di latenza
ms 6.722
ms 6.342

tps inclusa la creazione di connessioni
1587.657278
1576.792883

tps escluse le connessioni instaurate
1588.380574
1577.694766

CPU
17%
21%

Con carichi leggeri, l'influenza di SSL è paragonabile all'errore di misurazione. Se la quantità di dati trasferiti è molto elevata, la situazione potrebbe essere diversa. Se stabiliamo una connessione per transazione (questo è raro, di solito la connessione è condivisa tra gli utenti), si ha un gran numero di connessioni/disconnessioni, l'impatto potrebbe essere un po' maggiore. Cioè, potrebbero esserci rischi di riduzione delle prestazioni, tuttavia, la differenza non è così grande da non utilizzare la protezione.

Tieni presente che c'è una forte differenza se confronti le modalità operative: stai lavorando all'interno della stessa sessione o in sessioni diverse. Questo è comprensibile: le risorse vengono spese per creare ciascuna connessione.

Abbiamo avuto un caso in cui abbiamo collegato Zabbix in modalità trust, ovvero md5 non è stato controllato, non era necessaria l'autenticazione. Quindi il cliente ha chiesto di abilitare la modalità di autenticazione MD5. Ciò ha messo un carico pesante sulla CPU e le prestazioni sono diminuite. Abbiamo iniziato a cercare modi per ottimizzare. Una delle possibili soluzioni al problema è implementare restrizioni di rete, creare VLAN separate per il DBMS, aggiungere impostazioni per chiarire chi si connette da dove e rimuovere l'autenticazione. È anche possibile ottimizzare le impostazioni di autenticazione per ridurre i costi quando si abilita l'autenticazione, ma in generale l'utilizzo di metodi diversi di autenticazione incide sulle prestazioni e richiede di tenere conto di questi fattori quando si progetta la potenza di calcolo dei server (hardware) per il DBMS.

Conclusione: in molte soluzioni anche piccole sfumature nell'autenticazione possono influenzare notevolmente il progetto ed è un male quando ciò diventa chiaro solo quando viene implementato in produzione.

Verifica dell'azione

L'audit può essere non solo DBMS. Un audit consiste nell'ottenere informazioni su ciò che sta accadendo nei diversi segmenti. Può trattarsi di un firewall del database o del sistema operativo su cui è costruito il DBMS.

Nei DBMS commerciali di livello aziendale tutto va bene con l'auditing, ma in open source non sempre. Ecco cosa ha PostgreSQL:

  • registro predefinito: registrazione integrata;
  • estensioni: pgaudit - se la registrazione predefinita non è sufficiente per te, puoi utilizzare impostazioni separate che risolvono alcuni problemi.

Aggiunta al resoconto nel video:

"La registrazione delle istruzioni di base può essere fornita da una funzione di registrazione standard con log_statement = all.

Ciò è accettabile per il monitoraggio e altri usi, ma non fornisce il livello di dettaglio tipicamente richiesto per l'auditing.

Non è sufficiente avere un elenco di tutte le operazioni eseguite sul database.

Dovrebbe anche essere possibile trovare dichiarazioni specifiche che siano di interesse per il revisore.

La registrazione standard mostra ciò che l'utente ha richiesto, mentre pgAudit si concentra sui dettagli di ciò che è accaduto quando il database ha eseguito la query.

Ad esempio, il revisore potrebbe voler verificare che una determinata tabella sia stata creata all'interno di una finestra di manutenzione documentata.

Questo può sembrare un compito semplice con auditing e grep di base, ma cosa succederebbe se ti venisse presentato qualcosa come questo esempio (intenzionalmente confuso):

FARE$$
INIZIO
ESEGUIRE 'CREATE TABLE import' || 'ant_table(id int)';
FINE$$;

La registrazione standard ti darà questo:

LOG: istruzione: DO $$
INIZIO
ESEGUIRE 'CREATE TABLE import' || 'ant_table(id int)';
FINE$$;

Sembra che trovare la tabella di interesse possa richiedere una certa conoscenza del codice nei casi in cui le tabelle vengono create dinamicamente.

Questo non è l'ideale, poiché sarebbe preferibile cercare semplicemente per nome della tabella.

È qui che pgAudit torna utile.

Per lo stesso input, produrrà questo output nel registro:

VERIFICA: SESSIONE,33,1,FUNZIONE,FARE,,,"FARE $$
INIZIO
ESEGUIRE 'CREATE TABLE import' || 'ant_table(id int)';
FINE$$;"
AUDIT: SESSION,33,2,DDL,CREATE TABLE,TABLE,public.important_table,CREATE TABLE important_table (id INT)

Non viene registrato solo il blocco DO, ma anche il testo completo di CREATE TABLE con il tipo di istruzione, il tipo di oggetto e il nome completo, semplificando la ricerca.

Quando si registrano istruzioni SELECT e DML, pgAudit può essere configurato per registrare una voce separata per ciascuna relazione a cui si fa riferimento nell'istruzione.

Non è necessaria alcuna analisi per trovare tutte le istruzioni che toccano una particolare tabella(*). "

In che modo ciò influirà sulle prestazioni del DBMS?

Eseguiamo i test con il controllo completo abilitato e vediamo cosa succede alle prestazioni di PostgreSQL. Abilitiamo la registrazione massima del database per tutti i parametri.

Non cambiamo quasi nulla nel file di configurazione, la cosa più importante è attivare la modalità debug5 per ottenere il massimo delle informazioni.

postgresql.conf

log_destinazione = 'stderr'
logging_collector = attivo
log_truncate_on_rotation = attivo
log_rotazione_età = 1d
dimensione_rotazione_log = 10 MB
log_min_messaggi = debug5
log_min_error_statement = debug5
log_min_duration_statement = 0
debug_print_parse = attivo
debug_print_rescript = attivato
debug_print_plan = attivo
debug_pretty_print = attivo
log_checkpoints = attivo
log_connections = attivo
log_disconnections = attivo
log_duration = attivo
log_nomehost = attivo
log_lock_waits = attivo
log_replication_commands = attivo
log_temp_file = 0
log_timezone = 'Europa/Mosca'

Su un DBMS PostgreSQL con parametri di 1 CPU, 2,8 GHz, 2 GB di RAM, 40 GB di HDD, conduciamo tre test di carico utilizzando i comandi:

$ pgbench -p 3389 -U postgres -i -s 150 benchmark
$ pgbench -p 3389 -U postgres -c 50 -j 2 -P 60 -T 600 benchmark
$ pgbench -p 3389 -U postgres -c 150 -j 2 -P 60 -T 600 benchmark

Risultati del test:

Nessuna registrazione
Con registrazione

Tempo totale di riempimento del database
43,74 sec
53,23 sec

RAM
24%
40%

CPU
72%
91%

Test 1 (50 connessioni)

Numero di transazioni in 10 minuti
74169
32445

Transazioni/sec
123
54

Latenza media
405 мс
925 мс

Test 2 (150 connessioni di cui 100 possibili)

Numero di transazioni in 10 minuti
81727
31429

Transazioni/sec
136
52

Latenza media
550 мс
1432 мс

A proposito di dimensioni

dimensione del database
2251 MB
2262 MB

Dimensioni del registro del database
0 MB
4587 MB

In conclusione: un audit completo non è molto buono. I dati dell'audit saranno grandi quanto i dati nel database stesso, o anche di più. La quantità di registrazione generata quando si lavora con un DBMS è un problema comune in produzione.

Diamo un'occhiata ad altri parametri:

  • La velocità non cambia molto: senza registrazione - 43,74 secondi, con registrazione - 53,23 secondi.
  • Le prestazioni della RAM e della CPU ne risentiranno, poiché sarà necessario generare un file di controllo. Ciò si nota anche nella produttività.

All'aumentare del numero di connessioni, naturalmente, le prestazioni peggioreranno leggermente.

Nelle aziende con audit è ancora più difficile:

  • ci sono molti dati;
  • il controllo è necessario non solo tramite syslog in SIEM, ma anche nei file: se succede qualcosa al syslog, deve esserci un file vicino al database in cui sono salvati i dati;
  • per l'auditing è necessario uno scaffale separato per non sprecare i dischi di I/O, poiché occupa molto spazio;
  • Succede che i dipendenti della sicurezza delle informazioni abbiano bisogno degli standard GOST ovunque, richiedono l'identificazione statale.

Limitare l'accesso ai dati

Diamo un'occhiata alle tecnologie utilizzate per proteggere i dati e accedervi nei DBMS commerciali e open source.

Cosa puoi usare in generale:

  1. Crittografia e offuscamento di procedure e funzioni (Wrapping), ovvero strumenti e utilità separati che rendono illeggibile il codice leggibile. È vero, allora non può essere né modificato né rifattorizzato. Questo approccio è talvolta richiesto almeno dal lato DBMS: la logica delle restrizioni di licenza o la logica di autorizzazione è crittografata proprio a livello di procedura e funzione.
  2. La limitazione della visibilità dei dati per righe (RLS) avviene quando utenti diversi vedono una tabella, ma una diversa composizione di righe al suo interno, ovvero qualcosa non può essere mostrato a qualcuno a livello di riga.
  3. La modifica dei dati visualizzati (mascheramento) avviene quando gli utenti in una colonna della tabella vedono i dati o solo gli asterischi, ovvero per alcuni utenti le informazioni verranno chiuse. La tecnologia determina a quale utente viene mostrato cosa in base al suo livello di accesso.
  4. Sicurezza DBA/Applicazioni Il controllo degli accessi DBA/DBA consiste, piuttosto, nel limitare l'accesso al DBMS stesso, ovvero i dipendenti della sicurezza delle informazioni possono essere separati dagli amministratori del database e dagli amministratori dell'applicazione. Esistono poche tecnologie di questo tipo nell'open source, ma ce ne sono molte nei DBMS commerciali. Sono necessari quando ci sono molti utenti con accesso ai server stessi.
  5. Limitazione dell'accesso ai file a livello di file system. È possibile concedere diritti e privilegi di accesso alle directory in modo che ogni amministratore abbia accesso solo ai dati necessari.
  6. Accesso obbligatorio e cancellazione della memoria: queste tecnologie vengono utilizzate raramente.
  7. La crittografia end-to-end direttamente dal DBMS è la crittografia lato client con gestione delle chiavi sul lato server.
  8. Crittografia dei dati. Ad esempio, la crittografia a colonne avviene quando si utilizza un meccanismo che crittografa una singola colonna del database.

In che modo ciò influisce sulle prestazioni del DBMS?

Diamo un'occhiata all'esempio della crittografia a colonne in PostgreSQL. C'è un modulo pgcrypto, che ti consente di memorizzare i campi selezionati in forma crittografata. Ciò è utile quando solo alcuni dati sono preziosi. Per leggere i campi crittografati, il client trasmette una chiave di decrittografia, il server decrittografa i dati e li restituisce al client. Senza la chiave, nessuno può fare nulla con i tuoi dati.

Proviamo con pgcrypto. Creiamo una tabella con dati crittografati e dati regolari. Di seguito sono riportati i comandi per la creazione di tabelle, nella prima riga c'è un comando utile: creare l'estensione stessa con la registrazione DBMS:

CREATE EXTENSION pgcrypto;
CREATE TABLE t1 (id integer, text1 text, text2 text);
CREATE TABLE t2 (id integer, text1 bytea, text2 bytea);
INSERT INTO t1 (id, text1, text2)
VALUES (generate_series(1,10000000), generate_series(1,10000000)::text, generate_series(1,10000000)::text);
INSERT INTO t2 (id, text1, text2) VALUES (
generate_series(1,10000000),
encrypt(cast(generate_series(1,10000000) AS text)::bytea, 'key'::bytea, 'bf'),
encrypt(cast(generate_series(1,10000000) AS text)::bytea, 'key'::bytea, 'bf'));

Successivamente, proviamo a creare un campione di dati da ciascuna tabella e osserviamo i tempi di esecuzione.

Selezione da una tabella senza funzione di crittografia:

psql -c "timing" -c "select * from t1 limit 1000;" "host=192.168.220.129 dbname=taskdb
user=postgres sslmode=disable" > 1.txt

Il cronometro è acceso.

  id | testo1 | testo2
——+——-+——-
1| 1| 1
2| 2| 2
3| 3| 3
...
997 | 997 | 997
998 | 998 | 998
999 | 999 | 999
1000 | 1000 | 1000
(1000 righe)

Tempo: 1,386 ms

Selezione da una tabella con funzione di crittografia:

psql -c "timing" -c "select id, decrypt(text1, 'key'::bytea, 'bf'),
decrypt(text2, 'key'::bytea, 'bf') from t2 limit 1000;"
"host=192.168.220.129 dbname=taskdb user=postgres sslmode=disable" > 2.txt

Il cronometro è acceso.

  id | decifrare | decifrare
——+—————+————
1| x31 | x31
2| x32 | x32
3| x33 | x33
...
999| x393939 | x393939
1000| x31303030 | x31303030
(1000 righe)

Tempo: 50,203 ms

Risultati dei test:

 
Senza crittografia
Pgcrypto (decifra)

Campiona 1000 righe
1,386 мс
50,203 мс

CPU
15%
35%

RAM
 
+ 5%

La crittografia ha un grande impatto sulle prestazioni. Si può notare che i tempi sono aumentati, poiché le operazioni di decrittografia dei dati crittografati (e la decrittografia è solitamente ancora racchiusa nella logica) richiedono risorse significative. Cioè, l'idea di crittografare tutte le colonne contenenti alcuni dati comporta una diminuzione delle prestazioni.

Tuttavia, la crittografia non è la soluzione miracolosa che risolve tutti i problemi. I dati decrittografati e la chiave di decrittografia durante il processo di decrittografia e trasmissione dei dati si trovano sul server. Pertanto, le chiavi possono essere intercettate da qualcuno che ha pieno accesso al server del database, come un amministratore di sistema.

Quando esiste una chiave per l'intera colonna per tutti gli utenti (anche se non per tutti, ma per i client con un set limitato), ciò non è sempre corretto e corretto. Questo è il motivo per cui hanno iniziato a eseguire la crittografia end-to-end, nel DBMS hanno iniziato a considerare le opzioni per crittografare i dati sul lato client e server e sono apparsi gli stessi archivi di key-vault: prodotti separati che forniscono la gestione delle chiavi sul DBMS lato.

Sicurezza e DBMS: cosa bisogna ricordare quando si scelgono gli strumenti di sicurezza
Un esempio di tale crittografia in MongoDB

Funzionalità di sicurezza nei DBMS commerciali e open source

funzioni
tipo
Politica password

Proteggere il codice sorgente di procedure e funzioni
RLS
crittografia

Oracle
commerciale
+
+
+
+
+

Msql
commerciale
+
+
+
+
+

jatoba
commerciale
+
+
+
+
estensioni

PostgreSQL
Gratis
estensioni
estensioni
-
+
estensioni

MongoDb
Gratis
-
+
-
-
Disponibile solo in MongoDB Enterprise

La tabella è lungi dall'essere completa, ma la situazione è questa: nei prodotti commerciali i problemi di sicurezza sono stati risolti da molto tempo, nell'open source, di norma, vengono utilizzati alcuni tipi di componenti aggiuntivi per la sicurezza, mancano molte funzioni , a volte devi aggiungere qualcosa. Ad esempio, le politiche sulle password: PostgreSQL ha molte estensioni diverse (1, 2, 3, 4, 5), che implementano politiche relative alle password, ma, a mio avviso, nessuna di esse copre tutte le esigenze del segmento aziendale nazionale.

Cosa fare se non hai ciò di cui hai bisogno da nessuna parte? Ad esempio, desideri utilizzare un DBMS specifico che non dispone delle funzioni richieste dal cliente.

Quindi puoi utilizzare soluzioni di terze parti che funzionano con diversi DBMS, ad esempio Crypto DB o Garda DB. Se parliamo di soluzioni del segmento domestico, allora conoscono i GOST meglio che nell'open source.

La seconda opzione è scrivere tu stesso ciò di cui hai bisogno, implementare l'accesso ai dati e la crittografia nell'applicazione a livello di procedura. È vero, con GOST sarà più difficile. Ma in generale, puoi nascondere i dati secondo necessità, inserirli in un DBMS, quindi recuperarli e decrittografarli secondo necessità, proprio a livello di applicazione. Allo stesso tempo, pensa immediatamente a come proteggerai questi algoritmi nell'applicazione. A nostro avviso, ciò dovrebbe essere fatto a livello di DBMS, perché funzionerà più velocemente.

Questo rapporto è stato presentato per la prima volta a @Incontro sui database di Mail.ru Soluzioni cloud. Aspetto video altri spettacoli e iscriviti agli annunci degli eventi su Telegram Intorno a Kubernetes nel gruppo Mail.ru.

Cos'altro leggere sull'argomento:

  1. Più che Ceph: MCS cloud block storage.
  2. Come scegliere un database per un progetto in modo da non dover scegliere di nuovo.

Fonte: habr.com

Aggiungi un commento