Sikkerhed og DBMS: hvad du skal huske, når du vælger sikkerhedsværktøjer

Sikkerhed og DBMS: hvad du skal huske, når du vælger sikkerhedsværktøjer

Mit navn er Denis Rozhkov, jeg er leder af softwareudvikling hos Gazinformservice-virksomheden, i produktteamet Jatoba. Lovgivning og virksomhedsbestemmelser stiller visse krav til sikkerheden ved datalagring. Ingen ønsker, at tredjeparter skal få adgang til fortrolig information, så følgende spørgsmål er vigtige for ethvert projekt: identifikation og autentificering, håndtering af adgang til data, sikring af integriteten af ​​informationer i systemet, logning af sikkerhedshændelser. Derfor vil jeg fortælle om nogle interessante punkter vedrørende DBMS-sikkerhed.

Artiklen er udarbejdet på baggrund af en tale kl @DatabaserMeetup, organiseret Mail.ru Cloud-løsninger. Hvis du ikke vil læse, kan du se:


Artiklen vil have tre dele:

  • Sådan sikrer du forbindelser.
  • Hvad er en revision af handlinger, og hvordan man registrerer, hvad der sker på databasesiden og forbinder til den.
  • Hvordan beskytter man data i selve databasen og hvilke teknologier er tilgængelige til dette.

Sikkerhed og DBMS: hvad du skal huske, når du vælger sikkerhedsværktøjer
Tre komponenter af DBMS-sikkerhed: forbindelsesbeskyttelse, aktivitetsrevision og databeskyttelse

Sikring af dine forbindelser

Du kan oprette forbindelse til databasen enten direkte eller indirekte via webapplikationer. Som regel interagerer erhvervsbrugeren, det vil sige den person, der arbejder med DBMS, indirekte med det.

Før du taler om at beskytte forbindelser, skal du besvare vigtige spørgsmål, der bestemmer, hvordan sikkerhedsforanstaltninger vil blive struktureret:

  • Er én erhvervsbruger svarende til én DBMS-bruger?
  • om adgang til DBMS-data kun gives gennem en API, som du kontrollerer, eller om tabeller tilgås direkte;
  • om DBMS er allokeret til et separat beskyttet segment, hvem der interagerer med det og hvordan;
  • om der anvendes pooling/proxy og mellemlag, som kan ændre information om hvordan forbindelsen er opbygget og hvem der bruger databasen.

Lad os nu se, hvilke værktøjer der kan bruges til at sikre forbindelser:

  1. Brug database firewall klasse løsninger. Et ekstra beskyttelseslag vil som minimum øge gennemsigtigheden af, hvad der sker i DBMS, og maksimalt vil du kunne yde yderligere databeskyttelse.
  2. Brug adgangskodepolitikker. Deres brug afhænger af, hvordan din arkitektur er bygget. Under alle omstændigheder er én adgangskode i konfigurationsfilen for en webapplikation, der opretter forbindelse til DBMS, ikke nok til beskyttelse. Der er en række DBMS-værktøjer, som giver dig mulighed for at kontrollere, at brugeren og adgangskoden skal opdateres.

    Du kan læse mere om brugervurderingsfunktioner her, kan du også finde ud af om MS SQL Vulnerability Assessmen her

  3. Berig sessionens kontekst med de nødvendige oplysninger. Hvis sessionen er uigennemsigtig, forstår du ikke hvem der arbejder i DBMS'et inden for dets rammer, du kan inden for rammerne af den operation der udføres tilføje information om hvem der gør hvad og hvorfor. Disse oplysninger kan ses i revisionen.
  4. Konfigurer SSL, hvis du ikke har en netværksadskillelse mellem DBMS og slutbrugere; det er ikke i et separat VLAN. I sådanne tilfælde er det bydende nødvendigt at beskytte kanalen mellem forbrugeren og selve DBMS. Sikkerhedsværktøjer er også tilgængelige i open source.

Hvordan vil dette påvirke ydeevnen af ​​DBMS?

