Бяспека і СКБД: пра што трэба памятаць, падбіраючы сродкі абароны

Бяспека і СКБД: пра што трэба памятаць, падбіраючы сродкі абароны

Мяне клічуць Дзяніс Ражкоў, я кіраўнік распрацоўкі ПЗ у кампаніі «Газінфармсэрвіс», у камандзе прадукта Ятоба. Заканадаўства і карпаратыўныя нормы накладваюць пэўныя патрабаванні да бяспекі захоўвання дадзеных. Ніхто не хоча, каб трэція асобы атрымалі доступ да канфідэнцыйнай інфармацыі, таму для любога праекта важны наступныя пытанні: ідэнтыфікацыя і аўтэнтыфікацыя, кіраванне доступамі да дадзеных, забеспячэнне цэласнасці інфармацыі ў сістэме, рэгістрацыя падзей бяспекі. Таму я хачу расказаць пра некаторыя цікавыя моманты, якія тычацца бяспекі СКБД.

Артыкул падрыхтаваны па выступленні на @Databases Meetup, арганізаваным Mail.ru Cloud Solutions. Калі не жадаеце чытаць, можна паглядзець:


У артыкуле будзе тры часткі:

  • Як абараняць падключэнні.
  • Што такое аўдыт дзеянняў і як фіксаваць, што адбываецца з боку базы дадзеных і падключэння да яе.
  • Як абараняць дадзеныя ў самой базе даных і якія для гэтага ёсць тэхналогіі.

Бяспека і СКБД: пра што трэба памятаць, падбіраючы сродкі абароны
Тры складнікі бяспекі СКБД: абарона падлучэнняў, аўдыт дзеянняў і абарона дадзеных

Абарона падлучэнняў

Падлучацца да базы дадзеных можна як наўпрост, так і апасродкавана праз вэб-прыкладанні. Як правіла, карыстач са боку бізнэсу, гэта значыць чалавек, які працуе з СКБД, узаемадзейнічае з ёй не напроста.

Перад тым як казаць аб абароне злучэнняў, трэба адказаць на важныя пытанні, ад якіх залежыць, як будуць выбудоўвацца мерапрыемствы бяспекі:

  • ці эквівалентны адзін бізнэс-карыстальнік аднаму карыстачу СКБД;
  • ці забяспечваецца доступ да дадзеных СКБД толькі праз API, які вы кантралюеце, альбо ёсць доступ да табліц напрамую;
  • ці выдзелена СКБД у асобны абаронены сегмент, хто і як з ім узаемадзейнічае;
  • ці выкарыстоўваецца pooling/proxy і прамежкавыя пласты, якія могуць змяняць інфармацыю аб тым, як выбудавана падлучэнне і хто выкарыстоўвае базу дадзеных.

Цяпер паглядзім, якія прылады можна ўжыць для абароны падлучэнняў:

  1. Выкарыстоўвайце рашэнні класа database firewall. Дадатковы пласт абароны, як мінімум, павысіць празрыстасць таго, што адбываецца ў СКБД, як максімум - вы зможаце забяспечыць дадатковую абарону дадзеных.
  2. Выкарыстоўвайце парольныя палітыкі. Іх ужыванне залежыць ад таго, як выбудавана ваша архітэктура. У любым выпадку - аднаго пароля ў канфігурацыйным файле вэб-прыкладанні, якое падлучаецца да СКБД, мала для абароны. Ёсць шэраг прылад СКБД, якія дазваляюць кантраляваць, што карыстач і пароль патрабуюць актуалізацыі.

    Пачытаць падрабязней пра функцыі адзнакі карыстальнікаў можна тут, гэтак жа пра MS SQL Vulnerability Assessmen можна пазнаць тут

  3. Абагачайце кантэкст сесіі патрэбнай інфармацыяй. Калі сесія непразрыстая, вы не разумееце, хто ў яе рамках працуе ў СКБД, можна ў рамках выкананай аперацыі дапоўніць інфармацыю аб тым, хто, што і навошта робіць. Гэтую інфармацыю можна ўбачыць у аўдыце.
  4. Настройвайце SSL, калі ў вас няма сеткавага размежавання СКБД ад канчатковых карыстальнікаў, яна не ў асобным VLAN. У такіх выпадках абавязкова абараняць канал паміж спажыўцом і самой СКБД. Інструменты абароны ёсць у тым ліку і сярод open source.

Як гэта паўплывае на прадукцыйнасць СКБД?

