Kriptimi në MySQL: depoja e çelësave

Në prag të fillimit të një grupi të ri për kursin «Baza të dhënash» kemi përgatitur një përkthim të një artikulli të dobishëm për ju.

Kriptimi në MySQL: depoja e çelësave

Enkriptimi i transparencës së të dhënave (Transparent Data Encryption, TDE) ka dalë në Percona Server për MySQL dhe MySQL prej kohësh. Por, a keni menduar ndonjëherë se si funksionon ai nën kapak dhe çfarë ndikimi mund të ketë TDE në serverin tuaj? Në këtë seri artikujsh, ne do të shqyrtojmë se si funksionon TDE nga brenda. Le të fillojmë me ruajtjen e çelësave, pasi është e nevojshme për funksionimin e çdo enkriptimi. Pastaj do të shqyrtojmë me detaje se si funksionon enkriptimi në Percona Server for MySQL/MySQL dhe cilat mundësi shtesë ka në Percona Server for MySQL.

MySQL Keyring

Keyring janĂ« plginĂ« qĂ« lejojnĂ« serverin tĂ« kĂ«rkojĂ«, krijojĂ« dhe fshijĂ« çelĂ«sat nĂ« njĂ« skedarin lokal (keyring_file) ose nĂ« njĂ« server tĂ« largĂ«t (p.sh., nĂ« HashiCorp Vault). ÇelĂ«sat gjithmonĂ« ruhen nĂ« cache lokal, pĂ«r tĂ« pĂ«rshpejtuar marrjen e tyre.

Plginët mund të ndahen në dy kategori:

  • Ruajtje lokale. PĂ«r shembull, njĂ« skedar lokal (ne e quajmĂ« kĂ«tĂ« ruajtje çelĂ«sash nĂ« skedar, file-based keyring).
  • Ruajtje tĂ« largĂ«t. PĂ«r shembull, Vault Server (ne e quajmĂ« kĂ«tĂ« ruajtje çelĂ«sash nĂ« server, server-based keyring).

Kyç i ndarjes është i rëndësishëm, sepse llojet e ndryshme të ruajtjes sjellin ndarje të ndryshme jo vetëm gjatë ruajtjes dhe marrjes së çelësave, por edhe gjatë aktivizimit.

Me përdorimin e ruajtjes me skedarë, gjatë aktivizimit ngarkohet në cache përmbajtja e gjithë ruajtjes: key id, key user, key type dhe vetë çelësi.

NĂ« rastin e ruajtjes nĂ« server (p.sh., nĂ« serverin Vault) gjatĂ« aktivizimit ngarkohet vetĂ«m key id dhe key user, kĂ«shtu qĂ« marrja e tĂ« gjithĂ« çelĂ«save nuk e ngadalĂ«son aktivizimin. ÇelĂ«sat ngarkohen nĂ« mĂ«nyrĂ« lenjike. Kjo do tĂ« thotĂ« se çelĂ«si ngarkohet nga Vault vetĂ«m kur ai nĂ« fakt ka nevojĂ«. Pasi qĂ« Ă«shtĂ« ngarkuar, çelĂ«si ruhet nĂ« kujtesĂ«, pĂ«r tĂ« shmangur nevojĂ«n pĂ«r ta kĂ«rkuar pĂ«rmes lidhjeve TLS me Serverin Vault. MĂ« pas, do tĂ« shqyrtojmĂ« se çfarĂ« informacioni pĂ«rmban ruajtja e çelĂ«save.

