Pag-encrypt sa MySQL: Keystore

Sa bisperas ng pagsisimula ng isang bagong pagpapatala para sa kurso "Database" Naghanda kami ng pagsasalin ng isang kapaki-pakinabang na artikulo para sa iyo.

Pag-encrypt sa MySQL: Keystore

Lumitaw ang Transparent Data Encryption (TDE). Percona Server para sa MySQL at MySQL sa loob ng mahabang panahon. Ngunit naisip mo na ba kung paano ito gumagana sa ilalim ng hood at kung ano ang maaaring maging epekto ng TDE sa iyong server? Sa seryeng ito ng mga artikulo, titingnan natin kung paano gumagana ang TDE sa loob. Magsimula tayo sa key storage, dahil kinakailangan ito para gumana ang anumang pag-encrypt. Pagkatapos ay titingnan natin nang mabuti kung paano gumagana ang pag-encrypt sa Percona Server para sa MySQL/MySQL at kung anong mga karagdagang feature ang mayroon ang Percona Server para sa MySQL.

MySQL Keyring

Ang keyring ay mga plugin na nagbibigay-daan sa server na mag-query, gumawa, at magtanggal ng mga key sa isang lokal na file (keyring_file) o sa isang malayuang server (gaya ng HashiCorp Vault). Palaging naka-cache ang mga susi nang lokal upang mapabilis ang pagkuha ng mga ito.

Ang mga plugin ay maaaring nahahati sa dalawang kategorya:

  • Lokal na imbakan. Halimbawa, isang lokal na file (tinatawag namin itong file-based na keyring).
  • Malayong imbakan. Halimbawa, Vault Server (tinatawag namin itong server-based na keyring).

Ang paghihiwalay na ito ay mahalaga dahil ang iba't ibang uri ng storage ay bahagyang naiiba, hindi lamang kapag nag-iimbak at kumukuha ng mga susi, kundi pati na rin kapag pinapatakbo ang mga ito.

Kapag gumagamit ng isang imbakan ng file, sa pagsisimula, ang buong nilalaman ng imbakan ay na-load sa cache: key id, key user, key type, at ang key mismo.

Sa kaso ng isang server-based na tindahan (tulad ng Vault Server), tanging ang key id at key user lang ang nilo-load sa startup, kaya ang pagkuha ng lahat ng key ay hindi nagpapabagal sa startup. Tamad na ni-load ang mga susi. Iyon ay, ang susi mismo ay nilo-load mula sa Vault lamang kapag ito ay talagang kinakailangan. Kapag na-download na, ang key ay naka-cache sa memorya para hindi na ito kailangang ma-access sa pamamagitan ng mga TLS na koneksyon sa Vault Server sa hinaharap. Susunod, tingnan natin kung anong impormasyon ang naroroon sa key store.

Ang pangunahing impormasyon ay naglalaman ng mga sumusunod:

  • key id β€” key identifier, halimbawa:
    INNODBKey-764d382a-7324-11e9-ad8f-9cb6d0d5dc99-1
  • uri ng susi β€” uri ng key batay sa ginamit na algorithm ng pag-encrypt, mga posibleng halaga: β€œAES”, β€œRSA” o β€œDSA”.
  • haba ng susi β€” haba ng key sa mga byte, AES: 16, 24 o 32, RSA 128, 256, 512 at DSA 128, 256 o 384.
  • gumagamit - may-ari ng susi. Kung system ang key, halimbawa, Master Key, walang laman ang field na ito. Kung ang isang susi ay ginawa gamit ang keyring_udf, ang field na ito ay kinikilala ang may-ari ng susi.
  • ang susi mismo

Ang susi ay natatanging kinilala ng pares: key_id, user.

Mayroon ding mga pagkakaiba sa pag-iimbak at pagtanggal ng mga susi.