Lad os se på eksemplet med PostgreSQL for at se, hvordan SSL påvirker CPU-belastningen, øger timings og mindsker TPS, og om det vil forbruge for mange ressourcer, hvis du aktiverer det.

Indlæsning af PostgreSQL ved hjælp af pgbench er et simpelt program til at køre præstationstest. Den udfører en enkelt sekvens af kommandoer gentagne gange, muligvis i parallelle databasesessioner, og beregner derefter den gennemsnitlige transaktionshastighed.

Test 1 uden SSL og ved hjælp af SSL — forbindelsen etableres for hver transaktion:

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 uden SSL og ved hjælp af SSL — alle transaktioner udføres i én forbindelse:

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"

Andre indstillinger:

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

Testresultater:

 
INGEN SSL
SSL

Der etableres en forbindelse for hver transaktion

ventetid gennemsnit
171.915 ms
187.695 ms

tps inklusive oprettelse af forbindelser
58.168112
53.278062

tps eksklusive oprettelse af forbindelser
64.084546
58.725846

CPU
24 %
28 %

Alle transaktioner udføres i én forbindelse

ventetid gennemsnit
6.722 ms
6.342 ms

tps inklusive oprettelse af forbindelser
1587.657278
1576.792883

tps eksklusive oprettelse af forbindelser
1588.380574
1577.694766

CPU
17 %
21 %

Ved lette belastninger er indflydelsen af ​​SSL sammenlignelig med målefejlen. Hvis mængden af ​​overførte data er meget stor, kan situationen være anderledes. Hvis vi etablerer én forbindelse pr. transaktion (dette er sjældent, normalt er forbindelsen delt mellem brugere), har du et stort antal forbindelser/afbrydelser, påvirkningen kan være lidt større. Det vil sige, at der kan være risiko for nedsat ydeevne, dog er forskellen ikke så stor, at man ikke bruger beskyttelse.

Bemærk venligst, at der er en stærk forskel, hvis du sammenligner driftstilstandene: du arbejder inden for samme session eller i forskellige. Dette er forståeligt: ​​Der bruges ressourcer på at skabe hver forbindelse.

Vi havde en sag, da vi tilsluttede Zabbix i tillidstilstand, det vil sige, at md5 ikke blev kontrolleret, der var ikke behov for godkendelse. Derefter bad kunden om at aktivere md5-godkendelsestilstand. Dette satte en stor belastning på CPU'en, og ydeevnen faldt. Vi begyndte at lede efter måder at optimere på. En af de mulige løsninger på problemet er at implementere netværksrestriktioner, lave separate VLAN'er til DBMS'et, tilføje indstillinger for at gøre det klart, hvem der forbinder hvorfra og fjerne godkendelse. Du kan også optimere godkendelsesindstillinger for at reducere omkostningerne ved aktivering af godkendelse, men generelt påvirker brugen af ​​forskellige autentificeringsmetoder ydeevnen og kræver, at der tages højde for disse faktorer, når man designer servernes (hardware) computerkraft til DBMS.

Konklusion: I en række løsninger kan selv små nuancer i autentificering i høj grad påvirke projektet, og det er dårligt, når dette først bliver tydeligt, når det implementeres i produktionen.

Handlingsrevision

Revision kan ikke kun være DBMS. En revision handler om at indhente information om, hvad der sker i forskellige segmenter. Dette kan enten være en database firewall eller det operativsystem, som DBMS er bygget på.

I kommercielle Enterprise-niveau DBMS'er er alt fint med revision, men i open source - ikke altid. Her er hvad PostgreSQL har:

  • standard log - indbygget logning;
  • udvidelser: paudit - hvis standardlogning ikke er nok for dig, kan du bruge separate indstillinger, der løser nogle problemer.

Tilføjelse til rapporten i videoen:

"Grundlæggende erklæringslogning kan leveres af en standardlogningsfacilitet med log_statement = all.

Dette er acceptabelt til overvågning og andre formål, men giver ikke det detaljeringsniveau, der typisk kræves til revision.

Det er ikke nok at have en liste over alle de operationer, der udføres på databasen.

