Salaus MySQL:ssä: Keystore

Uuden kurssin ilmoittautumisen alkamista odotellessa "Tietokanta" Olemme laatineet sinulle käännöksen hyödyllisestä artikkelista.

Salaus MySQL:ssä: Keystore

Transparent Data Encryption (TDE) ilmestyi vuonna Percona Server MySQL:lle ja MySQL jo jonkin aikaa. Mutta oletko koskaan ajatellut, kuinka se toimii konepellin alla ja mikä vaikutus TDE:llä voi olla palvelimellesi? Tässä artikkelisarjassa tarkastellaan, kuinka TDE toimii sisäisesti. Aloitetaan avainten tallentamisesta, koska sitä tarvitaan, jotta mikä tahansa salaus toimii. Sitten tarkastellaan tarkemmin, kuinka salaus toimii Percona Server for MySQL/MySQL:ssä ja mitä lisäominaisuuksia Percona Server for MySQL sisältää.

MySQL avaimenperä

Keyring ovat laajennuksia, joiden avulla palvelin voi kysellä, luoda ja poistaa avaimia paikallisessa tiedostossa (keyring_file) tai etäpalvelimessa (kuten HashiCorp Vault). Avaimet tallennetaan aina paikallisesti välimuistiin niiden hakemisen nopeuttamiseksi.

Pluginit voidaan jakaa kahteen luokkaan:

  • Paikallinen varasto. Esimerkiksi paikallinen tiedosto (kutsumme tätä tiedostopohjaiseksi avaimenperäksi).
  • Etävarasto. Esimerkiksi Holvipalvelin (kutsumme tätä palvelinpohjaiseksi avaimenperäksi).

Tämä erottelu on tärkeä, koska erityyppiset tallennustilat käyttäytyvät hieman eri tavalla, ei vain avaimia tallennettaessa ja noudettaessa, vaan myös niitä käytettäessä.

Tiedostomuistia käytettäessä tallennustilan koko sisältö ladataan käynnistyksen yhteydessä välimuistiin: avaimen tunnus, avaimen käyttäjä, avaimen tyyppi ja itse avain.

Palvelinpuolen myymälän (kuten Vault Server) tapauksessa vain avaimen tunnus ja avainkäyttäjä ladataan käynnistyksen yhteydessä, joten kaikkien avainten hankkiminen ei hidasta käynnistystä. Avaimet ladataan laiskasti. Eli itse avain ladataan Holvista vain silloin, kun sitä todella tarvitaan. Kun avain on ladattu, se tallennetaan välimuistiin, jotta sitä ei tarvitse käyttää TLS-yhteyksien kautta Vault-palvelimeen tulevaisuudessa. Katsotaan seuraavaksi, mitä tietoja avainsäilössä on.

Keskeiset tiedot sisältävät seuraavat tiedot:

  • avaimen tunnus — avaimen tunniste, esimerkiksi:
    INNODBKey-764d382a-7324-11e9-ad8f-9cb6d0d5dc99-1
  • avaimen tyyppi — käytettyyn salausalgoritmiin perustuva avaintyyppi, mahdolliset arvot: "AES", "RSA" tai "DSA".
  • näppäimen pituus — avaimen pituus tavuina, AES: 16, 24 tai 32, RSA 128, 256, 512 ja DSA 128, 256 tai 384.
  • lähettämä - avaimen omistaja. Jos avain on järjestelmä, esimerkiksi Master Key, tämä kenttä on tyhjä. Jos avain luodaan käyttämällä avainrengas_udf:a, tämä kenttä identifioi avaimen omistajan.
  • itse avain

Avain tunnistetaan yksilöllisesti parilla: key_id, user.

Myös avainten tallentamisessa ja poistamisessa on eroja.

