Säkerhet och DBMS: vad du behöver komma ihåg när du väljer säkerhetsverktyg

Säkerhet och DBMS: vad du behöver komma ihåg när du väljer säkerhetsverktyg

Jag heter Denis Rozhkov, jag är chef för mjukvaruutveckling på Gazinformservice-företaget, i produktteamet Jatoba. Lagstiftning och företagsbestämmelser ställer vissa krav på säkerheten för datalagring. Ingen vill att tredje part ska få tillgång till konfidentiell information, så följande frågor är viktiga för alla projekt: identifiering och autentisering, hantering av åtkomst till data, säkerställande av informationens integritet i systemet, loggning av säkerhetshändelser. Därför vill jag prata om några intressanta punkter angående DBMS-säkerhet.

Artikeln förbereddes utifrån ett tal kl @DatabaserMeetup, organiserad Mail.ru molnlösningar. Om du inte vill läsa kan du titta på:


Artikeln kommer att ha tre delar:

  • Hur man säkrar anslutningar.
  • Vad är en granskning av åtgärder och hur man registrerar vad som händer på databassidan och kopplar till den.
  • Hur man skyddar data i själva databasen och vilka teknologier som finns tillgängliga för detta.

Säkerhet och DBMS: vad du behöver komma ihåg när du väljer säkerhetsverktyg
Tre komponenter i DBMS-säkerhet: anslutningsskydd, aktivitetsrevision och dataskydd

Säkra dina anslutningar

Du kan ansluta till databasen antingen direkt eller indirekt via webbapplikationer. Som regel interagerar affärsanvändaren, det vill säga personen som arbetar med DBMS, indirekt med den.

Innan du pratar om att skydda anslutningar måste du svara på viktiga frågor som avgör hur säkerhetsåtgärder kommer att struktureras:

  • Är en företagsanvändare likvärdig med en DBMS-användare?
  • om åtkomst till DBMS-data endast tillhandahålls via ett API som du kontrollerar, eller om tabeller nås direkt;
  • om DBMS är allokerat till ett separat skyddat segment, vem som interagerar med det och hur;
  • om pooling/proxy och mellanlager används, vilket kan ändra information om hur anslutningen är uppbyggd och vem som använder databasen.

Låt oss nu se vilka verktyg som kan användas för att säkra anslutningar:

  1. Använd databasbrandväggsklasslösningar. Ett extra skyddslager kommer, som ett minimum, att öka transparensen av vad som händer i DBMS, och högst kommer du att kunna tillhandahålla ytterligare dataskydd.
  2. Använd lösenordspolicyer. Deras användning beror på hur din arkitektur är byggd. I alla fall räcker inte ett lösenord i konfigurationsfilen för en webbapplikation som ansluter till DBMS för skydd. Det finns ett antal DBMS-verktyg som låter dig kontrollera att användaren och lösenordet behöver uppdateras.

    Du kan läsa mer om användarbetygsfunktioner här, kan du också ta reda på om MS SQL Vulnerability Assessmen här

  3. Berika sessionens sammanhang med nödvändig information. Om sessionen är ogenomskinlig förstår du inte vem som arbetar i DBMS inom dess ramar, du kan inom ramen för den operation som utförs lägga till information om vem som gör vad och varför. Denna information kan ses i revisionen.
  4. Konfigurera SSL om du inte har en nätverksseparation mellan DBMS och slutanvändare, det är inte i ett separat VLAN. I sådana fall är det absolut nödvändigt att skydda kanalen mellan konsumenten och själva DBMS. Säkerhetsverktyg är också tillgängliga i öppen källkod.

Hur kommer detta att påverka prestandan för DBMS?

Låt oss titta på exemplet med PostgreSQL för att se hur SSL påverkar CPU-belastningen, ökar timings och minskar TPS, och om det kommer att förbruka för många resurser om du aktiverar det.

Att ladda PostgreSQL med pgbench är ett enkelt program för att köra prestandatester. Den utför en enda sekvens av kommandon upprepade gånger, möjligen i parallella databassessioner, och beräknar sedan den genomsnittliga transaktionshastigheten.

Testa 1 utan SSL och med SSL — anslutningen upprättas för varje 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"

Testa 2 utan SSL och med SSL — alla transaktioner utförs i en anslutning:

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"

Andra inställningar:

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

Testresultat:

 
INGEN SSL
SSL

En anslutning upprättas för varje transaktion

genomsnitt för latens
171.915 ms
187.695 ms

tps inklusive upprättande av anslutningar
58.168112
53.278062

tps exklusive upprättande av anslutningar
64.084546
58.725846

CPU
24%
28%

Alla transaktioner utförs i en anslutning

genomsnitt för latens
6.722 ms
6.342 ms

tps inklusive upprättande av anslutningar
1587.657278
1576.792883

tps exklusive upprättande av anslutningar
1588.380574
1577.694766

CPU
17%
21%

Vid lätta belastningar är inverkan av SSL jämförbar med mätfelet. Om mängden överförd data är mycket stor kan situationen vara annorlunda. Om vi ​​upprättar en anslutning per transaktion (detta är sällsynt, vanligtvis delas anslutningen mellan användare) har du ett stort antal anslutningar/avbrott, påverkan kan bli lite större. Det vill säga att det kan finnas risker för nedsatt prestanda, dock är skillnaden inte så stor att man inte använder skydd.

Observera att det är stor skillnad om du jämför driftslägena: du arbetar inom samma session eller i olika. Detta är förståeligt: ​​resurser spenderas på att skapa varje anslutning.

Vi hade ett fall när vi kopplade Zabbix i förtroendeläge, det vill säga att md5 inte kontrollerades, det fanns inget behov av autentisering. Sedan bad kunden att aktivera md5-autentiseringsläget. Detta satte en stor belastning på CPU:n och prestandan sjönk. Vi började leta efter sätt att optimera. En av de möjliga lösningarna på problemet är att implementera nätverksbegränsningar, göra separata VLAN för DBMS, lägga till inställningar för att göra det tydligt vem som ansluter varifrån och ta bort autentisering. Du kan också optimera autentiseringsinställningar för att minska kostnaderna när autentisering aktiveras, men i allmänhet påverkar användningen av olika metoder för autentisering prestandan och kräver att man tar hänsyn till dessa faktorer när man utformar datorkraften hos servrar (hårdvara) för DBMS.

Slutsats: i ett antal lösningar kan även små nyanser i autentiseringen i hög grad påverka projektet och det är dåligt när detta blir tydligt först när det implementeras i produktionen.

Åtgärdsrevision

Revision kan inte bara vara DBMS. En revision handlar om att få information om vad som händer inom olika segment. Detta kan antingen vara en databasbrandvägg eller operativsystemet som DBMS är byggt på.

I kommersiella Enterprise-nivå DBMS är allt bra med revision, men i öppen källkod - inte alltid. Här är vad PostgreSQL har:

  • standardlogg - inbyggd loggning;
  • tillägg: pgaudit - om standardloggning inte räcker för dig kan du använda separata inställningar som löser vissa problem.

Tillägg till rapporten i videon:

"Grundläggande satsloggning kan tillhandahållas av en standardloggningsanläggning med log_statement = all.

Detta är acceptabelt för övervakning och annan användning, men ger inte den detaljnivå som vanligtvis krävs för revision.

Det räcker inte att ha en lista över alla operationer som utförs på databasen.

Det bör också vara möjligt att hitta specifika uttalanden som är av intresse för revisorn.

Standardloggning visar vad användaren begärde, medan pgAudit fokuserar på detaljerna om vad som hände när databasen körde frågan.

Till exempel kan revisorn vilja verifiera att en viss tabell skapades inom ett dokumenterat underhållsfönster.

Det här kan tyckas vara en enkel uppgift med grundläggande revision och grep, men tänk om du fick något liknande detta (avsiktligt förvirrande) exempel:

DO$$
BÖRJA
UTFÖR 'CREATE TABLE import' || 'ant_table(id int)';
END$$;

Standardloggning ger dig detta:

LOG: uttalande: GÖR $$
BÖRJA
UTFÖR 'CREATE TABLE import' || 'ant_table(id int)';
END$$;

Det verkar som om att hitta den intressanta tabellen kan kräva viss kodkunskap i fall där tabeller skapas dynamiskt.

Detta är inte idealiskt, eftersom det vore att föredra att helt enkelt söka efter tabellnamn.

Det är här pgAudit kommer väl till pass.

För samma ingång kommer den att producera denna utdata i loggen:

REVISION: SESSION,33,1,FUNCTION,DO,,,"DO $$
BÖRJA
UTFÖR 'CREATE TABLE import' || 'ant_table(id int)';
END$$;"
REVISION: SESSION,33,2,DDL,CREATE TABLE,TABELL,public.important_table,CREATE TABLE viktig_tabell (id INT)

Inte bara DO-blocket loggas, utan även hela texten i CREATE TABLE med satstyp, objekttyp och fullständigt namn, vilket gör sökningen enklare.

När du loggar SELECT- och DML-satser kan pgAudit konfigureras att logga en separat post för varje relation som refereras till i satsen.

Ingen analys krävs för att hitta alla påståenden som rör en viss tabell(*) ».

Hur kommer detta att påverka prestandan för DBMS?

Låt oss köra tester med full revision aktiverad och se vad som händer med PostgreSQL-prestanda. Låt oss aktivera maximal databasloggning för alla parametrar.