Паглядзім на прыкладзе PostgreSQL, як SSL уплывае на нагрузку CPU, павелічэнне таймінгаў і памяншэнне TPS, ці не сыдзе ці занадта шмат рэсурсаў, калі яго ўключыць.

Нагружаем PostgreSQL, выкарыстоўваючы pgbench - гэта простая праграма для запуску тэстаў прадукцыйнасці. Яна шматкроць выконвае адну паслядоўнасць каманд, магчыма ў раўналежных сеансах базы дадзеных, а затым вылічае сярэднюю хуткасць транзакцый.

Тэст 1 без SSL і з выкарыстаннем SSL - злучэнне ўсталёўваецца пры кожнай транзакцыі:

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"

Тэст 2 без SSL і з выкарыстаннем SSL - усе транзакцыі выконваюцца ў адно злучэнне:

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"

Астатнія наладкі:

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

вынікі тэставання:

 
NO SSL
SSL

Устанаўліваецца злучэнне пры кожнай транзакцыі

latency average
171.915 мс
187.695 мс

tps including connections establishing
58.168112
53.278062

tps excluding connections establishing
64.084546
58.725846

CPU
24%
28%

Усе транзакцыі выконваюцца ў адно злучэнне

latency average
6.722 мс
6.342 мс

tps including connections establishing
1587.657278
1576.792883

tps excluding connections establishing
1588.380574
1577.694766

CPU
17%
21%

Пры невялікіх нагрузках уплыў SSL супастаўна з хібнасцю вымярэння. Калі аб'ём перадаваных дадзеных вельмі вялікі, сітуацыя можа быць іншая. Калі мы ўсталёўваем адно злучэнне на кожную транзакцыю (гэта бывае рэдка, звычайна злучэнне дзеляць паміж карыстальнікамі), у вас вялікая колькасць падлучэнняў/адключэнняў, уплыў можа быць крыху больш. Гэта значыць рызыкі зніжэння прадукцыйнасці могуць быць, аднак, розніца не настолькі вялікая, каб не выкарыстоўваць абарону.

Звярніце ўвагу - моцнае адрозненне ёсць, калі параўноўваць рэжымы працы: у рамках адной сесіі вы працуеце або розных. Гэта зразумела: на стварэнне кожнага злучэння марнуюцца рэсурсы.

У нас быў кейс, калі мы падлучалі Zabbix у рэжыме trust, гэта значыць md5 не правяралі, у аўтэнтыфікацыі не было неабходнасці. Потым замовец папытаў улучыць рэжым md5-аўтэнтыфікацыі. Гэта дало вялікую нагрузку на CPU, прадукцыйнасць асела. Пачалі шукаць шляхі аптымізацыі. Адно з магчымых рашэнняў праблемы - рэалізаваць сеткавае абмежаванне, зрабіць для СКБД асобныя VLAN, дадаць налады, каб было зразумела, хто і адкуль падключаецца і прыбраць аўтэнтыфікацыю. Таксама можна аптымізаваць налады аўтэнтыфікацыі, каб знізіць выдаткі пры ўключэнні аўтэнтыфікацыі, але ў цэлым ужыванне розных метадаў аўтэнтыфікацыі ўплывае на прадукцыйнасць і патрабуе ўлічваць гэтыя фактары пры праектаванні вылічальных магутнасцяў сервераў (жалеза) для СКБД.

Выснова: у шэрагу рашэнняў нават невялікія нюансы на аўтэнтыфікацыі могуць моцна адбіцца на праекце і дрэнна, калі гэта становіцца зразумела толькі пры ўкараненні ў прадуктыў.

Аўдыт дзеянняў

Аўдыт можа быць не толькі СКБД. Аўдыт - гэта атрыманне інфармацыі аб тым, што адбываецца на розных сегментах. Гэта можа быць і database firewall, і аперацыйная сістэма, на якой будуецца СКБД.

У камерцыйных СКБД ўзроўню Enterprise з аўдытам усё добра, у open source – не заўсёды. Вось, што ёсць у PostgreSQL:

  • default log - убудаванае лагіраванне;
  • extensions: pgaudit - калі вам бракуе дэфолтнага лагавання, можна скарыстацца асобнымі наладамі, якія вырашаюць частку задач.

Дадатак да дакладу ў відэа:

«Базавая рэгістрацыя аператараў можа быць забяспечана стандартным сродкам вядзення часопіса з log_statement = all.

Гэта прымальна для маніторынгу і іншых відаў выкарыстання, але не забяспечвае ўзровень дэталізацыі, звычайна неабходны для аўдыту.

Недастаткова мець спіс усіх аперацый, якія выконваюцца з базай дадзеных.