Tiedostojen tallennus on nopeampaa. Saatat ajatella, että avainsäilö yksinkertaisesti kirjoittaa avaimen tiedostoon kerran, mutta ei, täällä tapahtuu muutakin. Aina kun tiedostoa muutetaan, kaikesta sisällöstä luodaan ensin varmuuskopio. Oletetaan, että tiedoston nimi on my_biggest_secrets, jolloin varmuuskopio on my_biggest_secrets.backup. Seuraavaksi välimuistia muutetaan (avaimet lisätään tai poistetaan) ja jos kaikki onnistuu, välimuisti palautetaan tiedostoksi. Harvinaisissa tapauksissa, kuten palvelinvirheessä, saatat nähdä tämän varmuuskopiotiedoston. Varmuuskopiotiedosto poistetaan, kun avaimet ladataan seuraavan kerran (yleensä palvelimen uudelleenkäynnistyksen jälkeen).

Kun tallennat tai poistat avaimen palvelinmuistiin, tallennustilan tulee muodostaa yhteys MySQL-palvelimeen komennoilla "lähetä avain" / "pyydä avaimen poistoa".

Palataan palvelimen käynnistysnopeuteen. Sen lisäksi, että laukaisunopeuteen vaikuttaa itse varasto, on myös kysymys siitä, kuinka monta avainta varastosta on haettava käynnistyksen yhteydessä. Tämä on tietysti erityisen tärkeää palvelimen tallennuksen kannalta. Käynnistettäessä palvelin tarkistaa, mitä avainta tarvitaan salatuille taulukoille/taulukkotiloille ja pyytää avainta tallennustilasta. "Puhtaalla" palvelimella, jossa on pääavaimen salaus, on oltava yksi pääavain, joka on haettava tallennustilasta. Suurempi määrä avaimia voidaan kuitenkin tarvita esimerkiksi silloin, kun varmuuskopiopalvelin palauttaa varmuuskopion ensisijaiselta palvelimelta. Tällaisissa tapauksissa pääavaimen kierto tulee järjestää. Tätä käsitellään yksityiskohtaisemmin tulevissa artikkeleissa, vaikka tässä haluaisinkin huomauttaa, että useita pääavaimia käyttävän palvelimen käynnistyminen voi kestää hieman kauemmin, etenkin käytettäessä palvelinpuolen avainsäilöä.

Puhutaanpa nyt hieman enemmän keyring_file-tiedostosta. Kun kehitin keyring_file-tiedostoa, olin myös huolissani siitä, kuinka tarkistaa avainrengastiedoston muutokset palvelimen ollessa käynnissä. 5.7:ssä tarkistus tehtiin tiedostotilastojen perusteella, mikä ei ollut ihanteellinen ratkaisu, ja 8.0:ssa se korvattiin SHA256-tarkistussummalla.

Kun suoritat avaimenperän_tiedoston ensimmäisen kerran, tiedostotilastot ja tarkistussumma lasketaan, jotka palvelin muistaa, ja muutokset otetaan käyttöön vain, jos ne täsmäävät. Kun tiedosto muuttuu, tarkistussumma päivitetään.

Olemme jo käsitelleet monia avainholveja koskevia kysymyksiä. On kuitenkin toinen tärkeä aihe, joka usein unohdetaan tai ymmärretään väärin: avainten jakaminen palvelimien välillä.

Mitä tarkoitan? Jokaisella klusterin palvelimella (esimerkiksi Percona Serverillä) on oltava erillinen sijainti Vault-palvelimella, johon Percona Serverin on tallennettava avaimensa. Jokainen tallennustilaan tallennettu pääavain sisältää Percona-palvelimen GUID-tunnuksen tunnisteessaan. Miksi se on tärkeää? Kuvittele, että sinulla on vain yksi Vault-palvelin ja kaikki klusterin Percona-palvelimet käyttävät tätä yhtä Vault-palvelinta. Ongelma näyttää ilmeiseltä. Jos kaikki Percona-palvelimet käyttäisivät pääavainta ilman yksilöllisiä tunnisteita, kuten id = 1, id = 2 jne., kaikki klusterin palvelimet käyttäisivät samaa pääavainta. GUID tarjoaa eron palvelimien välillä. Miksi sitten puhua avainten jakamisesta palvelimien välillä, jos yksilöllinen GUID on jo olemassa? On toinen laajennus - keyring_udf. Tämän laajennuksen avulla palvelimesi käyttäjä voi tallentaa avaimensa Vault-palvelimelle. Ongelma ilmenee, kun käyttäjä luo avaimen esimerkiksi palvelimelle 1 ja yrittää sitten luoda avaimen samalla tunnuksella palvelimelle 2, esimerkiksi:

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