Det bør også være muligt at finde konkrete erklæringer, som er af interesse for revisor.

Standardlogning viser, hvad brugeren anmodede om, mens pgAudit fokuserer på detaljerne om, hvad der skete, da databasen udførte forespørgslen.

For eksempel kan revisoren gerne bekræfte, at en bestemt tabel blev oprettet inden for et dokumenteret vedligeholdelsesvindue.

Dette kan virke som en simpel opgave med grundlæggende revision og grep, men hvad nu hvis du blev præsenteret for noget som dette (med vilje forvirrende) eksempel:

GØR $$
BEGIN
UDFØR 'CREATE TABLE import' || 'ant_table(id int)';
END$$;

Standard logning vil give dig dette:

LOG: erklæring: GØR $$
BEGIN
UDFØR 'CREATE TABLE import' || 'ant_table(id int)';
END$$;

Det ser ud til, at det kan kræve noget kodekendskab at finde den interessante tabel i tilfælde, hvor tabeller oprettes dynamisk.

Dette er ikke ideelt, da det ville være at foretrække blot at søge efter tabelnavn.

Det er her pgAudit kommer til nytte.

For det samme input vil det producere dette output i loggen:

AUDIT: SESSION,33,1,FUNCTION,DO,,,"DO $$
BEGIN
UDFØR 'CREATE TABLE import' || 'ant_table(id int)';
END$$;"
AUDIT: SESSION,33,2,DDL,CREATE TABLE,TABLE,public.important_table,CREATE TABLE vigtig_tabel (id INT)

Ikke kun DO-blokken logges, men også den fulde tekst i CREATE TABLE med sætningstype, objekttype og fulde navn, hvilket gør søgningen lettere.

Når du logger SELECT- og DML-sætninger, kan pgAudit konfigureres til at logge en separat post for hver relation, der refereres til i sætningen.

Der kræves ingen parsing for at finde alle udsagn, der berører en bestemt tabel(*). "

Hvordan vil dette påvirke ydeevnen af ​​DBMS?

Lad os køre test med fuld revision aktiveret og se, hvad der sker med PostgreSQL-ydelsen. Lad os aktivere maksimal databaselogning for alle parametre.

Vi ændrer næsten intet i konfigurationsfilen, det vigtigste er at slå debug5-tilstanden til for at få maksimal information.

postgresql.conf

log_destination = 'stderr'
logge_collector = på
log_truncate_on_rotation = tændt
log_rotation_age = 1d
log_rotation_size = 10 MB
log_min_messages = debug5
log_min_error_statement = debug5
log_min_duration_statement = 0
debug_print_parse = til
debug_print_rewritten = til
debug_print_plan = til
debug_pretty_print = tændt
log_checkpoints = tændt
log_connections = tændt
log_disconnections = tændt
log_duration = tændt
log_værtsnavn = til
log_lock_wait = tændt
log_replication_commands = til
log_temp_filer = 0
log_timezone = 'Europa/Moskva'

På en PostgreSQL DBMS med parametre på 1 CPU, 2,8 GHz, 2 GB RAM, 40 GB HDD udfører vi tre belastningstest ved hjælp af kommandoerne:

$ 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

Test resultater:

Ingen logning
Med logning

Samlet databaseudfyldningstid
43,74 sek
53,23 sek

RAM
24 %
40 %

CPU
72 %
91 %

Test 1 (50 forbindelser)

Antal transaktioner på 10 minutter
74169
32445

Transaktioner/sek
123
54

Gennemsnitlig latenstid
405 ms
925 ms

Test 2 (150 forbindelser med 100 mulige)

Antal transaktioner på 10 minutter
81727
31429

Transaktioner/sek
136
52

Gennemsnitlig latenstid
550 ms
1432 ms

Om størrelser

DB størrelse
2251 MB
2262 MB

Database log størrelse
0 MB
4587 MB

Nederste linje: en fuldstændig revision er ikke særlig god. Dataene fra revisionen vil være lige så store som dataene i selve databasen, eller endnu mere. Mængden af ​​logning, der genereres, når man arbejder med et DBMS, er et almindeligt problem i produktionen.

