Criptare în MySQL: Keystore

În așteptarea începerii unei noi înscrieri la curs "Bază de date" v-am pregătit traducerea unui articol util.

Criptare în MySQL: Keystore

Transparent Data Encryption (TDE) a apărut în Server Percona pentru MySQL și MySQL de ceva timp acum. Dar te-ai gândit vreodată cum funcționează sub capotă și ce impact poate avea TDE asupra serverului tău? În această serie de articole, vom arunca o privire asupra modului în care funcționează TDE intern. Să începem cu stocarea cheilor, deoarece este necesară pentru ca orice criptare să funcționeze. Apoi vom arunca o privire mai atentă asupra modului în care funcționează criptarea în Percona Server pentru MySQL/MySQL și ce caracteristici suplimentare sunt disponibile în Percona Server pentru MySQL.

Breloc MySQL

Keyring-urile sunt pluginuri care permit serverului să interogheze, să creeze și să ștergă chei într-un fișier local (keyring_file) sau pe un server la distanță (de exemplu, în HashiCorp Vault). Cheile sunt întotdeauna stocate în cache local pentru a accelera recuperarea.

Pluginurile pot fi împărțite în două categorii:

  • Stocare locală. De exemplu, un fișier local (numim acest ansamblu de chei bazat pe fișiere).
  • stocare la distanță. De exemplu Vault Server (noi îl numim un breloc de chei bazat pe server).

Această separare este importantă deoarece diferitele tipuri de stocare se comportă ușor diferit nu numai la stocarea și preluarea cheilor, ci și la pornire.

Când utilizați stocarea fișierelor, tot conținutul stocării este încărcat în memoria cache la pornire: id-ul cheii, utilizatorul cheii, tipul cheii și cheia însăși.

În cazul unui magazin back-end (de exemplu, serverul Vault), doar ID-ul cheii și utilizatorul cheii sunt încărcate la pornire, astfel încât obținerea tuturor cheilor nu încetinește pornirea. Cheile sunt încărcate alene. Adică, cheia în sine este încărcată din Vault numai atunci când este cu adevărat necesară. După descărcare, cheia este stocată în cache în memorie, astfel încât pe viitor să nu mai fie nevoie să o accesați prin conexiuni TLS la Vault Server. Apoi, luați în considerare ce informații sunt prezente în depozitul de chei.

Informațiile cheie conțin următoarele:

  • ID-ul cheii - identificatorul cheii, de exemplu:
    INNODBKey-764d382a-7324-11e9-ad8f-9cb6d0d5dc99-1
  • tip cheie - tip cheie bazat pe algoritmul de criptare utilizat, valori posibile: „AES”, „RSA” sau „DSA”.
  • lungimea cheii - lungimea cheii în octeți, AES: 16, 24 sau 32, RSA 128, 256, 512 și DSA 128, 256 sau 384.
  • utilizator este proprietarul cheii. Dacă cheia este o cheie de sistem, cum ar fi cheia principală, atunci acest câmp este gol. Dacă cheia este creată folosind keyring_udf, atunci acest câmp indică proprietarul cheii.
  • cheia în sine

Cheia este identificată în mod unic prin perechea: key_id, user.

Există, de asemenea, diferențe în stocarea și ștergerea cheilor.

Stocarea fișierelor este mai rapidă. S-ar putea să credeți că depozitul de chei este doar o scriere unică a cheii într-un fișier, dar nu este - aici se întâmplă mai multe. Ori de câte ori un fișier de stocare este modificat, se face mai întâi o copie de rezervă a întregului conținut. Să presupunem că fișierul se numește my_biggest_secrets, apoi backup-ul va fi my_biggest_secrets.backup. Apoi, memoria cache este schimbată (cheile sunt adăugate sau eliminate) și, dacă totul are succes, memoria cache este aruncată într-un fișier. În cazuri rare, cum ar fi o blocare a serverului, este posibil să vedeți acest fișier de rezervă. Fișierul de rezervă este șters data viitoare când cheile sunt încărcate (de obicei după repornirea serverului).

La salvarea sau ștergerea unei chei în magazinul de server, magazinul trebuie să se conecteze la serverul MySQL cu comenzile „trimite cheia” / „cerere ștergere cheie”.

Să revenim la viteza de pornire a serverului. Pe lângă faptul că seiful în sine afectează viteza de pornire, există și întrebarea câte chei din seif trebuie să fie obținute la pornire. Desigur, acest lucru este deosebit de important pentru stocarea pe server. La pornire, serverul verifică ce cheie este necesară pentru tabelele/spațiile de tabele criptate și solicită cheia din stocare. Pe un server „curat” cu o cheie principală - trebuie să existe o cheie principală pentru criptare, care trebuie preluată din stocare. Cu toate acestea, pot fi necesare mai multe chei, de exemplu, atunci când o copie de rezervă de pe serverul principal este restaurată pe un server de așteptare. În astfel de cazuri, trebuie furnizată rotația Master Key. Acest lucru va fi discutat mai detaliat în articolele viitoare, deși aici aș dori să remarc faptul că un server care utilizează mai multe chei master poate dura puțin mai mult pentru a porni, mai ales când folosește un depozit de chei de server.