Informacioni mbi çelësin përmban sa vijon:

  • key id — identifikuesi i çelĂ«sit, p.sh.:
    INNODBKey-764d382a-7324-11e9-ad8f-9cb6d0d5dc99-1
  • key type — tipi i çelĂ«sit, i bazuar nĂ« algoritmin e enkriptimit tĂ« pĂ«rdorur, vlerat e mundshme: "AES", "RSA" ose "DSA".
  • key length — gjatĂ«sia e çelĂ«sit nĂ« byte, AES: 16, 24 ose 32, RSA 128, 256, 512 dhe DSA 128, 256 ose 384.
  • pĂ«rdorues — pronari i çelĂ«sit. NĂ«se çelĂ«si Ă«shtĂ« sistemik, siç Ă«shtĂ« Master Key, atĂ«herĂ« kjo fushĂ« Ă«shtĂ« bosh. NĂ«se çelĂ«si krijohet me keyring_udf, atĂ«herĂ« kjo fushĂ« tregon pronarin e çelĂ«sit.
  • çelĂ«si vetĂ«

ÇelĂ«si identifikohet njĂ«herĂ« e pĂ«rgjithmonĂ« me çiftin: key_id, user.

Gjithashtu ka dallime në ruajtjen dhe fshirjen e çelësave.

Ruajtja nĂ« skedar punon mĂ« shpejt. Mund tĂ« supozohet se depozita e çelĂ«save Ă«shtĂ« njĂ« regjistrim i thjeshtĂ« i njĂ« herĂ«sh i çelĂ«sit nĂ« njĂ« skedar, por jo — kĂ«tu ndodhin mĂ« shumĂ« operacione. Me çdo modifikim tĂ« depozitĂ«s sĂ« skedarĂ«ve, fillimisht krijohet njĂ« kopje e gjithĂ« pĂ«rmbajtjes. Supozoni se skedari quhet my_biggest_secrets, atĂ«herĂ« kopja do tĂ« jetĂ« my_biggest_secrets.backup. MĂ« pas modifikohet cache (shtohen ose hiqen çelĂ«sat) dhe, nĂ«se gjithçka kalon me sukses, atĂ«herĂ« cache-et pĂ«rshtatet nĂ« skedar. NĂ« raste tĂ« rralla, siç Ă«shtĂ« njĂ« dĂ«shtim serveri, mund tĂ« shihni kĂ«tĂ« skedar kopje rezervĂ«. Skedari i kopjes rezervĂ« fshihet kur ngarkohen çelĂ«sat ndjekĂ«s (zakonisht pas ribĂ«rĂ«jes sĂ« serverit).

Kur savahen ose fshihet çelësi në ruajtjen e serverit, ruajtja duhet të lidhet me serverin MySQL me komandat "dërgo çelësin" / "kërko fshirjen e çelësit".

Le tĂ« kthehemi te shpejtĂ«sia e nisjes sĂ« serverit. PĂ«rveç faktit se ruajtja e vet ndikon nĂ« shpejtĂ«sinĂ« e nisjes, pyetja Ă«shtĂ« gjithashtu se sa çelĂ«sa nga ruajtja duhet tĂ« merren gjatĂ« nisjes. Sigurisht, kjo Ă«shtĂ« veçanĂ«risht e rĂ«ndĂ«sishme pĂ«r ruajtjet e serverĂ«ve. GjatĂ« nisjes, serveri kontrollon se cili çelĂ«s Ă«shtĂ« i nevojshĂ«m pĂ«r tabelat e enkriptuara / hapĂ«sirat e tabelave dhe kĂ«rkon çelĂ«sin nga ruajtja. NĂ« njĂ« server "tĂ« pastĂ«r" me Master Key — enkriptimi duhet tĂ« ketĂ« njĂ« Master Key tĂ« vetĂ«m, qĂ« duhet tĂ« nxirret nga ruajtja. MegjithatĂ«, mund tĂ« kĂ«rkohen edhe mĂ« shumĂ« çelĂ«sa, pĂ«r shembull, kur njĂ« server rezervĂ« rikuperon njĂ« kopje rezervĂ« nga serveri kryesor. NĂ« kĂ«to raste, duhet tĂ« parashikohet rotacioni i Master Key. Kjo do tĂ« shqyrtohet mĂ« nĂ« detaje nĂ« artikujt e ardhshĂ«m, megjithatĂ« kĂ«tu do tĂ« doja tĂ« theksoja se serveri qĂ« pĂ«rdor disa Master Key mund tĂ« nisĂ« pak mĂ« ngadalĂ«, veçanĂ«risht, kur pĂ«rdoret ruajtja e çelĂ«sit tĂ« serverit.

Tani tani, le të flasim pak më shumë për keyring_file. Gjatë zhvillimit të keyring_file, isha gjithashtu i shqetësuar për mënyrën e kontrollit të ndryshimit të keyring_file gjatë funksionimit të serverit. Në versionin 5.7, kontrolli u bazua në statistikat e skedarit, e cila nuk ishte zgjidhja më e mirë, dhe në versionin 8.0 kjo u zëvendësua me një checksum SHA256.

Kur ekzekutohet për herë të parë, keyring_file llogarit statistikën e skedarit dhe checksum-in, të cilat regjistrohen nga serveri, dhe ndryshimet zbatohen vetëm nëse ato përkasin pjesës. Kur skedari ndryshon, checksum-i përditësohet.

Kemi shqyrtuar shumĂ« pyetje rreth depozitave tĂ« çelĂ«save. MegjithatĂ«, ka njĂ« temĂ« tjetĂ«r tĂ« rĂ«ndĂ«sishme, e cila shpesh harrohet ose keqkuptohet — ndarja e çelĂ«save sipas serverĂ«ve.

ÇfarĂ« po them? Çdo server (pĂ«r shembull, Percona Server) nĂ« kluster duhet tĂ« ketĂ« njĂ« vend tĂ« veçantĂ« nĂ« serverin Vault, ku Percona Server duhet tĂ« ruajĂ« çelĂ«sat e tij. Çdo ÇelĂ«s kryesor, i ruajtur nĂ« depo, pĂ«rmban GUID-in e serverit Percona Server brenda identifikuesit tĂ« tij. Pse Ă«shtĂ« kjo e rĂ«ndĂ«sishme? Imagjinoni qĂ« keni vetĂ«m njĂ« server Vault dhe tĂ« gjithĂ« serverat Percona nĂ« klaster pĂ«rdorin kĂ«tĂ« server tĂ« vetĂ«m Vault. Problemi duket i qartĂ«. Po sikur tĂ« gjithĂ« serverat Percona tĂ« pĂ«rdorin çelĂ«sin kryesor pa identifikatorĂ« unikĂ«, pĂ«r shembull, id = 1, id = 2 etj., tĂ« gjithĂ« serverat nĂ« klaster do tĂ« pĂ«rdornin tĂ« njĂ«jtin çelĂ«s kryesor. ÇfarĂ« ofron GUID - ndarjen ndĂ«rmjet serverĂ«ve. Pse pastaj tĂ« flasim pĂ«r ndarjen e çelĂ«save midis serverĂ«ve, nĂ«se tashmĂ« ekziston njĂ« GUID unik? Ka njĂ« plugin tjetĂ«r - keyring_udf. Me kĂ«tĂ« plugin, pĂ«rdoruesi i serverit tuaj mund tĂ« ruajĂ« çelĂ«sat e tij nĂ« serverin Vault. Problemi lind kur pĂ«rdoruesi krijon njĂ« çelĂ«s, pĂ«r shembull, nĂ« serverin server1, dhe pastaj pĂ«rpiqet tĂ« krijojĂ« njĂ« çelĂ«s me tĂ« njĂ«jtin identifikues nĂ« server2, pĂ«r shembull:

--server1:
select keyring_key_store('ROB_1','AES',"123456789012345");
1
--1 do të thotë përfundim të sukseeshëm
--server2:
select keyring_key_store('ROB_1','AES',"543210987654321");
1

Pritni pak. Të dy serverët përdorin të njëjtin Vault Server, nuk duhet të përfundojë funksioni keyring_key_store me një gabim në serverin server2? E çuditshme, sepse nëse provoni të bëni të njëjtën gjë në një server, do të merrni një gabim:

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

Saktë, ROB_1 tashmë ekziston.

Le të diskutojmë fillimisht shembullin e dytë. Siç e thamë më parë, keyring_vault ose çdo plugin tjetër depozite (keyring) ruan në memory të gjitha identifikuesit e çelësave. Pra, pasi të krijohet një çelës i ri, ROB_1 shtohet në serverin 1, dhe përveç dërgimit të këtij çelësi në Vault, çelësi gjithashtu shtohet në cache. Tani, kur përpiqemi të shtojmë të njëjtin çelës për herë të dytë, keyring_vault kontrollon nëse ky çelës ekziston në cache dhe kthen një gabim.

NĂ« rastin e parĂ« situata Ă«shtĂ« ndryshe. NĂ« serverĂ«t server1 dhe server2 ka cache tĂ« veçantĂ«. Pas shtimit tĂ« ROB_1 nĂ« cache-n e çelĂ«save nĂ« serverin server1 dhe serverin Vault, cache-i i çelĂ«save nĂ« serverin server2 nuk Ă«shtĂ« sinkronizuar. NĂ« cache-n e serverit server2 nuk ka çelĂ«s ROB_1. KĂ«shtu, çelĂ«si ROB_1 shkruhet nĂ« keyring_key_store dhe nĂ« serverin Vault, i cili faktikisht ripёrshkruan (!) vlerĂ«n e mĂ«parshme. Tani çelĂ«si ROB_1 nĂ« serverin Vault Ă«shtĂ« i barabartĂ« me 543210987654321. ËshtĂ« interesante qĂ« serveri Vault nuk e bllokon njĂ« veprim tĂ« tillĂ« dhe lehtĂ«sisht ripёrshkruan vlerĂ«n e vjetĂ«r.

Tani ne shohim pse ndarja sipas serverĂ«ve nĂ« Vault mund tĂ« jetĂ« e rĂ«ndĂ«sishme — kur pĂ«rdorni keyring_udf dhe dĂ«shironi tĂ« ruani çelĂ«sat nĂ« Vault. Si tĂ« sigurojmĂ« njĂ« ndarje tĂ« tillĂ« nĂ« serverin Vault?

Ka dy mënyra për ndarjen në Vault. Mund të krijoni pika montimi të ndryshme për çdo server ose të përdorni rrugë të ndryshme brenda një pike montimi. Më së miri kjo mund të demonstrohet me shembuj. Le të shikojmë fillimisht pikat e montimit të veçanta:

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

Këtu duket se server1 dhe server2 përdorin pika të montimit të ndryshme. Kur ndahen rrugët, konfigurimi do të duket si më poshtë:

--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ë këtë rast, të dy serverat përdorin të njëjtën pikë montimi "mount_point", por rrugë të ndryshme. Kur krijoni sekreti e parë në serverin server1 në këtë rrugë, serveri Vault automatikisht krijon drejtorinë "server1". Për server2 gjithçka është e ngjashme. Kur hiqni sekreti e fundit në mount_point/server1 ose mount_point/server2, serveri Vault gjithashtu hiqet këto drejtoritë. Nëse përdorni ndarjen e rrugëve, duhet të krijoni vetëm një pikë montimi dhe të ndryshoni skedarët e konfigurimit në mënyrë që serverat të përdorin rrugë të veçanta. Pika e montimit mund të krijohet me anë të një kërkese HTTP. Me CURL, kjo mund të bëhet si më poshtë:

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

Të gjitha fushat (TOKEN, VAULT_CA, VAULT_URL, SECRET_MOUNT_POINT) përputhen me parametrat e skedarit të konfigurimit. Sigurisht, mund të përdorni mjetet e Vault për të bërë të njëjtën gjë. Por kështu është më e lehtë për të automatizuar krijimin e pikës së montimit. Shpresoj që kjo informacion të jetë e dobishme për ju dhe do të takohemi në artikujt e tjerë të kësaj serie.

Kriptimi në MySQL: depoja e çelësave

Lexoni më shumë:

Burimi: habr.com

Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« đŸ”„ Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« | ProHoster