Шифроване в MySQL: Keystore

В очакване на началото на ново записване за курса "База данни" Подготвили сме превод на полезна статия за вас.

Шифроване в MySQL: Keystore

Transparent Data Encryption (TDE) се появи в Percona сървър за MySQL и MySQL от доста време. Но замисляли ли сте се как работи под капака и какво влияние може да има TDE върху вашия сървър? В тази поредица от статии ще разгледаме как TDE работи вътрешно. Нека започнем със съхранението на ключове, тъй като това е необходимо, за да работи всяко криптиране. След това ще разгледаме по-отблизо как работи криптирането в Percona Server за MySQL/MySQL и какви допълнителни функции има Percona Server за MySQL.

Ключодържател MySQL

Keyring са добавки, които позволяват на сървъра да прави заявки, да създава и изтрива ключове в локален файл (keyring_file) или на отдалечен сървър (като HashiCorp Vault). Ключовете винаги се кешират локално, за да се ускори тяхното извличане.

Приставките могат да бъдат разделени на две категории:

  • Локално съхранение. Например локален файл (наричаме това базиран на файл ключодържател).
  • Отдалечено съхранение. Например Vault Server (наричаме това сървърно-базиран ключодържател).

Това разделяне е важно, тъй като различните типове хранилища се държат малко по-различно, не само когато съхраняват и извличат ключове, но и когато ги изпълняват.

Когато използвате файлово хранилище, при стартиране цялото съдържание на хранилището се зарежда в кеша: идентификатор на ключ, потребител на ключ, тип ключ и самият ключ.

В случай на хранилище от страна на сървъра (като Vault Server), само идентификаторът на ключа и потребителят на ключа се зареждат при стартиране, така че получаването на всички ключове не забавя стартирането. Ключовете се зареждат лениво. Тоест самият ключ се зарежда от Vault само когато наистина е необходим. Веднъж изтеглен, ключът се кешира в паметта, така че да не е необходимо да бъде достъпван чрез TLS връзки към сървъра на Vault в бъдеще. След това нека да разгледаме каква информация присъства в хранилището на ключове.

Ключовата информация съдържа следното:

  • идентификатор на ключ — ключов идентификатор, например:
    INNODBKey-764d382a-7324-11e9-ad8f-9cb6d0d5dc99-1
  • тип ключ — тип ключ въз основа на използвания алгоритъм за криптиране, възможни стойности: „AES“, „RSA“ или „DSA“.
  • дължина на ключа — дължина на ключа в байтове, AES: 16, 24 или 32, RSA 128, 256, 512 и DSA 128, 256 или 384.
  • потребител - собственик на ключа. Ако ключът е системен, например Master Key, това поле е празно. Ако ключът е създаден с помощта на keyring_udf, тогава това поле идентифицира собственика на ключа.
  • самият ключ

Ключът се идентифицира уникално от двойката: key_id, потребител.

Има и разлики в съхраняването и изтриването на ключове.

Съхранението на файлове е по-бързо. Може би си мислите, че хранилището на ключове просто записва ключа във файл веднъж, но не, тук се случва нещо повече. Всеки път, когато се прави промяна на файловото хранилище, първо се създава резервно копие на цялото съдържание. Да кажем, че файлът се нарича my_biggest_secrets, тогава резервното копие ще бъде my_biggest_secrets.backup. След това кешът се променя (добавят се или се изтриват ключове) и ако всичко е успешно, кешът се нулира във файл. В редки случаи, като повреда на сървъра, може да видите този архивен файл. Архивният файл се изтрива при следващото зареждане на ключовете (обикновено след рестартиране на сървъра).

Когато записвате или изтривате ключ в сървърно хранилище, хранилището трябва да се свърже с MySQL сървъра с командите „изпратете ключа“ / „искайте изтриване на ключ“.

Да се ​​върнем към скоростта на стартиране на сървъра. В допълнение към факта, че скоростта на стартиране се влияе от самия хранилище, съществува и проблемът колко ключове от хранилището трябва да бъдат извлечени при стартиране. Разбира се, това е особено важно за сървърното съхранение. При стартиране сървърът проверява кой ключ е необходим за криптирани таблици/пространства за таблици и изисква ключа от хранилището. На „чист“ сървър с криптиране на главен ключ трябва да има един главен ключ, който трябва да бъде извлечен от хранилището. Въпреки това може да се изисква по-голям брой ключове, например когато резервният сървър възстановява резервно копие от основния сървър. В такива случаи трябва да се осигури ротация на главния ключ. Това ще бъде разгледано по-подробно в бъдещи статии, въпреки че тук бих искал да отбележа, че стартирането на сървър, използващ множество главни ключове, може да отнеме малко повече време, особено когато се използва хранилище за ключове от страна на сървъра.

Сега нека поговорим малко повече за keyring_file. Когато разработвах keyring_file, също бях загрижен как да проверя за промени в keyring_file, докато сървърът работи. В 5.7 проверката беше извършена въз основа на файлови статистики, което не беше идеалното решение, а в 8.0 беше заменена с контролна сума SHA256.

Първият път, когато стартирате keyring_file, се изчисляват файлови статистики и контролна сума, които се запомнят от сървъра и промените се прилагат само ако съвпадат. Когато файлът се промени, контролната сума се актуализира.

