Енкрипција во MySQL: Keystore

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

Енкрипција во MySQL: Keystore

Транспарентно шифрирање на податоци (TDE) се појави во Перкона сервер за 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 серверот во кој Percona Server мора да ги складира своите клучеви. Секој главен клуч зачуван во складиштето го содржи GUID на серверот Percona во неговиот идентификатор. Зошто е важно? Замислете дека имате само еден Vault Server и сите Percona сервери во кластерот го користат тој единствен Vault Server. Проблемот изгледа очигледен. Ако сите сервери на Percona користеле главен клуч без единствени идентификатори, како што се id = 1, id = 2, итн., тогаш сите сервери во кластерот би го користеле истиот главен клуч. Она што го обезбедува GUID е разликата помеѓу серверите. Зошто тогаш да зборуваме за споделување клучеви помеѓу серверите ако веќе постои единствен GUID? Постои уште еден приклучок - keyring_udf. Со овој приклучок, корисникот на вашиот сервер може да ги складира своите клучеви на серверот Vault. Проблемот се јавува кога корисникот создава клуч на серверот1, на пример, и потоа се обидува да создаде клуч со истиот ID на серверот2, на пример:

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

Чекај. Двата сервери користат ист Vault Server, не треба ли функцијата 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 или кој било друг приклучок за клучеви ги кешира сите ID на клучеви во меморијата. Така, по креирањето на нов клуч, ROB_1 се додава на серверот1, а покрај испраќањето на овој клуч до Vault, клучот се додава и во кешот. Сега, кога се обидуваме да го додадеме истиот клуч по втор пат, keyring_vault проверува дали клучот постои во кешот и фрла грешка.

Во првиот случај ситуацијата е поинаква. Server1 и server2 имаат посебни кешови. По додавањето ROB_1 во кешот на клучеви на серверот1 и серверот Vault, кешот на клучеви на серверот2 не е синхронизиран. Нема клуч ROB_2 во кешот на серверот1. Така, клучот 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“, но различни патеки. Кога ја креирате првата тајна на серверот 1 користејќи ја оваа патека, серверот Vault автоматски создава директориум „сервер1“. За 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

Додадете коментар