Înainte de începerea unui nou grup pentru curs am pregătit pentru tine un traducere a unui articol util.

Criptarea transparentă a datelor (Transparent Data Encryption, TDE) a apărut în și MySQL de ceva vreme. Dar te-ai întrebat vreodată cum funcționează sub capotă și ce influență poate avea TDE asupra serverului tău? În această serie de articole, vom explora cum funcționează TDE în interior. Vom începe cu stocarea cheilor, deoarece aceasta este necesară pentru funcționarea oricărei criptări. Apoi vom analiza în detaliu cum funcționează criptarea în Percona Server for MySQL/MySQL și ce funcționalități suplimentare există în Percona Server for MySQL.
MySQL Keyring
Keyring este un plugin care permite serverului să solicite, să creeze și să elimine chei într-un fișier local (keyring_file) sau pe un server extern (de exemplu, în HashiCorp Vault). Cheile sunt întotdeauna cache-uite local, pentru a accelera obținerea acestora.
Pluginurile pot fi împărțite în două categorii:
- Stocare locală. De exemplu, un fișier local (numim aceasta stocare bazată pe fișiere, file-based keyring).
- Stocare la distanță. De exemplu, Vault Server (numim aceasta stocare bazată pe servere, server-based keyring).
Această împărțire este importantă, deoarece diferite tipuri de stocări se comportă ușor diferit nu doar la stocarea și obținerea cheilor, ci și la pornire.
Atunci când utilizezi o stocare bazată pe fișiere, la pornire se încarcă tot conținutul stocării în cache: key id, key user, key type și cheia în sine.
În cazul unei stocări bazate pe server (de exemplu, serverul Vault), la pornire se încarcă doar key id și key user, astfel încât obținerea tuturor cheilor nu încetinește pornirea. Cheile sunt încărcate oarecum lazy. Adică cheia în sine este ștearsă din Vault doar atunci când este necesară efectiv. După ce a fost încărcată, cheia este cache-uită în memorie, pentru a nu mai necesita accesul prin conexiuni TLS la Vault Server. Să mai vedem ce informații se găsesc în stocarea cheilor.
Informațiile despre cheie conțin următoarele:
- key id — identificatorul cheii, de exemplu:
INNODBKey-764d382a-7324-11e9-ad8f-9cb6d0d5dc99-1 - key type — tipul cheii, bazat pe algoritmul de criptare utilizat, valorile posibile sunt: „AES”, „RSA” sau „DSA”.
- key length — lungimea cheii în octeți, AES: 16, 24 sau 32, RSA 128, 256, 512 și DSA 128, 256 sau 384.
- utilizator — deținătorul cheii. Dacă cheia este sistemică, de exemplu, Master Key, atunci acest câmp este gol. Dacă cheia este creată folosind keyring_udf, atunci acest câmp indică deținătorul cheii.
- cheia în sine
Cheia este identificată în mod clar de perechea: key_id, user.
Există de asemenea diferențe în stocarea și ștergerea cheilor.
Stocarea pe fișiere funcționează mai rapid. Se poate presupune că stocarea cheilor este o simplă înregistrare unică a cheii într-un fișier, dar nu este așa — aici au loc mai multe operațiuni. La orice modificare a stocării pe fișiere, mai întâi se creează o copie de rezervă a întregului conținut. Să presupunem că fișierul se numește my_biggest_secrets, atunci copia de rezervă va fi my_biggest_secrets.backup. Apoi, se modifică memoria cache (se adaugă sau se șterg chei) și, dacă totul decurge cu succes, memoria cache este rescrisă în fișier. În cazuri rare, cum ar fi o defecțiune a serverului, este posibil să vezi acest fișier de rezervă. Fișierul de rezervă este șters la următoarea încărcare a cheilor (de obicei după repornirea serverului).
Atunci când salvezi sau șteri o cheie în stocarea serverului, stocarea trebuie să se conecteze la serverul MySQL cu comenzile „trimite cheie” / „solicită ștergerea cheii” („send the key” / „request key deletion”).
Să ne întoarcem la viteza de pornire a serverului. Pe lângă faptul că viteza de pornire este influențată de stocare în sine, există și întrebarea câte chei din stocare trebuie să fie obținute la pornire. Desigur, acest lucru este deosebit de important pentru stocările serverului. La pornire, serverul verifică ce cheie este necesară pentru tabelele criptate / spațiile de tabele și solicită cheia din stocare. Pe un server „curat” cu criptare Master Key — trebuie să existe o singură Master Key, care trebuie extrasă din stocare. Cu toate acestea, poate fi necesar un număr mai mare de chei, de exemplu, atunci când pe un server de rezervă se restaurează o copie de rezervă de pe serverul principal. În astfel de cazuri, ar trebui prevăzută rotația Master Key. Acest aspect va fi discutat în articolele viitoare, deși aici aș dori să subliniez că un server care utilizează mai multe Master Key poate porni puțin mai lent, în special atunci când folosește stocarea cheilor serverului.
Acum să discutăm puțin despre keyring_file. Când am dezvoltat keyring_file, m-a preocupat, de asemenea, modul de verificare a modificării keyring_file în timpul funcționării serverului. În versiunea 5.7, verificarea se realiza pe baza statisticilor fișierului, ceea ce nu era o soluție ideală, iar în versiunea 8.0 aceasta a fost înlocuită cu suma de control SHA256.
La prima rulare, keyring_file calculează statisticile fișierului și suma de control, care sunt memorate de server, iar modificările sunt aplicate doar dacă acestea coincid. La modificarea fișierului, suma de control este actualizată.
Am discutat deja multe aspecte despre magazinul de chei. Totuși, există o temă importantă pe care mulți o uită sau o înțeleg greșit - separarea cheilor pe servere.
Ce vreau să spun? Fiecare server (de exemplu, Percona Server) din cluster trebuie să aibă un loc separat pe serverul Vault, unde Percona Server își va stoca cheile. Fiecare Master Key salvat în magazin conține GUID-ul serverului Percona Server în interiorul identificatorului său. De ce este important? Imaginează-ți că ai un singur Vault Server și toate Percona Server din cluster folosesc acest singur Vault Server. Problema pare evidentă. Dacă toate Percona Server ar folosi Master Key fără identificatori unici, de exemplu, id = 1, id = 2 etc., atunci toate serverele din cluster ar folosi aceeași Master Key. Iar asta este ceea ce asigură GUID-ul - delimitarea între servere. De ce, atunci, să discutăm despre separarea cheilor între servere, dacă deja există un GUID unic? Există un alt plugin - keyring_udf. Cu ajutorul acestui plugin, utilizatorul serverului tău poate stoca cheile pe serverul Vault. Problema apare atunci când utilizatorul creează o cheie, de exemplu, pe serverul server1, și apoi încearcă să creeze o cheie cu același identificator pe serverul server2, de exemplu:
--server1:
select keyring_key_store('ROB_1','AES',"123456789012345");
1
--1 înseamnă finalizare cu succes
--server2:
select keyring_key_store('ROB_1','AES',"543210987654321");
1Așteaptă. Ambele servere folosesc același Vault Server, nu ar trebui ca funcția keyring_key_store să se încheie cu o eroare pe serverul server2? Este interesant, că dacă încerci să faci același lucru pe un singur server, vei obține o eroare:
--server1:
select keyring_key_store('ROB_1','AES',"123456789012345");
1
select keyring_key_store('ROB_1','AES',"543210987654321");
0Corect, ROB_1 există deja.
Să discutăm mai întâi al doilea exemplu. Așa cum am menționat anterior, keyring_vault sau orice alt plugin de stocare (keyring) cache-uiește toate identificatoarele cheilor în memorie. Astfel, după crearea unei noi chei, ROB_1 este adăugat pe serverul server1, iar, pe lângă trimiterea acestei chei în Vault, cheia este, de asemenea, adăugată în cache. Acum, când încercăm să adăugăm aceeași cheie a doua oară, keyring_vault verifică dacă această cheie există în cache și returnează o eroare.
În primul caz, situația este diferită. Pe serverele server1 și server2 există cache-uri separate. După adăugarea ROB_1 în cache-ul cheilor de pe serverul server1 și serverul Vault, cache-ul cheilor pe serverul server2 nu este sincronizat. În cache-ul de pe server2 nu există 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 egală cu 543210987654321. Este interesant că serverul Vault nu blochează astfel de acțiuni și pur și simplu suprascrie vechea valoare.
Acum vedem de ce separarea pe servere în Vault poate fi importantă — când folosiți keyring_udf și doriți să stocați cheile în Vault. Cum asigurați o astfel de separare pe serverul Vault?
Există două modalități de a separa în Vault. Puteți crea diferite puncte de montare pentru fiecare server sau utiliza diferite căi în interiorul unui singur punct de montare. Cel mai bine este să arătăm acest lucru prin exemple. Așadar, să ne uităm mai întâi la puncte de montare separate:
--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 = server2_mount
token = (...)
vault_ca = (...)Aici se poate observa că serverul server1 și serverul server2 folosesc puncte de montare diferite. Când separați căile, 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/server2
token = (...)
vault_ca = (...)În acest caz, ambele servere folosesc același punct de montare „mount_point”, dar căi diferite. Atunci când se creează primul secret pe serverul server1 la această cale, serverul Vault creează automat directorul „server1”. Pentru server2, totul este similar. Când ștergeți ultimul secret din mount_point/server1 sau mount_point/server2, serverul Vault șterge de asemenea aceste directoare. În cazul în care folosiți separarea căilor, trebuie să creați un singur punct de montare și să modificați fișierele de configurare, astfel încât serverele să folosească căi separate. Punctul de montare poate fi creat printr-o solicitare HTTP. Cu CURL, 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_POINTToate câmpurile (TOKEN, VAULT_CA, VAULT_URL, SECRET_MOUNT_POINT) corespund parametrilor din fișierul de configurare. Desigur, se pot utiliza utilitarele Vault pentru a realiza aceeași operațiune. Dar este mai simplu să automatizați crearea punctului de montare. Sper că aceste informații vă vor fi utile și ne vom vedea în următoarele articole din această serie.
Citește mai mult:
Sursa: habr.com
