Sigurnost i DBMS: što trebate zapamtiti pri odabiru sigurnosnih alata

Sigurnost i DBMS: što trebate zapamtiti pri odabiru sigurnosnih alata

Moje ime je Denis Rozhkov, ja sam voditelj razvoja softvera u tvrtki Gazinformservice, u proizvodnom timu jatoba. Zakoni i korporativni propisi nameću određene zahtjeve za sigurnost pohrane podataka. Nitko ne želi da treće strane dobiju pristup povjerljivim informacijama, stoga su sljedeća pitanja važna za svaki projekt: identifikacija i autentifikacija, upravljanje pristupom podacima, osiguranje integriteta informacija u sustavu, bilježenje sigurnosnih događaja. Stoga želim govoriti o nekim zanimljivim točkama u vezi sa sigurnošću DBMS-a.

Članak je pripremljen na temelju govora na @DatabasesMeetup, organiziran Mail.ru Cloud rješenja. Ako ne želite čitati, možete pogledati:


Članak će imati tri dijela:

  • Kako osigurati veze.
  • Što je revizija radnji i kako bilježiti što se događa na strani baze podataka i povezivanja s njom.
  • Kako zaštititi podatke u samoj bazi podataka i koje tehnologije su za to dostupne.

Sigurnost i DBMS: što trebate zapamtiti pri odabiru sigurnosnih alata
Tri komponente sigurnosti DBMS-a: zaštita veze, revizija aktivnosti i zaštita podataka

Osiguravanje vaših veza

Na bazu podataka možete se povezati izravno ili neizravno putem web aplikacija. U pravilu, poslovni korisnik, odnosno osoba koja radi sa DBMS-om, s njim komunicira neizravno.

Prije nego što počnete govoriti o zaštiti veza, trebate odgovoriti na važna pitanja koja određuju kako će sigurnosne mjere biti strukturirane:

  • Je li jedan poslovni korisnik jednak jednom korisniku DBMS-a?
  • je li pristup DBMS podacima omogućen samo putem API-ja koji vi kontrolirate ili se tablicama pristupa izravno;
  • da li je DBMS dodijeljen posebnom zaštićenom segmentu, tko s njim komunicira i kako;
  • koriste li se udruživanje/proxy i međuslojevi, što može promijeniti informacije o tome kako je veza izgrađena i tko koristi bazu podataka.

Sada da vidimo koji se alati mogu koristiti za osiguranje veza:

  1. Koristite rješenja klasa vatrozida baze podataka. Dodatni sloj zaštite minimalno će povećati transparentnost onoga što se događa u DBMS-u, a maksimalno ćete moći osigurati dodatnu zaštitu podataka.
  2. Koristite pravila za lozinke. Njihova upotreba ovisi o tome kako je izgrađena vaša arhitektura. U svakom slučaju, jedna lozinka u konfiguracijskoj datoteci web aplikacije koja se spaja na DBMS nije dovoljna za zaštitu. Postoji niz DBMS alata koji vam omogućuju da kontrolirate da korisnik i lozinka zahtijevaju ažuriranje.

    Možete pročitati više o funkcijama ocjenjivanja korisnika здесь, također možete saznati o MS SQL Vulnerability Assessmen ovdje

  3. Obogatite kontekst sesije potrebnim informacijama. Ako je sesija neprozirna, ne razumijete tko radi u DBMS-u unutar njenog okvira, možete u okviru operacije koja se izvodi dodati informacije o tome tko radi što i zašto. Ovaj podatak se može vidjeti u reviziji.
  4. Konfigurirajte SSL ako nemate mrežno odvajanje između DBMS-a i krajnjih korisnika; nije u zasebnom VLAN-u. U takvim slučajevima imperativ je zaštititi kanal između potrošača i samog DBMS-a. Sigurnosni alati također su dostupni u otvorenom kodu.

Kako će to utjecati na performanse DBMS-a?

Pogledajmo primjer PostgreSQL-a da vidimo kako SSL utječe na opterećenje CPU-a, povećava tajminge i smanjuje TPS te hoće li trošiti previše resursa ako ga omogućite.

Učitavanje PostgreSQL-a pomoću pgbencha je jednostavan program za izvođenje testova performansi. Izvršava jedan niz naredbi više puta, moguće u paralelnim sesijama baze podataka, a zatim izračunava prosječnu stopu transakcije.