Ang imbakan ng file ay mas mabilis. Maaari mong isipin na ang keystore ay isang beses lamang na pagsulat ng susi sa isang file, ngunit hindi - marami pang nangyayari dito. Sa tuwing babaguhin ang isang imbakan ng file, bina-back up muna ang lahat ng nilalaman. Sabihin nating ang file ay tinatawag na my_biggest_secrets, at ang backup ay my_biggest_secrets.backup. Susunod, ang cache ay binago (ang mga susi ay idinagdag o inalis) at, kung ang lahat ay matagumpay, ang cache ay itinapon sa isang file. Sa mga bihirang kaso, tulad ng pag-crash ng server, maaari mong makita ang backup na file na ito. Ang backup file ay tatanggalin sa susunod na oras na ang mga susi ay na-load (karaniwan ay pagkatapos ng pag-restart ng server).

Kapag nagse-save o nagtatanggal ng susi sa storage ng server, dapat kumonekta ang storage sa MySQL server na may mga command na "ipadala ang susi" / "hilingin ang pagtanggal ng key".

Bumalik tayo sa bilis ng pagsisimula ng server. Bilang karagdagan sa katotohanan na ang bilis ng paglunsad ay apektado ng mismong vault, mayroon ding isyu kung gaano karaming mga susi mula sa vault ang kailangang makuha sa pagsisimula. Siyempre, ito ay lalong mahalaga para sa imbakan ng server. Sa pagsisimula, sinusuri ng server kung aling key ang kinakailangan para sa mga naka-encrypt na table/tablespace at hinihiling ang susi mula sa storage. Sa isang "malinis" na server na may Master Key encryption, dapat mayroong isang Master Key, na dapat makuha mula sa storage. Gayunpaman, maaaring kailanganin ang mas malaking bilang ng mga susi, halimbawa, kapag ang backup na server ay nagpapanumbalik ng backup mula sa pangunahing server. Sa ganitong mga kaso, dapat ibigay ang pag-ikot ng Master Key. Tatalakayin ito nang mas detalyado sa mga artikulo sa hinaharap, bagama't dito gusto kong tandaan na ang isang server na gumagamit ng maraming Master Keys ay maaaring tumagal nang kaunti upang magsimula, lalo na kapag gumagamit ng isang server-side na key store.

Ngayon, pag-usapan natin ang tungkol sa keyring_file. Noong nagdidisenyo ako ng keyring_file, nag-aalala rin ako kung paano suriin ang mga pagbabago sa keyring_file habang tumatakbo ang server. Sa 5.7, isinagawa ang pagsusuri batay sa mga istatistika ng file, na hindi perpekto, at sa 8.0 ay pinalitan ito ng SHA256 checksum.

Sa unang pagkakataon na magpatakbo ka ng keyring_file, ang mga istatistika ng file at isang checksum ay kinakalkula, na naaalala ng server, at ang mga pagbabago ay ilalapat lamang kung magkatugma ang mga ito. Kapag nagbago ang file, ina-update ang checksum.

Natalakay na namin ang maraming tanong tungkol sa mga key vault. Gayunpaman, may isa pang mahalagang paksa na kadalasang nakalimutan o hindi nauunawaan: pagbabahagi ng mga susi sa mga server.

Ang ibig kong sabihin? Ang bawat server (halimbawa, Percona Server) sa cluster ay dapat may hiwalay na lokasyon sa Vault Server kung saan dapat iimbak ng Percona Server ang mga susi nito. Ang bawat Master Key na naka-save sa storage ay naglalaman ng GUID ng Percona Server sa loob ng identifier nito. Bakit ito mahalaga? Isipin na mayroon ka lang isang Vault Server at lahat ng Percona Server sa cluster ay gumagamit ng solong Vault Server na iyon. Ang problema ay tila halata. Kung gumamit ang lahat ng Percona Server ng Master Key na walang mga natatanging identifier, gaya ng id = 1, id = 2, atbp., ang lahat ng server sa cluster ay gagamit ng parehong Master Key. Ang ibinibigay ng GUID ay ang pagkakaiba sa pagitan ng mga server. Bakit pag-uusapan ang pagbabahagi ng mga susi sa pagitan ng mga server kung mayroon nang natatanging GUID? May isa pang plugin - keyring_udf. Gamit ang plugin na ito, maiimbak ng user ng iyong server ang kanilang mga susi sa Vault server. Ang problema ay nangyayari kapag ang isang user ay lumikha ng isang susi sa server1, halimbawa, at pagkatapos ay sinubukang lumikha ng isang susi na may parehong ID sa server2, halimbawa:

