Sikkerhet og DBMS: hva du må huske når du velger sikkerhetsverktøy

Sikkerhet og DBMS: hva du må huske når du velger sikkerhetsverktøy

Mitt navn er Denis Rozhkov, jeg er leder for programvareutvikling i Gazinformservice-selskapet, i produktteamet Jatoba. Lovgivning og bedriftsbestemmelser stiller visse krav til sikkerheten ved datalagring. Ingen ønsker at tredjeparter skal få tilgang til konfidensiell informasjon, så følgende saker er viktige for ethvert prosjekt: identifikasjon og autentisering, administrering av tilgang til data, sikring av integriteten til informasjon i systemet, logging av sikkerhetshendelser. Derfor vil jeg snakke om noen interessante punkter angående DBMS-sikkerhet.

Artikkelen ble utarbeidet basert på en tale kl @DatabaserMeetup, organisert Mail.ru skyløsninger. Hvis du ikke vil lese, kan du se:


Artikkelen vil ha tre deler:

  • Hvordan sikre tilkoblinger.
  • Hva er en revisjon av handlinger og hvordan registrere hva som skjer på databasesiden og koble til den.
  • Hvordan beskytte data i selve databasen og hvilke teknologier som finnes for dette.

Sikkerhet og DBMS: hva du må huske når du velger sikkerhetsverktøy
Tre komponenter av DBMS-sikkerhet: tilkoblingsbeskyttelse, aktivitetsrevisjon og databeskyttelse

Sikre tilkoblingene dine

Du kan koble til databasen enten direkte eller indirekte gjennom webapplikasjoner. Som regel samhandler forretningsbrukeren, det vil si personen som jobber med DBMS, indirekte med det.

Før du snakker om å beskytte tilkoblinger, må du svare på viktige spørsmål som bestemmer hvordan sikkerhetstiltak skal struktureres:

  • Tilsvarer én bedriftsbruker én DBMS-bruker?
  • om tilgang til DBMS-data kun gis gjennom en API som du kontrollerer, eller om tabeller får direkte tilgang;
  • om DBMS er allokert til et eget beskyttet segment, hvem som samhandler med det og hvordan;
  • om det benyttes pooling/proxy og mellomlag, som kan endre informasjon om hvordan forbindelsen er bygget opp og hvem som bruker databasen.

La oss nå se hvilke verktøy som kan brukes for å sikre tilkoblinger:

  1. Bruk klasseløsninger for databasebrannmur. Et ekstra lag med beskyttelse vil som et minimum øke åpenheten av hva som skjer i DBMS, og maksimalt vil du kunne gi ekstra databeskyttelse.
  2. Bruk passordpolitikk. Bruken avhenger av hvordan arkitekturen din er bygget. Uansett er ett passord i konfigurasjonsfilen til en nettapplikasjon som kobles til DBMS ikke nok for beskyttelse. Det finnes en rekke DBMS-verktøy som lar deg kontrollere at brukeren og passordet krever oppdatering.

    Du kan lese mer om brukervurderingsfunksjoner her, kan du også finne ut om MS SQL Vulnerability Assessmen her

  3. Berik konteksten til økten med nødvendig informasjon. Hvis økten er ugjennomsiktig forstår du ikke hvem som jobber i DBMS innenfor rammen av det, du kan innenfor rammen av operasjonen som utføres, legge til informasjon om hvem som gjør hva og hvorfor. Denne informasjonen kan sees i tilsynet.
  4. Konfigurer SSL hvis du ikke har et nettverksskille mellom DBMS og sluttbrukere; det er ikke i et eget VLAN. I slike tilfeller er det viktig å beskytte kanalen mellom forbrukeren og selve DBMS. Sikkerhetsverktøy er også tilgjengelig i åpen kildekode.

Hvordan vil dette påvirke ytelsen til DBMS?

La oss se på eksemplet med PostgreSQL for å se hvordan SSL påvirker CPU-belastningen, øker timingen og reduserer TPS, og om det vil forbruke for mange ressurser hvis du aktiverer det.

