Kryptering i MySQL: nyckellagring

Inför starten av det nya kursutbudet Databaser har vi förberett en översÀttning av en anvÀndbar artikel.

Kryptering i MySQL: nyckellagring

Transparent datakryptering (Transparent Data Encryption, TDE) introducerades i Percona Server for MySQL och MySQL för ganska lÀnge sedan. Men har du nÄgonsin funderat pÄ hur det fungerar under huven och vilken pÄverkan TDE kan ha pÄ din server? I den hÀr artikelserien kommer vi att titta pÄ hur TDE fungerar internt. Vi börjar med nyckellagring, eftersom det behövs för att allt kryptering ska fungera. DÀrefter kommer vi att titta mer i detalj pÄ hur kryptering fungerar i Percona Server for MySQL / MySQL och vilka extra funktioner som finns i Percona Server for MySQL.

MySQL Keyring

Keyring Àr plugins som lÄter servern begÀra, skapa och ta bort nycklar i en lokal fil (keyring_file) eller pÄ en fjÀrrserver (till exempel i HashiCorp Vault). Nycklarna cachas alltid lokalt för att pÄskynda Ätkomsten.

Plugins kan delas in i tvÄ kategorier:

  • Lokal lagring. Till exempel en lokal fil (vi kallar detta ett filbaserat nyckellager, file-based keyring).
  • FjĂ€rrlagring. Till exempel Vault Server (vi kallar detta ett serverbaserat nyckellager, server-based keyring).

Denna uppdelning Àr viktig eftersom olika typer av lagring beter sig nÄgot olika, inte bara vid lagring och hÀmtning av nycklar, utan ocksÄ vid start.

Vid anvÀndning av filbaserat lager laddas allt innehÄll i lagret vid start i cachen: key id, key user, key type och sjÀlva nyckeln.

I fallet med serverbaserat lager (till exempel Vault-servern) laddas endast key id och key user vid start, sÄ att hÀmtning av alla nycklar inte fördröjer starten. Nycklarna laddas latinskt. Det innebÀr att sjÀlva nyckeln endast laddas frÄn Vault nÀr den faktiskt behövs. Efter att ha laddats cachas nyckeln i minnet för att det i framtiden inte ska behöva göras en TLS-koppling till Vault Server för att hÀmta den. LÄt oss nu titta pÄ vilken information som finns i nyckellagret.

Nyckelinformationen innehÄller följande:

  • key id — nyckelidentifierare, till exempel:
    INNODBKey-764d382a-7324-11e9-ad8f-9cb6d0d5dc99-1
  • key type — nyckeltyp, baserad pĂ„ den anvĂ€nda krypteringsalgoritmen, möjliga vĂ€rden: "AES", "RSA" eller "DSA".
  • key length — nyckellĂ€ngd i byte, AES: 16, 24 eller 32, RSA 128, 256, 512 och DSA 128, 256 eller 384.
  • anvĂ€ndare — nyckelns Ă€gare. Om nyckeln Ă€r systemnyckel, till exempel Master Key, Ă€r detta fĂ€lt tomt. Om nyckeln skapas med hjĂ€lp av keyring_udf, anger detta fĂ€lt nyckelns Ă€gare.
  • nyckeln

Nyckeln identifieras entydigt med ett par: key_id, user.

Det finns ocksÄ skillnader i lagring och borttagning av nycklar.

Fil lagringen Ă€r snabbare. Man kan anta att nyckellagringen Ă€r en enkel engĂ„ngsinmatning av nyckeln i en fil, men sĂ„ Ă€r det inte – hĂ€r sker fler operationer. Vid varje modifiering av fil lagringen skapas först en sĂ€kerhetskopia av allt innehĂ„ll. Anta att filen heter my_biggest_secrets, dĂ„ kommer sĂ€kerhetskopian att heta my_biggest_secrets.backup. DĂ€refter Ă€ndras cachen (nycklar lĂ€ggs till eller tas bort) och om allt gĂ„r bra, Ă„terstĂ€lls cachen till filen. I sĂ€llsynta fall, som vid serverfel, kan du se denna sĂ€kerhetskopia. SĂ€kerhetskopian tas bort vid nĂ€sta laddning av nycklarna (vanligtvis efter omstart av servern).

NÀr en nyckel sparas eller tas bort i serverlagring, mÄste lagringen ansluta till MySQL-servern med kommandona "skicka nyckel" / "begÀra borttagning av nyckel" ("send the key" / "request key deletion").

LÄt oss ÄtergÄ till serverns starttid. Förutom att lagringens hastighet pÄverkar starttiden, finns det ocksÄ frÄgan om hur mÄnga nycklar som behöver hÀmtas frÄn lagringen vid start. Detta Àr sÀrskilt viktigt för serverlagringar. Vid uppstart kontrollerar servern vilken nyckel som krÀvs för de krypterade tabellerna / tabellutrymmena och begÀr nyckeln frÄn lagringen. PÄ en "ren" server med Master Key -kryptering ska det finnas en Master Key som mÄste hÀmtas frÄn lagringen. Det kan dock krÀvas fler nycklar, till exempel nÀr en sÀkerhetskopia ÄterstÀlls frÄn huvudservern till en reservserver. I sÄdana fall bör rotation av Master Key övervÀgas. Detta kommer att diskuteras mer i kommande artiklar, men hÀr skulle jag vilja nÀmna att en server som anvÀnder flera Master Keys kan starta lite lÀngre, sÀrskilt vid anvÀndning av serverlagring av nycklar.

LÄt oss nu prata lite mer om keyring_file. NÀr jag utvecklade keyring_file var jag ocksÄ bekymrad över hur man kontrollerar Àndringar av keyring_file medan servern Àr i drift. I version 5.7 utfördes kontrollen baserat pÄ filens statistik, vilket inte var en idealisk lösning, och i version 8.0 ersattes det med en SHA256-kontrollsumma.