Test 1 bez SSL-a i korištenjem SSL-a — veza se uspostavlja za svaku transakciju:

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 bez SSL-a i korištenjem SSL-a — sve se transakcije izvode u jednoj vezi:

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"

Ostale postavke:

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

Rezultati ispitivanja:

 
NEMA SSL-a
SSL

Veza se uspostavlja za svaku transakciju

prosječna latencija
171.915 ms
187.695 ms

tps uključujući uspostavljanje veza
58.168112
53.278062

tps isključujući uspostavljanje veza
64.084546
58.725846

CPU
24%
28%

Sve transakcije se obavljaju u jednoj vezi

prosječna latencija
6.722 ms
6.342 ms

tps uključujući uspostavljanje veza
1587.657278
1576.792883

tps isključujući uspostavljanje veza
1588.380574
1577.694766

CPU
17%
21%

Pri malim opterećenjima utjecaj SSL-a je usporediv s greškom mjerenja. Ako je količina prenesenih podataka vrlo velika, situacija može biti drugačija. Ako uspostavimo jednu vezu po transakciji (ovo je rijetkost, obično se veza dijeli između korisnika), imate velik broj veza/prekida veze, utjecaj može biti malo veći. To jest, mogu postojati rizici od smanjene učinkovitosti, međutim, razlika nije toliko velika da se ne koristi zaštita.

Imajte na umu da postoji velika razlika ako usporedite načine rada: radite unutar iste sesije ili u različitim. To je razumljivo: resursi se troše na stvaranje svake veze.

Imali smo slučaj kada smo povezali Zabbix u modu povjerenja, to jest, md5 nije bio provjeren, nije bilo potrebe za autentifikacijom. Zatim je kupac zatražio da omogući način provjere autentičnosti md5. To je jako opteretilo CPU i performanse su pale. Počeli smo tražiti načine za optimizaciju. Jedno od mogućih rješenja problema je implementacija mrežnih ograničenja, stvaranje zasebnih VLAN-ova za DBMS, dodavanje postavki da bi bilo jasno tko se odakle povezuje i uklanjanje autentifikacije. Također možete optimizirati postavke autentifikacije kako biste smanjili troškove prilikom omogućavanja autentifikacije, ali općenito, korištenje različitih metoda provjere autentičnosti utječe na izvedbu i zahtijeva uzimanje u obzir ovih čimbenika pri projektiranju računalne snage poslužitelja (hardvera) za DBMS.

Zaključak: u brojnim rješenjima čak i male nijanse u autentifikaciji mogu uvelike utjecati na projekt i loše je kada to postane jasno tek kada se implementira u produkciju.

Akcijska revizija

Revizija može biti ne samo DBMS. Revizija je prikupljanje informacija o tome što se događa u različitim segmentima. To može biti ili vatrozid baze podataka ili operativni sustav na kojem je izgrađen DBMS.

U komercijalnim DBMS-ovima razine poduzeća sve je u redu s revizijom, ali u otvorenom kodu - ne uvijek. Evo što PostgreSQL ima:

  • zadani zapisnik - ugrađeno bilježenje;
  • proširenja: pgaudit - ako vam zadano bilježenje nije dovoljno, možete koristiti zasebne postavke koje rješavaju neke probleme.

Dodatak izvješću u videu:

"Osnovno bilježenje naredbi može se osigurati pomoću standardne značajke bilježenja s log_statement = all.

Ovo je prihvatljivo za praćenje i druge upotrebe, ali ne pruža razinu detalja koja je obično potrebna za reviziju.

Nije dovoljno imati popis svih operacija izvršenih na bazi podataka.

Također bi trebalo biti moguće pronaći specifične izjave koje su od interesa za revizora.

Standardno bilježenje pokazuje što je korisnik tražio, dok se pgAudit fokusira na detalje onoga što se dogodilo kada je baza podataka izvršila upit.

Na primjer, revizor može htjeti provjeriti je li određena tablica stvorena unutar dokumentiranog razdoblja održavanja.

Ovo se može činiti kao jednostavan zadatak s osnovnom revizijom i grep-om, ali što ako vam se prikaže nešto poput ovog (namjerno zbunjujućeg) primjera:

DO$$
POČETI
IZVRŠITE 'CREATE TABLE import' || 'ant_table(id int)';
END$$;

Standardno bilježenje će vam dati ovo:

LOG: izjava: DO $$
POČETI
IZVRŠITE 'CREATE TABLE import' || 'ant_table(id int)';
END$$;

Čini se da pronalaženje tablice od interesa može zahtijevati određeno znanje koda u slučajevima kada se tablice stvaraju dinamički.

Ovo nije idealno, jer bi bilo poželjno jednostavno pretraživati ​​prema nazivu tablice.

Ovdje pgAudit dobro dolazi.

Za isti ulaz, proizvest će ovaj izlaz u dnevniku:

AUDIT: SESSION,33,1,FUNCTION,DO,,,"DO $$
POČETI
IZVRŠITE 'CREATE TABLE import' || 'ant_table(id int)';
END$$;"
AUDIT: SESSION,33,2,DDL,CREATE TABLE,TABLE,public.important_table,CREATE TABLE important_table (id INT)

Zapisuje se ne samo DO blok, već i cijeli tekst CREATE TABLE s vrstom naredbe, vrstom objekta i punim imenom, što olakšava pretraživanje.

Prilikom bilježenja SELECT i DML izjava, pgAudit se može konfigurirati da bilježi zaseban unos za svaki odnos naveden u izjavi.

Nije potrebno raščlanjivanje da bi se pronašli svi iskazi koji dodiruju određenu tablicu(*) ».

Kako će to utjecati na performanse DBMS-a?

Pokrenimo testove s omogućenom potpunom revizijom i vidimo što će se dogoditi s performansama PostgreSQL-a. Omogućimo maksimalno bilježenje baze podataka za sve parametre.

Ne mijenjamo gotovo ništa u konfiguracijskoj datoteci, najvažnije je uključiti debug5 mod kako bismo dobili maksimum informacija.

postgresql.conf

log_destination = 'stderr'
logging_collector = uključeno
log_truncate_on_rotation = uključeno
log_rotation_age = 1d
log_rotation_size = 10MB
log_min_messages = ispravljanje pogrešaka5
log_min_error_statement = ispravljanje pogrešaka5
log_min_duration_statement = 0
debug_print_parse = uključeno
debug_print_rewritten = uključeno
debug_print_plan = uključeno
debug_pretty_print = uključeno
log_kontrolne točke = uključeno
log_connections = uključeno
log_disconnections = uključeno
trajanje_zapisa = uključeno
log_hostname = uključeno
log_lock_wait = uključeno
log_replication_commands = uključeno
log_temp_files = 0
log_timezone = 'Europa/Moskva'

Na PostgreSQL DBMS-u s parametrima 1 CPU, 2,8 GHz, 2 GB RAM-a, 40 GB HDD, provodimo tri testa opterećenja pomoću naredbi:

$ 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

Rezultati testa:

Nema sječe
Sa sječom

Ukupno vrijeme punjenja baze podataka
43,74 sek
53,23 sek

RAM
24%
40%

CPU
72%
91%

Test 1 (50 veza)

Broj transakcija u 10 minuta
74169
32445

Transakcije/sek
123
54

Prosječna latencija
405 ms
925 ms

Test 2 (150 veza sa 100 mogućih)

Broj transakcija u 10 minuta
81727
31429

Transakcije/sek
136
52

Prosječna latencija
550 ms
1432 ms

O veličinama

DB veličina
2251 MB
2262 MB

Veličina dnevnika baze podataka
0 MB
4587 MB

Zaključak: potpuna revizija nije baš dobra. Podaci iz revizije bit će jednako veliki kao podaci u samoj bazi podataka, ili čak i više. Količina zapisivanja koja se generira pri radu s DBMS-om čest je problem u proizvodnji.

Pogledajmo ostale parametre:

  • Brzina se ne mijenja mnogo: bez zapisivanja - 43,74 sekunde, sa zapisivanjem - 53,23 sekunde.
  • Izvedbe RAM-a i CPU-a će biti oštećene jer morate generirati revizijsku datoteku. To je također vidljivo u produktivnosti.

Kako se broj veza povećava, naravno, performanse će se malo pogoršati.

U korporacijama s revizijom još je teže:

  • ima puno podataka;
  • revizija nije potrebna samo kroz syslog u SIEM-u, već iu datotekama: ako se nešto dogodi syslogu, mora postojati datoteka blizu baze podataka u kojoj su podaci spremljeni;
  • potrebna je posebna polica za reviziju kako se ne bi trošili I/O diskovi, jer zauzima puno prostora;
  • Događa se da zaposlenici informacijske sigurnosti posvuda trebaju GOST standarde, zahtijevaju državnu identifikaciju.

Ograničavanje pristupa podacima

Pogledajmo tehnologije koje se koriste za zaštitu podataka i pristup njima u komercijalnim DBMS-ovima i otvorenom kodu.

Što općenito možete koristiti:

  1. Enkripcija i maskiranje procedura i funkcija (Wrapping) - to jest, zasebni alati i pomoćni programi koji čitljiv kod čine nečitljivim. Istina, tada se ne može niti mijenjati niti refaktorirati natrag. Ovaj pristup je ponekad potreban barem na strani DBMS-a - logika ograničenja licence ili logika autorizacije je šifrirana upravo na razini procedure i funkcije.
  2. Ograničenje vidljivosti podataka po redovima (RLS) je kada različiti korisnici vide jednu tablicu, ali različit sastav redaka u njoj, odnosno da se nešto ne može pokazati nekome na razini reda.
  3. Uređivanje prikazanih podataka (Maskiranje) je kada korisnici u jednom stupcu tablice vide ili podatke ili samo zvjezdice, odnosno za neke korisnike informacija će biti zatvorena. Tehnologija određuje kojem se korisniku što prikazuje na temelju njihove razine pristupa.
  4. Sigurnost DBA/Application DBA/DBA kontrola pristupa radi se zapravo o ograničavanju pristupa samom DBMS-u, odnosno zaposlenici informacijske sigurnosti mogu se odvojiti od administratora baza podataka i administratora aplikacija. Malo je takvih tehnologija u otvorenom kodu, ali ima ih dosta u komercijalnim DBMS-ovima. Oni su potrebni kada postoji mnogo korisnika s pristupom samim poslužiteljima.
  5. Ograničavanje pristupa datotekama na razini datotečnog sustava. Možete dodijeliti prava i povlastice pristupa imenicima tako da svaki administrator ima pristup samo potrebnim podacima.
  6. Obavezan pristup i brisanje memorije - ove se tehnologije rijetko koriste.
  7. End-to-end enkripcija izravno iz DBMS-a je enkripcija na strani klijenta s upravljanjem ključem na strani poslužitelja.
  8. Šifriranje podataka. Na primjer, šifriranje stupaca je kada koristite mehanizam koji šifrira jedan stupac baze podataka.

Kako to utječe na performanse DBMS-a?

Pogledajmo primjer stupčaste enkripcije u PostgreSQL-u. Postoji modul pgcrypto koji vam omogućuje pohranu odabranih polja u šifriranom obliku. Ovo je korisno kada su samo neki podaci vrijedni. Kako bi pročitao šifrirana polja, klijent šalje ključ za dešifriranje, poslužitelj dekriptira podatke i vraća ih klijentu. Bez ključa nitko ne može učiniti ništa s vašim podacima.

Testirajmo s pgcrypto. Kreirajmo tablicu s šifriranim podacima i običnim podacima. Ispod su naredbe za kreiranje tablica, u prvom redu nalazi se korisna naredba - kreiranje samog proširenja s registracijom DBMS-a:

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'));

Zatim, pokušajmo napraviti uzorak podataka iz svake tablice i pogledajmo vremena izvršenja.

Odabir iz tablice bez funkcije šifriranja:

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

Štoperica je uključena.

  id | tekst1 | tekst2
——+——-+——-
1 | 1 | 1
2 | 2 | 2
3 | 3 | 3
...
997 | 997 | 997
998 | 998 | 998
999 | 999 | 999
1000 | 1000 | 1000
(1000 redaka)

Vrijeme: 1,386 ms

Odabir iz tablice s funkcijom šifriranja:

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

Štoperica je uključena.

  id | dešifrirati | dešifrirati
——+—————+————
1 | x31 | x31
2 | x32 | x32
3 | x33 | x33
...
999 | x393939 | x393939
1000 | x31303030 | x31303030
(1000 redaka)

Vrijeme: 50,203 ms

Rezultati ispitivanja:

 
Bez enkripcije
Pgcrypto (dekriptiranje)

Uzorak 1000 redaka
1,386 ms
50,203 ms

CPU
15%
35%

RAM
 
+ 5%

Enkripcija ima velik utjecaj na performanse. Može se vidjeti da se tajming povećao, budući da operacije dešifriranja šifriranih podataka (a dešifriranje je obično još uvijek umotano u vašu logiku) zahtijevaju značajne resurse. To jest, ideja o šifriranju svih stupaca koji sadrže neke podatke prepuna je smanjenja performansi.

Međutim, enkripcija nije srebrni metak koji rješava sve probleme. Dekriptirani podaci i ključ za dešifriranje tijekom procesa dekriptiranja i prijenosa podataka nalaze se na poslužitelju. Stoga ključeve može presresti netko tko ima puni pristup poslužitelju baze podataka, poput administratora sustava.

Kada postoji jedan ključ za cijeli stupac za sve korisnike (čak i ako ne za sve, već za klijente ograničenog skupa), to nije uvijek dobro i ispravno. Zbog toga su počeli raditi end-to-end enkripciju, u DBMS-u su počeli razmatrati mogućnosti šifriranja podataka na strani klijenta i poslužitelja, a pojavili su se i ti isti key-vault stores - zasebni proizvodi koji omogućuju upravljanje ključevima na DBMS-u. strana.

Sigurnost i DBMS: što trebate zapamtiti pri odabiru sigurnosnih alata
Primjer takve enkripcije u MongoDB-u

Sigurnosne značajke u komercijalnim i otvorenim DBMS-ovima

Funkcije
Vrsta
Politika zaporke
Revizija
Zaštita izvornog koda procedura i funkcija
RLS
Šifriranje

Proročanstvo
komercijalni
+
+
+
+
+

MsSql
komercijalni
+
+
+
+
+

jatoba
komercijalni
+
+
+
+
ekstenzije

PostgreSQL
Besplatno
ekstenzije
ekstenzije
-
+
ekstenzije

MongoDb
Besplatno
-
+
-
-
Dostupno samo u MongoDB Enterprise

Tablica je daleko od potpune, ali situacija je sljedeća: u komercijalnim proizvodima sigurnosni problemi već su dugo riješeni, u otvorenom kodu se u pravilu koriste neke vrste dodataka za sigurnost, mnoge funkcije nedostaju , ponekad morate nešto dodati. Na primjer, pravila o lozinkama - PostgreSQL ima mnogo različitih proširenja (1, 2, 3, 4, 5), koji implementiraju password policy, ali, po mom mišljenju, niti jedan ne pokriva sve potrebe domaćeg korporativnog segmenta.

Što učiniti ako nigdje nemate ono što vam treba? Na primjer, želite koristiti određeni DBMS koji nema funkcije koje klijent zahtijeva.

Zatim možete koristiti rješenja trećih strana koja rade s različitim DBMS-ovima, na primjer, Crypto DB ili Garda DB. Ako govorimo o rješenjima iz domaćeg segmenta, onda o GOST-ovima znaju bolje nego u otvorenom kodu.

Druga opcija je da sami napišete što vam treba, implementirate pristup podacima i enkripciju u aplikaciji na razini procedure. Istina, bit će teže s GOST-om. Ali općenito, možete sakriti podatke prema potrebi, staviti ih u DBMS, zatim ih dohvatiti i dešifrirati prema potrebi, točno na razini aplikacije. Istodobno, odmah razmislite o tome kako ćete zaštititi te algoritme aplikacije. Po našem mišljenju, to bi trebalo biti učinjeno na razini DBMS-a, jer će raditi brže.

Ovo je izvješće prvi put predstavljeno na @Databases Meetup od Mail.ru Cloud Solutions. Izgled video ostale izvedbe i pretplatite se na najave događaja na Telegramu Oko Kubernetesa u Mail.ru grupi.

Što još pročitati na temu:

  1. Više od Cepha: MCS blok pohrana u oblaku.
  2. Kako odabrati bazu podataka za projekt da ne morate ponovno birati.

Izvor: www.habr.com

Dodajte komentar