Laste PostgreSQL ved hjelp av pgbench er et enkelt program for å kjøre ytelsestester. Den utfører en enkelt sekvens av kommandoer gjentatte ganger, muligens i parallelle databasesesjoner, og beregner deretter den gjennomsnittlige transaksjonshastigheten.

Test 1 uten SSL og bruk SSL — forbindelsen opprettes for hver transaksjon:

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 uten SSL og bruk SSL – alle transaksjoner utfø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 innstillinger:

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

En forbindelse opprettes for hver transaksjon

gjennomsnittlig ventetid
171.915 ms
187.695 ms

tps inkludert etablering av tilkoblinger
58.168112
53.278062

tps unntatt etablering av tilkoblinger
64.084546
58.725846

prosessor
24%
28%

Alle transaksjoner utføres i én forbindelse

gjennomsnittlig ventetid
6.722 ms
6.342 ms

tps inkludert etablering av tilkoblinger
1587.657278
1576.792883

tps unntatt etablering av tilkoblinger
1588.380574
1577.694766

prosessor
17%
21%

Ved lett belastning er påvirkningen av SSL sammenlignbar med målefeilen. Hvis mengden data som overføres er svært stor, kan situasjonen være annerledes. Hvis vi etablerer én tilkobling per transaksjon (dette er sjelden, vanligvis er koblingen delt mellom brukere), har du et stort antall tilkoblinger/frakoblinger, virkningen kan være litt større. Det vil si at det kan være risiko for redusert ytelse, men forskjellen er ikke så stor at man ikke bruker beskyttelse.

Vær oppmerksom på at det er en sterk forskjell hvis du sammenligner driftsmodusene: du jobber i samme økt eller i forskjellige. Dette er forståelig: ressurser brukes på å opprette hver forbindelse.

Vi hadde en sak da vi koblet Zabbix i tillitsmodus, det vil si at md5 ikke ble sjekket, det var ikke behov for autentisering. Deretter ba kunden om å aktivere md5-autentiseringsmodus. Dette la en stor belastning på CPU, og ytelsen falt. Vi begynte å se etter måter å optimalisere på. En av de mulige løsningene på problemet er å implementere en nettverksbegrensning, lage separate VLAN-er for DBMS, legge til innstillinger for å gjøre det klart hvem som kobler fra hvor og fjerne autentisering. Du kan også optimalisere autentiseringsinnstillingene for å redusere kostnadene når du aktiverer autentisering , men generelt sett påvirker bruken av ulike metoder for autentisering ytelsen og krever at disse faktorene tas i betraktning når man designer datakraften til servere (maskinvare) for DBMS.

Konklusjon: i en rekke løsninger kan selv små nyanser i autentisering ha stor innvirkning på prosjektet, og det er dårlig når dette først blir klart når det implementeres i produksjonen.

Handlingsrevisjon

Revisjon kan ikke bare være DBMS. En revisjon handler om å innhente informasjon om hva som skjer i ulike segmenter. Dette kan enten være en databasebrannmur eller operativsystemet som DBMS er bygget på.

I kommersielle Enterprise-nivå DBMS-er er alt bra med revisjon, men i åpen kildekode - ikke alltid. Her er hva PostgreSQL har:

  • standardlogg - innebygd logging;
  • utvidelser: paudit - hvis standard logging ikke er nok for deg, kan du bruke separate innstillinger som løser noen problemer.

Tillegg til rapporten i videoen:

"Grunnleggende erklæringslogging kan leveres av en standard loggingsfunksjon med log_statement = all.

Dette er akseptabelt for overvåking og annen bruk, men gir ikke detaljnivået som vanligvis kreves for revisjon.

Det er ikke nok å ha en liste over alle operasjonene som utføres på databasen.

Det skal også være mulig å finne konkrete uttalelser som er av interesse for revisor.