Вече разгледахме много въпроси относно трезорите за ключове. Има обаче друга важна тема, която често се забравя или неразбира: споделянето на ключове между сървърите.

Това, което искам да кажа? Всеки сървър (например Percona Server) в клъстера трябва да има отделно местоположение на Vault Server, в което Percona Server трябва да съхранява своите ключове. Всеки главен ключ, записан в хранилището, съдържа GUID на сървъра Percona в своя идентификатор. Защо е важно? Представете си, че имате само един Vault Server и всички Percona сървъри в клъстера използват този единствен Vault Server. Проблемът изглежда очевиден. Ако всички сървъри на Percona използват главен ключ без уникални идентификатори, като id = 1, id = 2 и т.н., тогава всички сървъри в клъстера ще използват един и същ главен ключ. Това, което предоставя GUID, е разграничението между сървърите. Защо тогава да говорим за споделяне на ключове между сървъри, ако вече съществува уникален GUID? Има още един плъгин - keyring_udf. С този плъгин потребителят на вашия сървър може да съхранява своите ключове на сървъра на Vault. Проблемът възниква, когато потребител създаде ключ на сървър1, например, и след това се опита да създаде ключ със същия идентификатор на сървър2, например:

--server1:
select keyring_key_store('ROB_1','AES',"123456789012345");
1
--1 значит успешное завершение
--server2:
select keyring_key_store('ROB_1','AES',"543210987654321");
1

Изчакайте. И двата сървъра използват един и същ сървър на Vault, не трябва ли функцията keyring_key_store да се провали на server2? Интересното е, че ако се опитате да направите същото на един сървър, ще получите грешка:

--server1:
select keyring_key_store('ROB_1','AES',"123456789012345");
1
select keyring_key_store('ROB_1','AES',"543210987654321");
0

Точно така, ROB_1 вече съществува.

Нека първо обсъдим втория пример. Както казахме по-рано, keyring_vault или всяка друга добавка за keyring кешира всички идентификатори на ключове в паметта. И така, след създаването на нов ключ, ROB_1 се добавя към server1 и в допълнение към изпращането на този ключ към Vault, ключът се добавя и към кеша. Сега, когато се опитаме да добавим същия ключ втори път, keyring_vault проверява дали ключът съществува в кеша и извежда грешка.

В първия случай ситуацията е различна. Server1 и server2 имат отделни кешове. След добавяне на ROB_1 към кеша на ключовете на сървър1 и сървъра на Vault, кешът на ключовете на сървър2 не е синхронизиран. Няма ROB_2 ключ в кеша на server1. Така ключът ROB_1 се записва в keyring_key_store и в сървъра на Vault, който всъщност презаписва (!) предишната стойност. Сега ключът ROB_1 на сървъра на Vault е 543210987654321. Интересното е, че сървърът на Vault не блокира подобни действия и лесно презаписва старата стойност.

Сега можем да разберем защо разделянето на сървъра в Vault може да бъде важно - когато използвате keyring_udf и искате да съхранявате ключове в Vault. Как да постигнете това разделяне на сървър на Vault?

Има два начина за разделяне в Vault. Можете да създадете различни точки на монтиране за всеки сървър или да използвате различни пътища в една и съща точка на монтиране. Това се илюстрира най-добре с примери. Така че нека първо да разгледаме отделните точки на монтиране:

--server1:
vault_url = http://127.0.0.1:8200
secret_mount_point = server1_mount
token = (...)
vault_ca = (...)

--server2:
vault_url = http://127.0.0.1:8200
secret_mount_point = sever2_mount
token = (...)
vault_ca = (...)

Тук можете да видите, че server1 и server2 използват различни точки на монтиране. При разделяне на пътищата конфигурацията ще изглежда така:

--server1:
vault_url = http://127.0.0.1:8200
secret_mount_point = mount_point/server1
token = (...)
vault_ca = (...)
--server2:
vault_url = http://127.0.0.1:8200
secret_mount_point = mount_point/sever2
token = (...)
vault_ca = (...)

В този случай и двата сървъра използват една и съща точка на монтиране "mount_point", но различни пътища. Когато създадете първата тайна на server1, използвайки този път, сървърът на Vault автоматично създава директория „server1“. За server2 всичко е подобно. Когато изтриете последната тайна в mount_point/server1 или mount_point/server2, сървърът на Vault също изтрива тези директории. В случай, че използвате разделяне на пътя, трябва да създадете само една точка на монтиране и да промените конфигурационните файлове, така че сървърите да използват отделни пътища. Точка на монтиране може да бъде създадена чрез HTTP заявка. С помощта на CURL това може да се направи по следния начин:

curl -L -H "X-Vault-Token: TOKEN" –cacert VAULT_CA
--data '{"type":"generic"}' --request POST VAULT_URL/v1/sys/mounts/SECRET_MOUNT_POINT

Всички полета (TOKEN, VAULT_CA, VAULT_URL, SECRET_MOUNT_POINT) съответстват на параметрите на конфигурационния файл. Разбира се, можете да използвате помощните програми на Vault, за да направите същото. Но е по-лесно да автоматизирате създаването на точка на монтиране. Надявам се да намерите тази информация за полезна и ще се видим в следващите статии от тази поредица.

Шифроване в MySQL: Keystore

Прочетете още:

Източник: www.habr.com

Добавяне на нов коментар