Uue kursuse alguse eelõhtul oleme teie jaoks tõlkinud kasuliku artikli.

Andmete läbipaistev krüpteerimine (Transparent Data Encryption, TDE) ilmus ja MySQL juba mõnda aega tagasi. Kuid kas olete kunagi mõelnud, kuidas see töötab ning millist mõju TDE võib teie serverile avaldada? Selles artiklisarjas vaatleme, kuidas TDE töötab seestpoolt. Alustame võtmete salvestamisest, kuna see on vajalik iga krüpteerimise jaoks. Seejärel uurime põhjalikult, kuidas krüpteerimine Percona Server for MySQL/MySQL-s toimib ja millised täiendavad funktsioonid on Percona Server for MySQL-l.
MySQL Keyring
Keyring on pistikprogrammid, mis võimaldavad serveril pärida, luua ja kustutada võtmeid kohalikus failis (keyring_file) või eemalserveris (näiteks HashiCorp Vaultis). Võtmed vahetatakse alati kohalikult, et kiirendada nende saamist.
Pistikprogramme saab jagada kahte kategooriasse:
- Kohalik salvestamine. Näiteks kohalik fail (me nimetame seda failipõhiseks võtmehoidjaks, file-based keyring).
- Kaugsalvestamine. Näiteks Vault Server (me nimetame seda serveripõhiseks võtmehoidjaks, server-based keyring).
See jaotamine on oluline, kuna erinevat tüüpi salvestuslahendused käituvad veidi erinevalt, mitte ainult võtmete salvestamisel ja saamisel, vaid ka nende käivitamisel.
Failide salvestamise korral laetakse käivitamisel kõik salvestuse sisu vahemällu: key id, key user, key type ja ise võtmed.
Serveri salvestamise korral (näiteks Vault server) laetakse käivitamisel ainult key id ja key user, seetõttu ei aeglusta võtmete saamine käivitamist. Võtmed laaditakse laiskalt, see tähendab, et võtme sisu laetakse Vaultist alles siis, kui see tegelikult on vajalik. Pärast laadimist salvestatakse võtme sisu mällu, et tulevikus ei oleks vaja selle järele pöörduda Vault Serveri kaudu TLS-ühenduste kaudu. Vaatame lähemalt, millist teavet salvestuses on.
Võtme teave sisaldab järgmist:
- key id — võtme identifikaator, näiteks:
INNODBKey-764d382a-7324-11e9-ad8f-9cb6d0d5dc99-1 - key type — võtme tüüp, mis põhineb kasutataval krüptimisalgoritmil, võimalikud väärtused: „AES”, „RSA” või „DSA”.
- key length — võtme pikkus baitides, AES: 16, 24 või 32, RSA: 128, 256, 512 ja DSA: 128, 256 või 384.
- kasutaja — võtme omanik. Kui võti on süsteemi oma, näiteks Master Key, siis see väli on tühi. Kui võti luuakse keyring_udf abil, siis see väli tähistab võtme omanikku.
- ise võtme
Võti on unikaalselt tuvastatav paari abil: key_id, user.
Samuti on erinevusi võtmete hoidmise ja kustutamise osas.
Failihaldus töötab kiiremini. Võib arvata, et võtmete hoidmine on lihtsalt võtme ühekordne salvestamine faili, kuid see pole nii — siin toimub rohkem toiminguid. Iga kord, kui failihalduses toimub muudatus, luuakse esmalt varukoopia kogu sisust. Oletame, et fail kannab nime my_biggest_secrets, siis varukoopia nimetatakse my_biggest_secrets.backup. Edasi muudetakse vahemälu (lisatakse või eemaldatakse võtmeid) ja kui kõik õnnestub, siis vahemälu kirjutatakse faili tagasi. Harvadel juhtudel, nagu serveri ebaõnnestumine, võite näha seda varukoopia faili. Varukoopia faili kustutatakse järgmise võtmete laadimise käigus (tavaliselt pärast serveri taaskäivitamist).
Klavi säilitamisel või kustutamisel peab serveri salvestus ühenduma MySQL serveriga, kasutades käske "saada võti" / "taotleda võtme kustutamist".
Naaseme serveri käivitamise kiiruseni. Lisaks sellele, et käivitamise kiirus sõltub salvestusest, on ka oluline küsimus, kui palju võtmeid salvestusest tuleb käivitamisel võtta. See on loomulikult eriti tähtis serveri salvestuste puhul. Käivitamisel kontrollib server, milline võti on vajalik krüptitud tabelite / tabeli ruumide jaoks ja küsib võtme salvestusest. "Puhta" serveri puhul, kus on Master Key - krüptimine peab olema üks Master Key, mis tuleb salvestusest välja võtta. Kuid võib olla vajalik ka rohkem võtmeid, näiteks kui varu serverile taastatakse varukoopia põhiserverilt. Sellistes olukordades tuleks ette näha Master Key rotatsioon. Selle kohta käsitletakse rohkem tulevikes artiklites, kuigi ma tahaksin siin märkida, et server, mis kasutab mitmeid Master Key, võib käivituda veidi kauem, eriti võtme salvestuse kasutamisel.
Nüüd räägime natuke lähemalt keyring_file'ist. Kui ma keyring_file'i arendasin, muretsesin ka selle üle, kuidas kontrollida keyring_file'i muudatusi serveri töö ajal. Versioonis 5.7 tehti kontroll failistatistika alusel, mis ei olnud ideaalne lahendus, ja versioonis 8.0 asendati see SHA256 kontrollsummaga.
Esimese käivitamise ajal arvutatakse keyring_file'i statistika ja kontrollsumma, mis salvestatakse serverisse, ning muudatusi rakendatakse ainult siis, kui need vastavad. Faili muutmisel uuendatakse kontrollsummat.
Oleme juba käsitlenud paljusid teemasid võtmehoidlate kohta. Kuid on veel üks oluline teema, mida sageli unustatakse või valesti mõistetakse — võtmete jagamine serverite vahel.
Mida ma silmas pean? Igal serveril (nt Percona Server) klastris peab olema Vault serveris eraldi koht, kus Percona Server peab oma võtmed hoidma. Igas Vaultis talletatud Master Key sisaldab GUID'i Percona Serveri identifikaatori sees. Miks see oluline on? Kujutage ette, et teil on ainult üks Vault Server ja kõik Percona Serverid klastris kasutavad seda ühte Vault Serverit. Probleem tundub olevat ilmne. Kui kõik Percona Serverid kasutaksid Master Keyd ilma ainulaadsete identifikaatoriteta, näiteks id = 1, id = 2 jne, kasutaksid kõik klastris olevad serverid sama Master Keyd. Mis tagabki GUID — eristuse serverite vahel. Miks siis rääkida võtmete jagamisest serverite vahel, kui juba eksisteerib ainulaadne GUID? On veel üks pistikprogramm — keyring_udf. Selle pistikprogrammi abil võib teie serveri kasutaja hoida oma võtmeid Vault serveris. Probleem tekib siis, kui kasutaja loob võtme, näiteks serveris server1, ja seejärel püüab luua võtme sama identifikaatoriga serveris server2, näiteks:
--server1:
select keyring_key_store('ROB_1','AES',"123456789012345");
1
--1 tähendab eduka lõpetamist
--server2:
select keyring_key_store('ROB_1','AES',"543210987654321");
1Palun oodake. Mõlemad serverid kasutavad sama Vault Serverit, kas keyring_key_store funktsioon ei tohiks serveris server2 lõpetada tõrget? Huvitav, et kui proovite sama teha ühel serveril, siis saate tõrke:
--server1:
select keyring_key_store('ROB_1','AES',"123456789012345");
1
select keyring_key_store('ROB_1','AES',"543210987654321");
0Õige, ROB_1 juba eksisteerib.
Arutame kõigepealt teist näidet. Nagu me varem mainisime, cached keyring_vault või mõni muu salvestuspesa (keyring) kõik võtmeidentifikaatorid mällu. Nii et pärast uue võtme loomist lisatakse ROB_1 serverisse server1, ja lisaks sellele, et saata see võti Vault'i, lisatakse võtme ka cache'i. Nüüd, kui üritame sama võtit teist korda lisada, kontrollib keyring_vault, kas see võti on cache'is olemas, ning tagastab tõrke.
Esimeses olukorras on olukord teine. Serveritel server1 ja server2 on eraldi vahemälud. Pärast ROB_1 klahvi lisamist serveri server1 ja Vault'i võtme vahemällu pole serveri server2 võtme vahemälu sünkroonitud. Serveri server2 vahemälus ei ole klahvi ROB_1. Seega salvestatakse klahv ROB_1 keyring_key_store'isse ja Vault'is, mis tõepoolest kirjutab (!) üle eelneva väärtuse. Nüüd on klahv ROB_1 Vault'is võrdne 543210987654321. Huvitav, et Vault ei blokeeri selliseid toiminguid ja kirjutab vanad väärtused lihtsalt üle.
Nüüd näeme, miks serverite kaupa eraldamine Vault'is võib olla oluline — kui kasutate keyring_udf-d ja soovite klahve Vault'is salvestada. Kuidas tagada selline eraldamine Vault'i serveris?
Vault'i eraldamiseks on kaks võimalust. Saate iga serveri jaoks luua erinevad montaažipunktid või kasutada erinevaid teid ühes montaažipunktis. Parim on seda näidata näidete kaudu. Alustame aga eraldi montaažipunktidest:
--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 = (...)Siit on näha, et server1 ja server2 kasutavad erinevaid mount-punkte. Tee jagamisel näeb konfiguratsioon välja järgmine:
--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 = (...)Selles olukorras kasutavad mõlemad serverid ühte ja sama mount-punkti „mount_point“, kuid erinevaid teid. Kui serveris server1 luuakse esimene saladus sellel teel, loob Vaulti server automaatselt katalooge „server1“. Server2 puhul on kõik samamoodi. Kui kustutate viimase saladuse mount_point/server1 või mount_point/server2, kustutab Vaulti server samuti need kataloogid. Kui kasutate teede jagamist, peate looma ainult ühe mount-punkti ja muutma konfiguratsioonifailid nii, et serverid kasutaksid eraldi teid. Mount-punkti saab luua HTTP-päringu kaudu. CURL-iga saab seda teha järgmiselt:
curl -L -H "X-Vault-Token: TOKEN" --cacert VAULT_CA
--data '{"type":"generic"}' --request POST VAULT_URL/v1/sys/mounts/SECRET_MOUNT_POINTKõik väljad (TOKEN, VAULT_CA, VAULT_URL, SECRET_MOUNT_POINT) vastavad konfiguratsioonifaili nõuetele. Loomulikult on võimalik kasutada Vault utiliite samu asju teha. Kuid nii on lihtsam automatiseerida montaažikoha loomist. Loodan, et see teave on teile kasulik ja näeme järgmistes artiklites sellest sarjast.
Loe edasi:
Allikas: habr.com