Таксама павінна быць магчымасць знайсці канкрэтныя сцвярджэнні, якія ўяўляюць цікавасць для аўдытара.

Стандартны сродак вядзення часопіса паказвае тое, што запытаў карыстач, у той час як pgAudit факусуецца на дэталях таго, што адбылося, калі база дадзеных выконвала запыт.

Напрыклад, аўдытар можа захацець пераканацца, што канкрэтная табліца была створана ў задакументаваным акне абслугоўвання.

Гэта можа здацца простай задачай для базавага аўдыту і grep, але што, калі вам прадставіцца нешта накшталт гэтага (наўмысна заблытанага) прыкладу:

DO $$
ПАЧАЦЬ
EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
END $$;

Стандартнае вядзенне часопіса дасць вам гэта:

LOG: statement: DO $$
ПАЧАЦЬ
EXECUTE 'CREATE TABLE import' || 'ant_table (id INT)';
END $$;

Падобна, што для пошуку якая цікавіць табліцы можа запатрабавацца некаторае веданне кода ў тых выпадках, калі табліцы ствараюцца дынамічна.

Гэта не ідэальна, бо было б пераважней проста шукаць па імі табліцы.

Вось дзе будзе карысны pgAudit.

Для таго ж самага ўводу ён выдасць гэтую выснову ў часопісе:

AUDIT: SESSION,33,1,FUNCTION,DO,,,«DO $$
ПАЧАЦЬ
EXECUTE '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)

Рэгіструецца не толькі блок DO, але і поўны тэкст CREATE TABLE з тыпам аператара, тыпам аб'екта і поўным імем, што палягчае пошук.

Пры вядзенні часопіса аператараў SELECT і DML pgAudit можна наладзіць для рэгістрацыі асобнага запісу для кожнага стаўлення, на якое ёсць спасылка ў аператары.

Не патрабуецца сінтаксічны аналіз, каб знайсці ўсе аператары, якія датычацца канкрэтнай табліцы(*) ».

Як гэта паўплывае на прадукцыйнасць СКБД?

Давайце правядзём тэсты з уключэннем поўнага аўдыту і паглядзім, што будзе з прадукцыйнасцю PostgreSQL. Уключым максімальнае лагіраванне БД па ўсіх параметрах.

У канфігурацыйным файле амаль нічога не змяняем, з важнага - уключаем рэжым debug5, каб атрымаць максімум інфармацыі.

postgresql.conf

log_destination = 'stderr'
logging_collector = on
log_truncate_on_rotation = on
log_rotation_age = 1d
log_rotation_size = 10MB
log_min_messages = debug5
log_min_error_statement = debug5
log_min_duration_statement = 0
debug_print_parse = on
debug_print_rewritten = on
debug_print_plan = on
debug_pretty_print = on
log_checkpoints = on
log_connections = on
log_disconnections = on
log_duration = on
log_hostname = on
log_lock_waits = on
log_replication_commands = on
log_temp_files = 0
log_timezone = 'Europe/Moscow'

На СКБД PostgreSQL з параметрамі 1 CPU, 2,8 Ггц, 2 Гб АЗП, 40 Гб HDD праводзім тры нагрузачных тэсту, выкарыстоўваючы каманды:

$ 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

Вынікі тэсціравання:

Без лагіравання
З лагіраваннем

Выніковы час напаўнення БД
43,74 сек
53,23 сек

АЗП
24%
40%

CPU
72%
91%

Тэст 1 (50 канэктаў)

Коль-ць транзакцый за 10 мін
74169
32445

Транзакцый/сек
123
54

Сярэдняя затрымка
405 мс
925 мс

Тэст 2 (150 канэктаў пры 100 магчымых)

Коль-ць транзакцый за 10 мін
81727
31429

Транзакцый/сек
136
52

Сярэдняя затрымка
550 мс
1432 мс

Пра памеры

Памер БД
2251 МБ
2262 МБ

Памер логаў БД
0 Мб
4587 Мб

У выніку: поўны аўдыт - гэта не вельмі добра. Дадзеных ад аўдыту атрымаецца па аб'ёме, як дадзеных у самой базе даных, а то і больш. Такі аб'ём часопісавання, які генеруецца пры працы з СКБД, - звычайная праблема на прадуктыве.

Глядзім іншыя параметры:

  • Хуткасць моцна не мяняецца: без лагіравання - 43,74 сек, з лагіраваннем - 53,23 сек.
  • Прадукцыйнасць па АЗП і CPU будзе прасядаць, бо трэба сфармаваць файл з аўдытам. Гэта таксама прыкметна на прадуктыве.

Пры павелічэнні колькасці канэктаў, натуральна, паказчыкі будуць крыху пагаршацца.

У карпарацыях з аўдытам яшчэ складаней:

  • дадзеных шмат;
  • аўдыт патрэбен не толькі праз syslog у SIEM, але і ў файлы: раптам з syslog нешта адбудзецца, павінен быць блізка да базы файл, у якім захаваюцца дадзеныя;
  • для аўдыту патрэбна асобная паліца, каб не прасесці па I/O дыскаў, бо ён займае шмат месца;
  • бывае, што супрацоўнікам ИБ патрэбныя ўсюды Дасты, яны патрабуюць гасцёўню ідэнтыфікацыю.

Абмежаванне доступу да дадзеных

Паглядзім на тэхналогіі, якія выкарыстоўваюць для абароны дадзеных і доступу да іх у камерцыйных СКБД і open source.

Што ў цэлым можна выкарыстоўваць:

  1. Шыфраванне і обфускация працэдур і функцый (Wrapping) - гэта значыць асобныя прылады і ўтыліты, якія з чытэльнага кода робяць нечытэльны. Праўда, потым яго нельга ні памяняць, ні зарэфактарыць назад. Такі падыход часам патрабуецца як мінімум на баку СКБД - логіка ліцэнзійных абмежаванняў або логіка аўтарызацыі шыфруецца менавіта на ўзроўні працэдуры і функцыі.
  2. Абмежаванне бачнасці дадзеных па радках (RLS) - гэта калі розныя карыстачы бачаць адну табліцу, але розны склад радкоў у ёй, гэта значыць камусьці штосьці нельга паказваць на ўзроўні радкоў.
  3. Рэдагаванне якія адлюстроўваюцца дадзеных (Masking) - гэта калі карыстачы ў адной калонцы табліцы бачаць ці дадзеныя, ці толькі зорачкі, гэта значыць для нейкіх карыстачоў інфармацыя будзе зачыненая. Тэхналогія вызначае, якому карыстачу што паказваць з улікам узроўня доступу.
  4. Размежаванне доступу Security DBA / Application DBA / DBA – гэта, хутчэй, пра абмежаванне доступу да самой СКБД, гэта значыць супрацоўнікаў ИБ можна аддзяліць ад database-адміністратараў і application-адміністратараў. У open source такіх тэхналогій няшмат, у камерцыйных СКБД іх хапае. Яны патрэбныя, калі шмат карыстальнікаў з доступам да саміх сервераў.
  5. Абмежаванне доступу да файлаў на ўзроўні файлавай сістэмы. Можна выдаваць правы, прывілеі доступу да каталогаў, каб кожны адміністратар атрымліваў доступ толькі да патрэбных дадзеных.
  6. Мандатны доступ і ачыстка памяці - гэтыя тэхналогіі ўжываюць рэдка.
  7. End-to-end encryption непасрэдна СКБД - гэта client-side шыфраванне з кіраваннем ключамі на серверным боку.
  8. Шыфраванне дадзеных. Напрыклад, калонкавае шыфраванне - калі вы выкарыстоўваеце механізм, які шыфруе асобную калонку базы.

Як гэта ўплывае на прадукцыйнасць СКБД?

Паглядзім на прыкладзе калонкавага шыфравання ў PostgreSQL. Там ёсць модуль pgcrypto, ён дазваляе ў зашыфраваным выглядзе захоўваць абраныя палі. Гэта карысна, калі каштоўнасць уяўляюць толькі некаторыя дадзеныя. Каб прачытаць зашыфраваныя палі, кліент перадае які дэшыфруе ключ, сервер расшыфроўвае дадзеныя і выдае іх кліенту. Без ключа з вашымі дадзенымі ніхто нічога не зможа зрабіць.

Правядзем тэст з pgcrypto. Створым табліцу з зашыфраванымі дадзенымі і са звычайнымі дадзенымі. Ніжэй каманды для стварэння табліц, у самым першым радку карысная каманда - стварэнне самога extension з рэгістрацыяй СКБД:

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

Далей паспрабуем зрабіць з кожнай табліцы выбарку дадзеных і паглядзім на таймінгі выканання.

Выбарка з табліцы без функцыі шыфравання:

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

Секундамер уключаны.

  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 радкоў)

Час: 1,386 мс

Выбарка з табліцы з функцыяй шыфравання:

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

Секундамер уключаны.

  id | decrypt | decrypt
——+—————+————
1 | x31 | x31
2 | x32 | x32
3 | x33 | x33
...
999 | x393939 | x393939
1000 | x31303030 | x31303030
(1000 радкоў)