Acum să vorbim puțin mai mult despre keyring_file. Când proiectam fișierul keyring_file, am fost, de asemenea, îngrijorat de cum să verific modificările keyring_file în timp ce serverul rulează. În 5.7, verificarea a fost efectuată pe baza statisticilor fișierelor, ceea ce nu era ideal, iar în 8.0 a fost înlocuită cu o sumă de control SHA256.

Prima dată când este rulat keyring_file, statisticile fișierului și suma de control sunt calculate și reținute de server, iar modificările sunt aplicate numai dacă se potrivesc. Când fișierul se modifică, suma de control este actualizată.

Am abordat deja multe întrebări despre depozitele de chei. Cu toate acestea, există un alt subiect important care este adesea uitat sau înțeles greșit - partajarea cheilor între servere.

Ce vreau să spun? Fiecare server (de exemplu, Percona Server) din cluster trebuie să aibă o locație separată pe Vault Server în care Percona Server trebuie să-și păstreze cheile. Fiecare cheie principală stocată în seif conține GUID-ul serverului Percona în ID-ul său. De ce este important? Imaginați-vă că aveți un singur server Vault și toate serverele Percona din cluster folosesc acest singur server Vault. Problema pare evidentă. Dacă toate serverele Percona au folosit o cheie principală fără identificatori unici, cum ar fi id = 1, id = 2 etc., atunci toate serverele din cluster ar folosi aceeași cheie principală. Aceasta este ceea ce oferă GUID - distincția dintre servere. De ce atunci vorbim despre partajarea cheilor între servere dacă există deja un GUID unic? Există un alt plugin - keyring_udf. Cu acest plugin, un utilizator al serverului dvs. își poate stoca cheile pe serverul Vault. Problema apare atunci când un utilizator creează o cheie, de exemplu, pe server1, și apoi încearcă să creeze o cheie cu același ID pe server2, de exemplu:

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

Aștepta. Ambele servere folosesc același Server Vault, nu ar trebui să eșueze funcția keyring_key_store pe server2? Interesant, dacă încercați să faceți același lucru pe același server, veți primi o eroare:

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

Așa e, ROB_1 există deja.

Să discutăm mai întâi al doilea exemplu. După cum am spus mai devreme, keyring_vault sau orice alt plugin de seif (keyring) memorează toate ID-urile cheilor din memorie. Deci, după crearea unei noi chei, ROB_1 este adăugată la server1 și, pe lângă trimiterea acestei chei la Vault, cheia este adăugată și în cache. Acum, când încercăm să adăugăm aceeași cheie a doua oară, keyring_vault verifică dacă cheia există în cache și afișează o eroare.

În primul caz, situația este diferită. Server1 și server2 au cache separate. După adăugarea ROB_1 la memoria cache a cheilor de pe server1 și la serverul Vault, memoria cache a cheilor de pe server2 nu este sincronizată. Cache-ul de pe server2 nu conține cheia ROB_1. Astfel, cheia ROB_1 este scrisă în keyring_key_store și pe serverul Vault, care de fapt suprascrie (!) valoarea anterioară. Acum cheia ROB_1 de pe serverul Vault este 543210987654321. Interesant, serverul Vault nu blochează astfel de acțiuni și suprascrie cu ușurință vechea valoare.

Acum vedem de ce segregarea pe server în Vault poate fi importantă atunci când utilizați keyring_udf și doriți să stocați cheile în Vault. Cum se oferă o astfel de separare în serverul Vault?

Există două moduri de a partiționa pe Vault. Puteți crea puncte de montare diferite pentru fiecare server sau puteți utiliza căi diferite în cadrul aceluiași punct de montare. Cel mai bun mod de a arăta acest lucru este prin exemple. Deci, să ne uităm mai întâi la punctele de montare individuale:

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

Aici puteți vedea că server1 și server2 folosesc puncte de montare diferite. Cu separarea căilor, configurația va arăta astfel:

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

În acest caz, ambele servere folosesc același punct de montare „mount_point” dar căi diferite. Când creați primul secret pe server1 folosind această cale, serverul Vault creează automat un director „server1”. Pentru server2, totul este la fel. Când ștergeți ultimul secret din mount_point/server1 sau mount_point/server2, serverul Vault șterge și acele directoare. În cazul în care utilizați căi împărțite, trebuie să creați un singur punct de montare și să modificați fișierele de configurare, astfel încât serverele să utilizeze căi separate. Un punct de montare poate fi creat cu o solicitare HTTP. Cu CURL acest lucru se poate face astfel:

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

Toate câmpurile (TOKEN, VAULT_CA, VAULT_URL, SECRET_MOUNT_POINT) corespund parametrilor fișierului de configurare. Desigur, puteți utiliza utilitarele Vault pentru a face același lucru. Dar este mai ușor să automatizezi crearea unui punct de montare. Sper că veți găsi aceste informații utile și ne vedem în următoarele articole din această serie.

Criptare în MySQL: Keystore

Citeste mai mult:

Sursa: www.habr.com

Adauga un comentariu