Vi ändrar nästan ingenting i konfigurationsfilen, det viktigaste är att slå på debug5-läget för att få maximal information.

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 = felsöka5
log_min_error_statement = felsöka5
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 parametrar på 1 CPU, 2,8 GHz, 2 GB RAM, 40 GB HDD, genomför vi tre belastningstester med hjälp av kommandona:

$ 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

Testresultat:

Ingen loggning
Med loggning

Total databasfyllningstid
43,74 sek
53,23 sek

RAM
24%
40%

CPU
72%
91%

Test 1 (50 anslutningar)

Antal transaktioner på 10 minuter
74169
32445

Transaktioner/sek
123
54

Genomsnittlig latens
405 ms
925 ms

Test 2 (150 anslutningar med 100 möjliga)

Antal transaktioner på 10 minuter
81727
31429

Transaktioner/sek
136
52

Genomsnittlig latens
550 ms
1432 ms

Om storlekar

DB storlek
2251 MB
2262 MB

Databasloggstorlek
0 MB
4587 MB

Sammanfattning: en fullständig revision är inte särskilt bra. Uppgifterna från revisionen kommer att vara lika stora som uppgifterna i själva databasen, eller till och med mer. Mängden loggning som genereras när man arbetar med ett DBMS är ett vanligt problem i produktionen.

Låt oss titta på andra parametrar:

  • Hastigheten förändras inte mycket: utan loggning - 43,74 sekunder, med loggning - 53,23 sekunder.
  • RAM- och CPU-prestanda kommer att lida eftersom du behöver generera en revisionsfil. Detta märks också på produktiviteten.

När antalet anslutningar ökar kommer naturligtvis prestandan att försämras något.

I företag med revision är det ännu svårare:

  • det finns mycket data;
  • granskning behövs inte bara genom syslog i SIEM, utan också i filer: om något händer med syslog måste det finnas en fil nära databasen där data sparas;
  • revision kräver en separat hylla för att inte slösa bort I/O-diskar, eftersom det tar upp mycket utrymme;
  • Det händer att informationssäkerhetsanställda behöver GOST-standarder överallt, de kräver statlig identifiering.

Begränsa åtkomst till data

Låt oss titta på de teknologier som används för att skydda data och komma åt dem i kommersiella DBMS och öppen källkod.

Vad kan du generellt använda:

  1. Kryptering och obfuskering av procedurer och funktioner (Wrapping) - det vill säga separata verktyg och verktyg som gör läsbar kod oläsbar. Det är sant, då kan det varken ändras eller refaktoreras tillbaka. Detta tillvägagångssätt krävs ibland åtminstone på DBMS-sidan - logiken för licensbegränsningar eller auktoriseringslogik krypteras exakt på procedur- och funktionsnivå.
  2. Att begränsa synligheten av data efter rader (RLS) är när olika användare ser en tabell, men en annan sammansättning av rader i den, det vill säga något kan inte visas för någon på radnivå.
  3. Att redigera visade data (Maskning) är när användare i en kolumn i tabellen ser antingen data eller bara asterisker, det vill säga för vissa användare kommer informationen att stängas. Tekniken avgör vilken användare som visas vad baserat på deras åtkomstnivå.
  4. Säkerhet DBA/Application DBA/DBA åtkomstkontroll handlar snarare om att begränsa åtkomsten till själva DBMS, det vill säga att informationssäkerhetsanställda kan separeras från databasadministratörer och applikationsadministratörer. Det finns få sådana tekniker i öppen källkod, men det finns gott om dem i kommersiella DBMS. De behövs när det finns många användare med tillgång till själva servrarna.
  5. Begränsa åtkomst till filer på filsystemnivå. Du kan ge rättigheter och åtkomstprivilegier till kataloger så att varje administratör endast har åtkomst till nödvändig data.
  6. Obligatorisk åtkomst och minnesrensning - dessa tekniker används sällan.
  7. End-to-end-kryptering direkt från DBMS är kryptering på klientsidan med nyckelhantering på serversidan.
  8. Datakryptering. Kolumnär kryptering är till exempel när du använder en mekanism som krypterar en enda kolumn i databasen.

Hur påverkar detta prestandan hos DBMS?

Låt oss titta på exemplet med kolumnär kryptering i PostgreSQL. Det finns en pgcrypto-modul, den låter dig lagra utvalda fält i krypterad form. Detta är användbart när endast vissa data är värdefulla. För att läsa de krypterade fälten sänder klienten en dekrypteringsnyckel, servern dekrypterar data och returnerar den till klienten. Utan nyckeln kan ingen göra något med din data.

