Šifravimas MySQL: Keystore

Laukiant naujos registracijos į kursą pradžios "duomenų bazė" Mes paruošėme jums naudingo straipsnio vertimą.

Šifravimas MySQL: Keystore

Skaidrus duomenų šifravimas (TDE) pasirodė „Percona“ serveris, skirtas „MySQL“. ir MySQL gana ilgą laiką. Bet ar kada pagalvojote apie tai, kaip jis veikia po gaubtu ir kokį poveikį TDE gali turėti jūsų serveriui? Šioje straipsnių serijoje apžvelgsime, kaip TDE veikia viduje. Pradėkime nuo raktų saugojimo, nes tai reikalinga, kad bet koks šifravimas veiktų. Tada atidžiau pažvelgsime į tai, kaip veikia Percona Server for MySQL/MySQL šifravimas ir kokias papildomas funkcijas turi Percona Server for MySQL.

MySQL raktų pakabukas

„Keyring“ yra papildiniai, leidžiantys serveriui pateikti užklausą, kurti ir ištrinti raktus vietiniame faile (keyring_file) arba nuotoliniame serveryje (pvz., „HashiCorp Vault“). Raktai visada saugomi talpykloje vietoje, kad būtų pagreitintas jų gavimas.

Papildinius galima suskirstyti į dvi kategorijas:

  • Vietinė parduotuvė. Pavyzdžiui, vietinis failas (mes tai vadiname failų pagrindu veikiančiu raktų žiedu).
  • Nuotolinė saugykla. Pavyzdžiui, „Vault Server“ (mes tai vadiname serverio raktų žiedu).

Šis atskyrimas yra svarbus, nes skirtingų tipų saugyklos elgiasi šiek tiek skirtingai ne tik saugant ir paimant raktus, bet ir juos naudojant.

Naudojant failų saugyklą, paleidžiant į talpyklą įkeliamas visas saugyklos turinys: rakto ID, rakto naudotojas, rakto tipas ir pats raktas.

Serverio parduotuvės (pvz., Vault serverio) atveju paleidžiant įkeliamas tik rakto ID ir rakto vartotojas, todėl visų raktų gavimas nesustabdo paleidimo. Raktai kraunami tingiai. Tai yra, pats raktas įkeliamas iš Vault tik tada, kai jo iš tikrųjų reikia. Atsisiuntus raktas saugomas talpykloje atmintyje, kad ateityje jo nereikėtų pasiekti per TLS ryšius su Vault serveriu. Toliau pažiūrėkime, kokia informacija yra raktų saugykloje.

Pagrindinė informacija yra tokia:

  • rakto ID — rakto identifikatorius, pavyzdžiui:
    INNODBKey-764d382a-7324-11e9-ad8f-9cb6d0d5dc99-1
  • rakto tipas — rakto tipas, pagrįstas naudojamu šifravimo algoritmu, galimos reikšmės: „AES“, „RSA“ arba „DSA“.
  • rakto ilgis — rakto ilgis baitais, AES: 16, 24 arba 32, RSA 128, 256, 512 ir DSA 128, 256 arba 384.
  • vartotojas - rakto savininkas. Jei raktas yra sistemos, pavyzdžiui, pagrindinis raktas, šis laukas yra tuščias. Jei raktas sukurtas naudojant keyring_udf, šiame lauke nurodomas rakto savininkas.
  • pats raktas

Raktą vienareikšmiškai identifikuoja pora: key_id, user.

Taip pat skiriasi raktų saugojimas ir trynimas.

Failų saugojimas yra greitesnis. Galbūt manote, kad raktų saugykla tiesiog vieną kartą įrašo raktą į failą, bet ne, čia vyksta daugiau. Atlikus failo saugyklos pakeitimą, pirmiausia sukuriama viso turinio atsarginė kopija. Tarkime, failas vadinamas my_diggest_secrets, tada atsarginė kopija bus mano_didžiausios_slaptys.atsarginė kopija. Tada pakeičiama talpykla (pridedami arba ištrinami raktai) ir, jei viskas pavyksta, talpykla iš naujo nustatoma į failą. Retais atvejais, pvz., serverio gedimo atveju, galite pamatyti šį atsarginės kopijos failą. Atsarginės kopijos failas ištrinamas kitą kartą įkeliant raktus (paprastai iš naujo paleidus serverį).

Išsaugant arba ištrinant raktą serverio saugykloje, saugykla turi prisijungti prie MySQL serverio komandomis „siųsti raktą“ / „prašyti rakto ištrynimo“.

Grįžkime prie serverio paleidimo greičio. Be to, kad paleidimo greičiui įtakos turi pati saugykla, taip pat kyla klausimas, kiek raktų iš saugyklos reikia gauti paleidžiant. Žinoma, tai ypač svarbu serverio saugykloje. Paleidžiant, serveris patikrina, kuris raktas reikalingas šifruotoms lentelėms / lentelių erdvėms ir prašo rakto iš saugyklos. „Švariame“ serveryje su pagrindinio rakto šifravimu turi būti vienas pagrindinis raktas, kuris turi būti nuskaitytas iš saugyklos. Tačiau gali prireikti didesnio raktų skaičiaus, pavyzdžiui, kai atsarginės kopijos serveris atkuria atsarginę kopiją iš pirminio serverio. Tokiais atvejais turėtų būti numatytas pagrindinio rakto pasukimas. Tai bus išsamiau aprašyta būsimuose straipsniuose, nors čia norėčiau atkreipti dėmesį, kad serverio, naudojančio kelis pagrindinius raktus, paleidimas gali užtrukti šiek tiek ilgiau, ypač kai naudojama serverio pusės raktų saugykla.