Standard logging viser hva brukeren ba om, mens pgAudit fokuserer på detaljene om hva som skjedde da databasen utførte spørringen.

Revisor kan for eksempel ønske å verifisere at en bestemt tabell ble opprettet innenfor et dokumentert vedlikeholdsvindu.

Dette kan virke som en enkel oppgave med grunnleggende revisjon og grep, men hva om du ble presentert for noe sånt som dette (med vilje forvirrende) eksempel:

GJØR$$
BEGYNNE
UTFØR 'CREATE TABLE import' || 'ant_table(id int)';
END$$;

Standard logging vil gi deg dette:

LOG: setning: GJØR $$
BEGYNNE
UTFØR 'CREATE TABLE import' || 'ant_table(id int)';
END$$;

Det ser ut til at det å finne den interessante tabellen kan kreve noe kodekunnskap i tilfeller der tabeller opprettes dynamisk.

Dette er ikke ideelt, siden det ville være å foretrekke å bare søke etter tabellnavn.

Det er her pgAudit kommer godt med.

For den samme inngangen vil den produsere denne utgangen i loggen:

REVISJON: SESSION,33,1,FUNCTION,DO,,,"DO $$
BEGYNNE
UTFØR 'CREATE TABLE import' || 'ant_table(id int)';
END$$;"
REVISJON: SESSION,33,2,DDL,CREATE TABLE,TABLE,public.important_table,CREATE TABLE viktig_tabell (id INT)

Ikke bare DO-blokken logges, men også hele teksten til CREATE TABLE med setningstype, objekttype og fullt navn, noe som gjør det enklere å søke.

Når du logger SELECT- og DML-setninger, kan pgAudit konfigureres til å logge en separat oppføring for hvert forhold det refereres til i setningen.

Ingen analysering er nødvendig for å finne alle utsagn som berører en bestemt tabell(*) ”.

Hvordan vil dette påvirke ytelsen til DBMS?

La oss kjøre tester med full revisjon aktivert og se hva som skjer med PostgreSQL-ytelsen. La oss aktivere maksimal databaselogging for alle parametere.

Vi endrer nesten ingenting i konfigurasjonsfilen, det viktigste er å slå på debug5-modusen for å få maksimal informasjon.

postgresql.conf

log_destination = 'stderr'
logging_collector = på
log_truncate_on_rotation = på
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 = på
debug_print_rewritten = på
debug_print_plan = på
debug_pretty_print = på
log_checkpoints = på
log_connections = på
log_disconnections = på
log_duration = på
log_hostname = på
log_lock_wait = på
log_replication_commands = på
log_temp_files = 0
log_timezone = 'Europa/Moskva'

På en PostgreSQL DBMS med parametere på 1 CPU, 2,8 GHz, 2 GB RAM, 40 GB HDD, utfører vi tre belastningstester ved å bruke kommandoene:

$ 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

Testresultater:

Ingen logging
Med logging

Total databasefyllingstid
43,74 sek
53,23 sek

RAM
24%
40%

prosessor
72%
91%

Test 1 (50 tilkoblinger)

Antall transaksjoner på 10 minutter
74169
32445

Transaksjoner/sek
123
54

Gjennomsnittlig ventetid
405 ms
925 ms

Test 2 (150 tilkoblinger med 100 mulige)

Antall transaksjoner på 10 minutter
81727
31429

Transaksjoner/sek
136
52

Gjennomsnittlig ventetid
550 ms
1432 ms

Om størrelser

DB størrelse
2251 MB
2262 MB

Databaseloggstørrelse
0 MB
4587 MB

Bunnlinjen: en fullstendig revisjon er ikke veldig bra. Dataene fra tilsynet vil være like store som dataene i selve databasen, eller enda mer. Mengden logging som genereres når du arbeider med et DBMS er et vanlig problem i produksjonen.

La oss se på andre parametere:

  • Hastigheten endres ikke mye: uten logging - 43,74 sekunder, med logging - 53,23 sekunder.
  • RAM og CPU-ytelse vil lide, ettersom du må generere en revisjonsfil. Dette merkes også i produktiviteten.

Ettersom antall tilkoblinger øker, vil naturligvis ytelsen forringes noe.

I selskaper med revisjon er det enda vanskeligere:

  • det er mye data;
  • revisjon er nødvendig ikke bare gjennom syslog i SIEM, men også i filer: hvis noe skjer med syslog, må det være en fil nær databasen der dataene er lagret;
  • en egen hylle er nødvendig for revisjon for ikke å kaste bort I/O-disker, da den tar opp mye plass;
  • Det hender at ansatte i informasjonssikkerhet trenger GOST-standarder overalt, de krever statlig identifikasjon.

Begrensning av tilgang til data

La oss se på teknologiene som brukes til å beskytte data og få tilgang til dem i kommersielle DBMS-er og åpen kildekode.

Hva kan du vanligvis bruke:

  1. Kryptering og tilsløring av prosedyrer og funksjoner (Wrapping) – det vil si separate verktøy og verktøy som gjør lesbar kode uleselig. Riktignok kan den verken endres eller refaktoreres tilbake. Denne tilnærmingen er noen ganger nødvendig i det minste på DBMS-siden - logikken til lisensrestriksjoner eller autorisasjonslogikk er kryptert nøyaktig på prosedyre- og funksjonsnivå.
  2. Å begrense synligheten av data etter rader (RLS) er når forskjellige brukere ser én tabell, men en annen sammensetning av rader i den, det vil si at noe ikke kan vises til noen på radnivå.
  3. Redigering av de viste dataene (maskering) er når brukere i én kolonne i tabellen ser enten data eller bare stjerner, det vil si at for noen brukere vil informasjonen bli lukket. Teknologien bestemmer hvilken bruker som får vist hva basert på deres tilgangsnivå.
  4. Sikkerhet DBA/Application DBA/DBA-tilgangskontroll handler snarere om å begrense tilgangen til selve DBMS, det vil si at informasjonssikkerhetsansatte kan skilles fra databaseadministratorer og applikasjonsadministratorer. Det er få slike teknologier i åpen kildekode, men det er nok av dem i kommersielle DBMS-er. De trengs når det er mange brukere med tilgang til selve serverne.
  5. Begrensning av tilgang til filer på filsystemnivå. Du kan gi rettigheter og tilgangsprivilegier til kataloger slik at hver administrator bare har tilgang til de nødvendige dataene.
  6. Obligatorisk tilgang og minnetømming - disse teknologiene brukes sjelden.
  7. End-to-end-kryptering direkte fra DBMS er klientside-kryptering med nøkkelhåndtering på serversiden.
  8. Datakryptering. For eksempel er kolonnekryptering når du bruker en mekanisme som krypterer en enkelt kolonne i databasen.

Hvordan påvirker dette ytelsen til DBMS?

La oss se på eksemplet med kolonnekryptering i PostgreSQL. Det er en pgcrypto-modul, den lar deg lagre utvalgte felt i kryptert form. Dette er nyttig når bare noen data er verdifulle. For å lese de krypterte feltene, sender klienten en dekrypteringsnøkkel, serveren dekrypterer dataene og returnerer dem til klienten. Uten nøkkelen kan ingen gjøre noe med dataene dine.

La oss teste med pgcrypto. La oss lage en tabell med krypterte data og vanlige data. Nedenfor er kommandoene for å lage tabeller, i den aller første linjen er det en nyttig kommando - å lage selve utvidelsen 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'));

La oss deretter prøve å lage et dataeksempel fra hver tabell og se på utførelsestidspunktene.

Velge fra en tabell uten krypteringsfunksjon:

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

Stoppeklokken er på.

  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 linjer)

Tid: 1,386 ms

Valg fra en tabell med krypteringsfunksjon:

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

Stoppeklokken er på.

  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:

 
Ingen kryptering
Pgcrypto (dekryptere)

Prøve 1000 rader
1,386 ms
50,203 ms

prosessor
15%
35%

RAM
 
+ 5%

Kryptering har stor innvirkning på ytelsen. Det kan sees at timingen har økt, siden dekrypteringsoperasjoner av krypterte data (og dekryptering vanligvis fortsatt er pakket inn i logikken din) krever betydelige ressurser. Det vil si at ideen om å kryptere alle kolonner som inneholder noen data er fylt med en reduksjon i ytelse.

Kryptering er imidlertid ikke en sølvkule som løser alle problemer. De dekrypterte dataene og dekrypteringsnøkkelen under prosessen med dekryptering og overføring av data er plassert på serveren. Derfor kan nøklene bli fanget opp av noen som har full tilgang til databaseserveren, for eksempel en systemadministrator.

Når det er én nøkkel for hele kolonnen for alle brukere (selv om ikke for alle, men for klienter av et begrenset sett), er ikke dette alltid bra og riktig. Derfor begynte de å gjøre ende-til-ende-kryptering, i DBMS begynte de å vurdere alternativer for kryptering av data på klient- og serversiden, og de samme nøkkelhvelvlagrene dukket opp - separate produkter som gir nøkkeladministrasjon på DBMS side.

Sikkerhet og DBMS: hva du må huske når du velger sikkerhetsverktøy
Et eksempel på slik kryptering i MongoDB

Sikkerhetsfunksjoner i kommersiell og åpen kildekode DBMS

funksjoner
Type
Passordpolicy
Audit
Beskyttelse av kildekoden til prosedyrer og funksjoner
RLS
kryptering

Oracle
kommersiell
+
+
+
+
+

MsSql
kommersiell
+
+
+
+
+

Jatoba
kommersiell
+
+
+
+
utvidelser

PostgreSQL
Gratis
utvidelser
utvidelser
-
+
utvidelser

MongoDb
Gratis
-
+
-
-
Kun tilgjengelig i MongoDB Enterprise

Tabellen er langt fra komplett, men situasjonen er denne: i kommersielle produkter har sikkerhetsproblemer blitt løst i lang tid, i åpen kildekode brukes som regel noen slags tillegg for sikkerhet, mange funksjoner mangler , noen ganger må du legge til noe. For eksempel passordpolicyer - PostgreSQL har mange forskjellige utvidelser (1, 2, 3, 4, 5), som implementerer passordpolitikk, men etter min mening dekker ingen av dem alle behovene til det innenlandske bedriftssegmentet.

Hva du skal gjøre hvis du ikke har det du trenger noe sted? Du ønsker for eksempel å bruke et spesifikt DBMS som ikke har de funksjonene som kunden krever.

Da kan du bruke tredjepartsløsninger som fungerer med ulike DBMS-er, for eksempel Crypto DB eller Garda DB. Hvis vi snakker om løsninger fra det innenlandske segmentet, så vet de om GOST-er bedre enn i åpen kildekode.

Det andre alternativet er å skrive det du trenger selv, implementere datatilgang og kryptering i applikasjonen på prosedyrenivå. Riktignok vil det være vanskeligere med GOST. Men generelt kan du skjule dataene etter behov, legge dem i et DBMS, og deretter hente det og dekryptere det etter behov, rett på applikasjonsnivå. Tenk samtidig på hvordan du vil beskytte disse algoritmene i applikasjonen. Etter vår mening bør dette gjøres på DBMS-nivå, fordi det vil fungere raskere.

Denne rapporten ble først presentert kl @Databaser Meetup av Mail.ru Cloud Solutions. Se video andre forestillinger og abonner på begivenhetskunngjøringer på Telegram Rundt Kubernetes på Mail.ru Group.

Hva annet å lese om emnet:

  1. Mer enn Ceph: MCS skyblokklagring.
  2. Hvordan velge en database for et prosjekt slik at du ikke trenger å velge på nytt.

Kilde: www.habr.com

Legg til en kommentar