Lad os se på andre parametre:

  • Hastigheden ændrer sig ikke meget: uden logning - 43,74 sekunder, med logning - 53,23 sekunder.
  • RAM og CPU-ydeevne vil lide, da du skal generere en revisionsfil. Dette er også mærkbart i produktiviteten.

Efterhånden som antallet af forbindelser stiger, vil ydeevnen naturligvis forringes en smule.

I virksomheder med revision er det endnu sværere:

  • der er en masse data;
  • revision er nødvendig ikke kun gennem syslog i SIEM, men også i filer: hvis der sker noget med syslog, skal der være en fil tæt på databasen, hvor dataene er gemt;
  • en separat hylde er nødvendig til revision for ikke at spilde I/O-diske, da den fylder meget;
  • Det sker, at informationssikkerhedsansatte har brug for GOST-standarder overalt, de kræver statslig identifikation.

Begrænsning af adgang til data

Lad os se på de teknologier, der bruges til at beskytte data og få adgang til dem i kommercielle DBMS'er og open source.

Hvad kan du generelt bruge:

  1. Kryptering og sløring af procedurer og funktioner (Wrapping) - det vil sige separate værktøjer og hjælpeprogrammer, der gør læsbar kode ulæselig. Sandt nok, så kan det hverken ændres eller refaktoreres tilbage. Denne tilgang er nogle gange påkrævet i det mindste på DBMS-siden - logikken i licensbegrænsninger eller autorisationslogik er krypteret præcist på procedure- og funktionsniveau.
  2. Begrænsning af datas synlighed efter rækker (RLS) er, når forskellige brugere ser én tabel, men en anden sammensætning af rækker i den, det vil sige, at noget ikke kan vises til nogen på rækkeniveau.
  3. Redigering af de viste data (Maskning) er, når brugere i en kolonne i tabellen ser enten data eller kun stjerner, det vil sige, at for nogle brugere vil oplysningerne blive lukket. Teknologien bestemmer, hvilken bruger der får vist hvad baseret på deres adgangsniveau.
  4. Sikkerhed DBA/Application DBA/DBA adgangskontrol handler derimod om at begrænse adgangen til selve DBMS, det vil sige, at informationssikkerhedsmedarbejdere kan adskilles fra databaseadministratorer og applikationsadministratorer. Der er få sådanne teknologier i open source, men der er masser af dem i kommercielle DBMS'er. De er nødvendige, når der er mange brugere med adgang til selve serverne.
  5. Begrænsning af adgang til filer på filsystemniveau. Du kan give rettigheder og adgangsprivilegier til mapper, så hver administrator kun har adgang til de nødvendige data.
  6. Obligatorisk adgang og hukommelsesrydning - disse teknologier bruges sjældent.
  7. End-to-end kryptering direkte fra DBMS er klientside kryptering med nøglehåndtering på serversiden.
  8. Datakryptering. For eksempel er kolonnekryptering, når du bruger en mekanisme, der krypterer en enkelt kolonne i databasen.

Hvordan påvirker dette DBMS'ens ydeevne?

Lad os se på eksemplet med kolonnekryptering i PostgreSQL. Der er et pgcrypto-modul, det giver dig mulighed for at gemme udvalgte felter i krypteret form. Dette er nyttigt, når kun nogle data er værdifulde. For at læse de krypterede felter sender klienten en dekrypteringsnøgle, serveren dekrypterer dataene og returnerer dem til klienten. Uden nøglen kan ingen gøre noget med dine data.

Lad os teste med pgcrypto. Lad os oprette en tabel med krypterede data og almindelige data. Nedenfor er kommandoerne til at oprette tabeller, i den allerførste linje er der en nyttig kommando - oprettelse af selve udvidelsen med DBMS-registrering:

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

Lad os derefter prøve at lave et dataeksempel fra hver tabel og se på udførelsestidspunkterne.

Valg fra en tabel uden krypteringsfunktion:

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

Stopuret er tændt.

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

Tid: 1,386 ms

Valg fra en tabel med krypteringsfunktion:

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