--server1:
select keyring_key_store('ROB_1','AES',"123456789012345");
1
--1 Π·Π½Π°Ρ‡ΠΈΡ‚ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ΅ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅
--server2:
select keyring_key_store('ROB_1','AES',"543210987654321");
1

Teka. Parehong server ang gumagamit ng parehong Vault Server, hindi ba dapat mabigo ang keyring_key_store function sa server2? Kapansin-pansin, kung susubukan mong gawin ang parehong sa isang server, makakatanggap ka ng isang error:

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

Tama, mayroon nang ROB_1.

Talakayin muna natin ang pangalawang halimbawa. Gaya ng sinabi namin kanina, ini-cache ng keyring_vault o anumang iba pang keyring plugin ang lahat ng key ID sa memorya. Kaya, pagkatapos gumawa ng bagong key, idinaragdag ang ROB_1 sa server1, at bilang karagdagan sa pagpapadala ng key na ito sa Vault, idinaragdag din ang key sa cache. Ngayon, kapag sinubukan naming idagdag ang parehong key sa pangalawang pagkakataon, sinusuri ng keyring_vault kung ang key ay umiiral sa cache at naglalabas ng isang error.

Sa unang kaso, iba ang sitwasyon. Ang server1 at server2 ay may magkahiwalay na cache. Pagkatapos idagdag ang ROB_1 sa key cache sa server1 at sa Vault server, ang key cache sa server2 ay hindi naka-sync. Walang ROB_2 key sa cache sa server1. Kaya, ang ROB_1 key ay isinulat sa keyring_key_store at sa Vault server, na talagang nag-o-overwrite (!) sa dating halaga. Ngayon ang ROB_1 key sa Vault server ay 543210987654321. Kapansin-pansin, hindi hinaharangan ng Vault server ang mga naturang pagkilos at madaling na-overwrite ang lumang halaga.

Ngayon ay makikita na natin kung bakit maaaring maging mahalaga ang paghati ng server sa Vault - kapag gumagamit ka ng keyring_udf at gustong mag-imbak ng mga susi sa Vault. Paano makamit ang paghihiwalay na ito sa isang Vault server?

Mayroong dalawang paraan upang mahati sa Vault. Maaari kang lumikha ng iba't ibang mga mount point para sa bawat server, o gumamit ng iba't ibang mga path sa loob ng parehong mount point. Ito ay pinakamahusay na inilarawan sa mga halimbawa. Kaya tingnan muna natin ang mga indibidwal na mount point:

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

Dito makikita mo na ang server1 at server2 ay gumagamit ng magkaibang mga mount point. Kapag hinahati ang mga landas, magiging ganito ang configuration:

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

Sa kasong ito, ang parehong mga server ay gumagamit ng parehong mount point na "mount_point", ngunit magkaibang mga landas. Kapag ginawa mo ang unang lihim sa server1 gamit ang path na ito, awtomatikong gagawa ang Vault server ng direktoryo ng "server1". Para sa server2 lahat ay magkatulad. Kapag tinanggal mo ang huling lihim sa mount_point/server1 o mount_point/server2, tatanggalin din ng Vault server ang mga direktoryo na iyon. Kung sakaling gumamit ka ng paghihiwalay ng landas, dapat kang lumikha lamang ng isang mount point at baguhin ang mga file ng pagsasaayos upang ang mga server ay gumamit ng magkahiwalay na mga landas. Maaaring gumawa ng mount point gamit ang HTTP request. Sa CURL ito ay maaaring gawin tulad nito:

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

Ang lahat ng mga field (TOKEN, VAULT_CA, VAULT_URL, SECRET_MOUNT_POINT) ay tumutugma sa mga parameter ng configuration file. Siyempre, maaari mong gamitin ang mga utility ng Vault upang gawin ang parehong. Ngunit mas madaling i-automate ang paglikha ng isang mount point. Sana ay maging kapaki-pakinabang ang impormasyong ito at magkita-kita tayo sa mga susunod na artikulo sa seryeng ito.

Pag-encrypt sa MySQL: Keystore

Magbasa pa:

Pinagmulan: www.habr.com

Magdagdag ng komento