Dabar pakalbėkime šiek tiek daugiau apie keyring_file. Kurdamas raktų žiedo_failą taip pat nerimavau, kaip patikrinti raktų žiedo_failo pakeitimus, kol serveris veikia. 5.7 patikrinimas buvo atliktas remiantis failų statistika, o tai nebuvo idealus sprendimas, o 8.0 buvo pakeistas SHA256 kontroline suma.

Pirmą kartą paleidus keyring_file, apskaičiuojama failų statistika ir kontrolinė suma, kurią įsimena serveris, o pakeitimai taikomi tik tuo atveju, jei jie sutampa. Kai failas pasikeičia, kontrolinė suma atnaujinama.

Jau aptarėme daug klausimų apie raktų saugyklas. Tačiau yra dar viena svarbi tema, kuri dažnai pamirštama arba nesuprantama: raktų bendrinimas tarp serverių.

Ką turiu omenyje? Kiekvienas klasteryje esantis serveris (pavyzdžiui, „Percona Server“) turi turėti atskirą vietą „Vault“ serveryje, kurioje „Percona Server“ turi saugoti savo raktus. Kiekvieno pagrindinio rakto, išsaugoto saugykloje, identifikatoriuje yra Percona serverio GUID. Kodėl tai svarbu? Įsivaizduokite, kad turite tik vieną „Vault“ serverį ir visi „Percona“ serveriai klasteryje naudoja tą vienintelį „Vault“ serverį. Problema atrodo akivaizdi. Jei visi Percona serveriai naudotų pagrindinį raktą be unikalių identifikatorių, pvz., id = 1, id = 2 ir tt, tada visi klasterio serveriai naudotų tą patį pagrindinį raktą. Tai, ką suteikia GUID, yra serverių skirtumas. Kam tada kalbėti apie raktų bendrinimą tarp serverių, jei unikalus GUID jau yra? Yra dar vienas papildinys – keyring_udf. Naudodamas šį papildinį, jūsų serverio vartotojas gali saugoti savo raktus Vault serveryje. Problema kyla, kai vartotojas sukuria raktą server1, pavyzdžiui, ir tada bando sukurti raktą su tuo pačiu ID serveryje2, pavyzdžiui:

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

Laukti. Abu serveriai naudoja tą patį „Vault“ serverį. Ar „keyring_key_store“ funkcija neturėtų sugesti serveryje2? Įdomu tai, kad jei bandysite tą patį padaryti viename serveryje, gausite klaidą:

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

Teisingai, ROB_1 jau yra.

Pirmiausia aptarkime antrąjį pavyzdį. Kaip minėjome anksčiau, keyring_vault arba bet kuris kitas raktų žiedo papildinys talpina visus raktų ID atmintyje. Taigi, sukūrus naują raktą, ROB_1 pridedamas prie serverio1, o be šio rakto siuntimo į Vault, raktas taip pat pridedamas prie talpyklos. Dabar, kai bandome pridėti tą patį raktą antrą kartą, keyring_vault patikrina, ar raktas yra talpykloje, ir pateikia klaidą.

Pirmuoju atveju situacija yra kitokia. Server1 ir serveris2 turi atskiras talpyklas. Pridėjus ROB_1 prie serverio1 ir Vault serverio raktų talpyklos, serverio2 rakto talpykla nesinchronizuojama. Server2 talpykloje nėra ROB_1 rakto. Taigi, ROB_1 raktas įrašomas į raktų žiedo_raktų_parduotuvė ir "Vault" serverį, kuris iš tikrųjų perrašo (!) ankstesnę reikšmę. Dabar Vault serverio ROB_1 raktas yra 543210987654321. Įdomu tai, kad Vault serveris neblokuoja tokių veiksmų ir lengvai perrašo seną reikšmę.

Dabar matome, kodėl serverio skaidymas „Vault“ gali būti svarbus – kai naudojate keyring_udf ir norite saugoti raktus „Vault“. Kaip pasiekti šį atskyrimą Vault serveryje?

Yra du būdai, kaip skaidyti į Vault. Kiekvienam serveriui galite sukurti skirtingus prijungimo taškus arba naudoti skirtingus kelius tame pačiame prijungimo taške. Tai geriausiai iliustruoja pavyzdžiai. Taigi pirmiausia pažvelkime į atskirus tvirtinimo taškus:

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

Čia galite pamatyti, kad serveris1 ir serveris2 naudoja skirtingus prijungimo taškus. Padalijus kelius, konfigūracija atrodys taip:

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

Šiuo atveju abu serveriai naudoja tą patį prijungimo tašką „mount_point“, bet skirtingus kelius. Kai sukuriate pirmąją paslaptį server1 naudodamiesi šiuo keliu, „Vault“ serveris automatiškai sukuria „server1“ katalogą. Server2 viskas panašiai. Kai ištrinate paskutinę paslaptį mount_point/server1 arba mount_point/server2, Vault serveris taip pat ištrina tuos katalogus. Jei naudojate kelių atskyrimą, turite sukurti tik vieną prijungimo tašką ir pakeisti konfigūracijos failus, kad serveriai naudotų atskirus kelius. Sujungimo tašką galima sukurti naudojant HTTP užklausą. Naudojant CURL tai galima padaryti taip:

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

Visi laukai (TOKEN, VAULT_CA, VAULT_URL, SECRET_MOUNT_POINT) atitinka konfigūracijos failo parametrus. Žinoma, galite naudoti „Vault“ paslaugų programas, kad padarytumėte tą patį. Tačiau lengviau automatizuoti prijungimo taško kūrimą. Tikiuosi, kad ši informacija jums bus naudinga ir pasimatysime kituose šios serijos straipsniuose.

Šifravimas MySQL: Keystore

Skaityti daugiau:

Šaltinis: www.habr.com

Добавить комментарий