Stopuret er tændt.

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

Tid: 50,203 ms

Testresultater:

 
Uden kryptering
Pgcrypto (dekryptere)

Prøve 1000 rækker
1,386 ms
50,203 ms

CPU
15 %
35 %

RAM
 
+ 5%

Kryptering har stor indflydelse på ydeevnen. Det kan ses, at timingen er steget, da dekrypteringsoperationer af krypterede data (og dekryptering normalt stadig er pakket ind i din logik) kræver betydelige ressourcer. Det vil sige, at ideen om at kryptere alle kolonner, der indeholder nogle data, er fyldt med et fald i ydeevne.

Kryptering er dog ikke en sølvkugle, der løser alle problemer. De dekrypterede data og dekrypteringsnøglen under processen med dekryptering og overførsel af data er placeret på serveren. Derfor kan nøglerne opsnappes af en person, der har fuld adgang til databaseserveren, såsom en systemadministrator.

Når der er én nøgle til hele kolonnen for alle brugere (selvom ikke for alle, men for klienter i et begrænset sæt), er dette ikke altid godt og korrekt. Det er grunden til, at de begyndte at lave ende-til-ende-kryptering, i DBMS begyndte de at overveje muligheder for at kryptere data på klient- og serversiden, og de samme nøglehvælvingslagre dukkede op - separate produkter, der giver nøglestyring på DBMS'et side.

Sikkerhed og DBMS: hvad du skal huske, når du vælger sikkerhedsværktøjer
Et eksempel på en sådan kryptering i MongoDB

Sikkerhedsfunktioner i kommerciel og open source DBMS

Funktioner
Type
Password-politik
Revision
Beskyttelse af kildekoden til procedurer og funktioner
RLS
Kryptering

Oracle
kommerciel
+
+
+
+
+

MsSql
kommerciel
+
+
+
+
+

Jatoba
kommerciel
+
+
+
+
udvidelser

PostgreSQL
Gratis
udvidelser
udvidelser

+
udvidelser

MongoDb
Gratis

+


Kun tilgængelig i MongoDB Enterprise

Tabellen er langt fra komplet, men situationen er denne: I kommercielle produkter er sikkerhedsproblemer blevet løst i lang tid, i open source bruges som regel en form for tilføjelser til sikkerhed, mange funktioner mangler , nogle gange skal man tilføje noget. For eksempel adgangskodepolitikker - PostgreSQL har mange forskellige udvidelser (1, 2, 3, 4, 5), som implementerer adgangskodepolitikker, men efter min mening dækker ingen af ​​dem alle behovene i det indenlandske virksomhedssegment.

Hvad skal du gøre, hvis du ikke har det, du har brug for nogen steder? For eksempel vil du bruge et specifikt DBMS, der ikke har de funktioner, som kunden efterspørger.

Så kan du bruge tredjepartsløsninger, der fungerer med forskellige DBMS'er, for eksempel Crypto DB eller Garda DB. Hvis vi taler om løsninger fra det indenlandske segment, så kender de til GOST'er bedre end i open source.

Den anden mulighed er at skrive, hvad du har brug for selv, implementere dataadgang og kryptering i applikationen på procedureniveau. Sandt nok vil det være sværere med GOST. Men generelt kan du skjule dataene efter behov, lægge dem i et DBMS, derefter hente dem og dekryptere dem efter behov, lige på applikationsniveau. Tænk samtidig med det samme over, hvordan du vil beskytte disse algoritmer i applikationen. Det bør efter vores mening gøres på DBMS-niveau, fordi det vil fungere hurtigere.

Denne rapport blev første gang præsenteret kl @Databaser Meetup af Mail.ru Cloud Solutions. Se видео andre forestillinger og abonner på begivenhedsannonceringer på Telegram Omkring Kubernetes på Mail.ru Group.

Hvad skal man ellers læse om emnet:

  1. Mere end Ceph: MCS cloud block storage.
  2. Sådan vælger du en database til et projekt, så du ikke behøver at vælge igen.

Kilde: www.habr.com

Tilføj en kommentar