Låt oss testa med pgcrypto. Låt oss skapa en tabell med krypterad data och vanliga data. Nedan finns kommandona för att skapa tabeller, på den allra första raden finns ett användbart kommando - skapa själva tillägget 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'));

Låt oss sedan försöka göra ett dataprov från varje tabell och titta på exekveringstiderna.

Välja från en tabell utan krypteringsfunktion:

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

Stoppuret är på.

  id | text1 | text2
——+——-+——-
1 | 1 | 1
2 | 2 | 2
3 | 3 | 3
.
997 | 997 | 997
998 | 998 | 998
999 | 999 | 999
1000 | 1000 | 1000
(1000 rader)

Tid: 1,386 ms

Val från en tabell 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

Stoppuret är på.

  id | dekryptera | Avkryptera
——+—————+————
1 | x31 | x31
2 | x32 | x32
3 | x33 | x33
.
999 | x393939 | x393939
1000 | x31303030 | x31303030
(1000 rader)

Tid: 50,203 ms

Testresultat:

 
Utan kryptering
Pgcrypto (dekryptera)

Prov på 1000 rader
1,386 ms
50,203 ms

CPU
15%
35%

RAM
 
+ 5%

Kryptering har stor inverkan på prestanda. Det kan ses att timingen har ökat, eftersom dekrypteringsoperationer av krypterad data (och dekryptering vanligtvis fortfarande är insvept i din logik) kräver betydande resurser. Det vill säga, idén om att kryptera alla kolumner som innehåller vissa data är fylld med en minskning av prestanda.

Kryptering är dock inte en silverkula som löser alla problem. Den dekrypterade datan och dekrypteringsnyckeln under processen att dekryptera och överföra data finns på servern. Därför kan nycklarna fångas upp av någon som har full tillgång till databasservern, till exempel en systemadministratör.

När det finns en nyckel för hela kolumnen för alla användare (även om det inte är för alla, men för klienter i en begränsad uppsättning), är detta inte alltid bra och korrekt. Det var därför de började göra end-to-end-kryptering, i DBMS började de överväga alternativ för att kryptera data på klient- och serversidan, och samma nyckelvalvslagringar dök upp - separata produkter som tillhandahåller nyckelhantering på DBMS sida.

Säkerhet och DBMS: vad du behöver komma ihåg när du väljer säkerhetsverktyg
Ett exempel på sådan kryptering i MongoDB

Säkerhetsfunktioner i kommersiella och öppen källkod DBMS

funktioner
Typ
Lösenordspolicy
Revision
Skydda källkoden för procedurer och funktioner
RLS
kryptering

Oracle
kommersiell
+
+
+
+
+

MsSql
kommersiell
+
+
+
+
+

Jatoba
kommersiell
+
+
+
+
förlängningar

PostgreSQL
Fri
förlängningar
förlängningar
-
+
förlängningar

MongoDb
Fri
-
+
-
-
Endast tillgängligt i MongoDB Enterprise

Tabellen är långt ifrån komplett, men situationen är denna: i kommersiella produkter har säkerhetsproblem lösts under lång tid, i öppen källkod används som regel någon form av tillägg för säkerhet, många funktioner saknas , ibland måste man lägga till något. Till exempel lösenordspolicyer - PostgreSQL har många olika tillägg (1, 2, 3, 4, 5), som implementerar lösenordspolicyer, men enligt min mening täcker ingen av dem alla behoven hos det inhemska företagssegmentet.

Vad du ska göra om du inte har det du behöver någonstans? Till exempel vill du använda ett specifikt DBMS som inte har de funktioner som kunden kräver.

Då kan du använda tredjepartslösningar som fungerar med olika DBMS, till exempel Crypto DB eller Garda DB. Om vi ​​pratar om lösningar från det inhemska segmentet, så känner de till GOST bättre än i öppen källkod.

Det andra alternativet är att skriva vad du behöver själv, implementera dataåtkomst och kryptering i applikationen på procedurnivå. Det är sant att det blir svårare med GOST. Men generellt sett kan du dölja datan efter behov, lägga in det i ett DBMS, sedan hämta det och dekryptera det efter behov, direkt på applikationsnivå. Tänk samtidigt omedelbart på hur du ska skydda dessa algoritmer i applikationen. Enligt vår mening bör detta göras på DBMS-nivå, eftersom det kommer att fungera snabbare.

Denna rapport presenterades först kl @Databas Meetup av Mail.ru Cloud Solutions. Se video andra föreställningar och prenumerera på evenemangsmeddelanden på Telegram Runt Kubernetes på Mail.ru Group.

Vad mer att läsa om ämnet:

  1. Mer än Ceph: MCS molnblocklagring.
  2. Hur man väljer en databas för ett projekt så att du inte behöver välja igen.

Källa: will.com

Lägg en kommentar