Час: 50,203 мс

вынікі тэставання:

 
Без шыфравання
Pgcrypto (decrypt)

Выбарка 1000 радкоў
1,386 мс
50,203 мс

CPU
15%
35%

АЗП
 
+ 5%

Шыфраванне моцна ўплывае на прадукцыйнасць. Відаць, што вырас таймінг, бо аперацыі дэшыфрацыі зашыфраваных дадзеных (а дэшыфрацыя звычайна яшчэ абгорнутая ў вашу логіку) патрабуюць значных рэсурсаў. Гэта значыць ідэя зашыфраваць усе калонкі, якія змяшчаюць нейкія дадзеныя, багатая зніжэннем прадукцыйнасці.

Пры гэтым шыфраванне не сярэбраная куля, якая вырашае ўсе пытанні. Расшыфраваныя дадзеныя і ключ дэшыфравання падчас расшыфроўванні і перадачы дадзеных знаходзяцца на серверы. Таму ключы могуць быць перахоплены тым, хто мае поўны доступ да сервера баз даных, напрыклад сістэмным адміністратарам.

Калі на ўсю калонку для ўсіх карыстальнікаў адзін ключ (нават калі не для ўсіх, а для кліентаў абмежаванага набору), - гэта не заўсёды добра і правільна. Менавіта таму пачалі рабіць end-to-end шыфраванне, у СКБД сталі разглядаць варыянты шыфравання дадзеных з боку кліента і сервера, з'явіліся тыя самыя key-vault сховішчы – асобныя прадукты, якія забяспечваюць кіраванне ключамі на баку СКБД.

Бяспека і СКБД: пра што трэба памятаць, падбіраючы сродкі абароны
Прыклад такога шыфравання ў MongoDB

Сродкі бяспекі ў камерцыйных і open source СКБД

функцыі
Тып
Палітыка пароляў
Аўдыт
Абарона зыходнага кода працэдур і функцый
RLS
Шыфраванне

Аракул
камерцыйная
+
+
+
+
+

MsSql
камерцыйная
+
+
+
+
+

Ятоба
камерцыйная
+
+
+
+
Пашырэння

PostgreSQL
Free
Пашырэння
Пашырэння
-
+
Пашырэння

MongoDB
Free
-
+
-
-
Available in MongoDB Enterprise толькі

Табліца далёка не поўная, але сітуацыя такая: у камерцыйных прадуктах задачы бяспекі вырашаюцца даўно, у open source, як правіла, для бяспекі выкарыстоўваюць нейкія надбудовы, шматлікіх функцый бракуе, часам даводзіцца нешта дапісваць. Напрыклад, парольныя палітыкі - у PostgreSQL шмат розных пашырэнняў (1, 2, 3, 4, 5), якія рэалізуюць парольныя палітыкі, але ўсе патрэбы айчыннага карпаратыўнага сегмента, на мой погляд, ні адно не пакрывае.

Што рабіць, калі нідзе няма таго, што трэба? Напрыклад, хочацца выкарыстоўваць пэўную СКБД, у якой няма функцый, якія патрабуе заказчык.

Тады можна выкарыстоўваць іншыя рашэнні, якія працуюць з рознымі СКБД, напрыклад, «Крыпта БД» або «Гарда БД». Калі гаворка аб рашэннях з айчыннага сегмента, то там пра Дасты ведаюць лепш, чым у open source.

Другі варыянт - самастойна напісаць, што трэба, рэалізаваць на ўзроўні працэдур доступ да дадзеных і шыфраванне ў дадатку. Праўда, з ДАСТам будзе складаней. Але ў цэлым - вы можаце схаваць дадзеныя, як трэба, скласці ў СКБД, потым дастаць і расшыфраваць як трэба, прама на ўзроўні application. Пры гэтым адразу думайце, як вы будзеце гэтыя алгарытмы на application абараняць. На наш погляд, гэта трэба рабіць на ўзроўні СКБД, бо так будзе працаваць хутчэй.

Гэты даклад упершыню прагучаў на @Databases Meetup by Mail.ru Cloud Solutions. Глядзіце відэа іншых выступаў і падпісвайцеся на анонсы мерапрыемстваў у Telegram Вакол Kubernetes у Mail.ru Group.

Што яшчэ пачытаць па тэме:

  1. Больш чым Ceph: блокавае сховішча аблокі MCS.
  2. Як выбраць базу дадзеных для праекту, каб не выбіраць зноў.

Крыніца: habr.com

Дадаць каментар