Odota. Molemmat palvelimet käyttävät samaa Holvipalvelinta. Eikö keyring_key_store-funktion pitäisi epäonnistua palvelimella 2? Mielenkiintoista on, että jos yrität tehdä saman yhdellä palvelimella, saat virheilmoituksen:

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

Aivan oikein, ROB_1 on jo olemassa.

Keskustellaan ensin toisesta esimerkistä. Kuten aiemmin sanoimme, keyring_vault tai mikä tahansa muu avaimenperälaajennus tallentaa kaikki muistissa olevat avaintunnukset välimuistiin. Joten uuden avaimen luomisen jälkeen ROB_1 lisätään palvelimeen 1, ja sen lisäksi, että tämä avain lähetetään Holviin, avain lisätään myös välimuistiin. Nyt kun yritämme lisätä saman avaimen toisen kerran, keyring_vault tarkistaa, onko avain olemassa välimuistissa ja antaa virheilmoituksen.

Ensimmäisessä tapauksessa tilanne on toinen. Palvelimella1 ja palvelimella2 on erilliset välimuistit. Kun ROB_1 on lisätty palvelimen1 ja Vault-palvelimen avainvälimuistiin, palvelimen2 avainvälimuisti ei ole synkronoitu. Server2:n välimuistissa ei ole ROB_1-avainta. Siten ROB_1-avain kirjoitetaan avaimenperän_avainvarastoon ja Vault-palvelimeen, joka itse asiassa korvaa (!) edellisen arvon. Nyt Vault-palvelimen ROB_1-avain on 543210987654321. Mielenkiintoista on, että Vault-palvelin ei estä tällaisia ​​toimia ja korvaa helposti vanhan arvon.

Nyt voimme nähdä, miksi palvelimen osiointi Holvissa voi olla tärkeää - kun käytät keyring_udf-tiedostoa ja haluat tallentaa avaimet Holviin. Kuinka saavuttaa tämä erottelu Vault-palvelimella?

On kaksi tapaa osioida Holviin. Voit luoda eri liitospisteitä kullekin palvelimelle tai käyttää eri polkuja saman liitoskohdan sisällä. Tämä havainnollistetaan parhaiten esimerkein. Katsotaanpa siis ensin yksittäisiä kiinnityspisteitä:

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

Tästä näet, että palvelin1 ja palvelin2 käyttävät eri liitoskohtia. Kun polkuja jaetaan, kokoonpano näyttää tältä:

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

Tässä tapauksessa molemmat palvelimet käyttävät samaa liitoskohtaa "mount_point", mutta eri polkuja. Kun luot ensimmäisen salaisuuden palvelimelle 1 käyttämällä tätä polkua, Vault-palvelin luo automaattisesti "palvelin1"-hakemiston. Server2:lla kaikki on samanlaista. Kun poistat viimeisen salaisuuden hakemistosta mount_point/server1 tai mount_point/server2, Vault-palvelin poistaa myös kyseiset hakemistot. Jos käytät polkuerottelua, sinun on luotava vain yksi liitoskohta ja muutettava kokoonpanotiedostot siten, että palvelimet käyttävät eri polkuja. Liitäntäpiste voidaan luoda HTTP-pyynnön avulla. Käyttämällä CURL-osoitetta tämä voidaan tehdä seuraavasti:

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

Kaikki kentät (TOKEN, VAULT_CA, VAULT_URL, SECRET_MOUNT_POINT) vastaavat määritystiedoston parametreja. Tietenkin voit käyttää Vault-apuohjelmia tehdäksesi saman. Mutta on helpompi automatisoida liitospisteen luominen. Toivottavasti näistä tiedoista on hyötyä, ja näemme sinut tämän sarjan seuraavissa artikkeleissa.

Salaus MySQL:ssä: Keystore

Lue lisää:

Lähde: will.com

Lisää kommentti