Vid första körning berÀknas statistik för keyring_file och en kontrollsumma, som sparas av servern, och Àndringar tillÀmpas endast om de stÀmmer överens. Vid Àndring av filen uppdateras kontrollsumman.

Vi har redan diskuterat mĂ„nga frĂ„gor om nyckellager. Men det finns ett annat viktigt Ă€mne som ofta glöms bort eller missförstĂ„s – separation av nycklar mellan servrar.

Vad menar jag med detta? Varje server (till exempel Percona Server) i en kluster mĂ„ste ha en separat plats pĂ„ Vault-servern dĂ€r Percona Server ska lagra sina nycklar. I varje Master Key som sparas i lagret finns en GUID för Percona Server inuti dess identifierare. Varför Ă€r detta viktigt? FörestĂ€ll dig att du har en enda Vault-server och alla Percona-servrar i klustret anvĂ€nder denna enda Vault-server. Problemet verkar uppenbart. Om alla Percona-servrar anvĂ€nde Master Key utan unika identifierare, till exempel id = 1, id = 2 osv., skulle alla servrar i klustret anvĂ€nda samma Master Key. Vad som sĂ€kerstĂ€lls av GUID — avgrĂ€nsning mellan servrar. Varför prata dĂ„ om separation av nycklar mellan servrar nĂ€r det redan finns en unik GUID? Det finns en annan plugin — keyring_udf. Med denna plugin kan anvĂ€ndaren av din server lagra sina nycklar pĂ„ Vault-servern. Problemet uppstĂ„r nĂ€r anvĂ€ndaren skapar en nyckel, till exempel pĂ„ server server1, och sedan försöker skapa en nyckel med samma identifierare pĂ„ server2.

--server1:
select keyring_key_store('ROB_1','AES',"123456789012345");
1
--1 betyder lyckad avslutning
--server2:
select keyring_key_store('ROB_1','AES',"543210987654321");
1

VÀnta. BÄda servrarna anvÀnder samma Vault-server, borde inte funktionen keyring_key_store avslutas med ett fel pÄ server server2? Intressant nog, om du försöker göra samma sak pÄ en och samma server, fÄr du ett fel:

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

RĂ€tt, ROB_1 finns redan.

LÄt oss först diskutera det andra exemplet. Som vi tidigare nÀmnt, cache:ar keyring_vault eller vilken annan lagringsplugin (keyring) alla nyckelidentifierare i minnet. SÄ, efter att en nyckel skapats, lÀggs ROB_1 till pÄ server1, och förutom att skicka denna nyckel till Vault, lÀggs nyckeln ocksÄ till i cachen. Nu, nÀr vi försöker lÀgga till samma nyckel en andra gÄng, kontrollerar keyring_vault om denna nyckel redan finns i cachen och ger ett felmeddelande.

I det första fallet Àr situationen en annan. PÄ servrarna server1 och server2 finns separata cacher. Efter att ha lagt till ROB_1 i cache:en av nycklar pÄ server1 och server Vault, Àr nyckelcachen pÄ server2 inte synkroniserad. I cachen pÄ server2 finns det ingen nyckel ROB_1. SÄledes skrivs nyckeln ROB_1 in i keyring_key_store och pÄ server Vault, vilket faktiskt skriver över (!) det tidigare vÀrdet. Nu Àr nyckeln ROB_1 pÄ server Vault lika med 543210987654321. Det Àr intressant att server Vault inte blockerar sÄdana ÄtgÀrder och enkelt skriver över det gamla vÀrdet.

Nu ser vi varför uppdelningen över servrar pĂ„ Vault kan vara viktig — nĂ€r du anvĂ€nder keyring_udf och vill lagra nycklar i Vault. Hur sĂ€kerstĂ€ller man en sĂ„dan uppdelning pĂ„ server Vault?

Det finns tvÄ sÀtt att uppdelning pÄ Vault. Man kan skapa olika monteringspunkter för varje server eller anvÀnda olika sökvÀgar inom en och samma monteringspunkt. Det Àr bÀst att visa detta med exempel. SÄ, lÄt oss först titta pÄ separata monteringspunkter:

--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 = (...)

HÀr ser vi att server1 och server2 anvÀnder olika monteringspunkter. Vid uppdelning av sökvÀgar skulle konfigurationen se ut pÄ följande sÀtt:

--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 = (...)

I det hÀr fallet anvÀnder bÄda servrarna samma monteringspunkt "mount_point", men olika sökvÀgar. NÀr den första hemligheten skapas pÄ servern server1 pÄ denna vÀg skapar Vault-servern automatiskt katalogen "server1". För server2 Àr allt likadant. NÀr du tar bort den sista hemligheten i mount_point/server1 eller mount_point/server2, tar Vault-servern ocksÄ bort dessa kataloger. Om du anvÀnder separering av sökvÀgar mÄste du skapa endast en monteringspunkt och Àndra konfigurationsfilerna sÄ att servrarna anvÀnder separata sökvÀgar. Monteringspunkten kan skapas med en HTTP-förfrÄgan. Med CURL kan detta göras pÄ följande sÀtt:

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

Alla fÀlt (TOKEN, VAULT_CA, VAULT_URL, SECRET_MOUNT_POINT) motsvarar parametrarna i konfigurationsfilen. SjÀlvklart kan du anvÀnda Vault-verktyg för att göra samma sak. Men det Àr lÀttare att automatisera skapandet av monteringspunkten. Jag hoppas att denna information Àr anvÀndbar för dig, och vi ses i nÀsta artiklar i den hÀr serien.

Kryptering i MySQL: nyckellagring

LĂ€s mer:

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster