Šifrovanie v MySQL: Keystore

V očakávaní začiatku nového zápisu do kurzu "databáza" pripravili pre vás preklad užitočného článku.

Šifrovanie v MySQL: Keystore

Objavilo sa Transparent Data Encryption (TDE). Server Percona pre MySQL a MySQL už nejaký čas. Zamysleli ste sa však niekedy nad tým, ako to funguje pod kapotou a aký vplyv môže mať TDE na váš server? V tejto sérii článkov sa pozrieme na to, ako TDE interne funguje. Začnime s ukladaním kľúčov, pretože je potrebné na fungovanie akéhokoľvek šifrovania. Potom sa bližšie pozrieme na to, ako funguje šifrovanie v Percona Server pre MySQL/MySQL a aké ďalšie funkcie sú dostupné v Percona Server pre MySQL.

Kľúčenka MySQL

Kľúčenky sú zásuvné moduly, ktoré umožňujú serveru dopytovať, vytvárať a odstraňovať kľúče v lokálnom súbore (súbor_ kľúča) alebo na vzdialenom serveri (napríklad v HashiCorp Vault). Kľúče sa vždy ukladajú do lokálnej vyrovnávacej pamäte, aby sa urýchlilo vyhľadávanie.

Pluginy možno rozdeliť do dvoch kategórií:

  • Lokálny obchod. Napríklad lokálny súbor (nazývame ho súbor kľúčov).
  • vzdialené úložisko. Napríklad server Vault (nazývame ho zväzok kľúčov založený na serveri).

Toto oddelenie je dôležité, pretože rôzne typy úložísk sa správajú mierne odlišne nielen pri ukladaní a získavaní kľúčov, ale aj pri ich spustení.

Pri použití úložiska súborov sa všetok obsah úložiska načíta do vyrovnávacej pamäte pri spustení: ID kľúča, používateľ kľúča, typ kľúča a samotný kľúč.

V prípade koncového obchodu (napríklad server Vault) sa pri spustení načíta iba ID kľúča a používateľ kľúča, takže získanie všetkých kľúčov spustenie nespomalí. Kľúče sa načítavajú lenivo. To znamená, že samotný kľúč sa z Vaultu načíta iba vtedy, keď je skutočne potrebný. Po stiahnutí sa kľúč uloží do vyrovnávacej pamäte, takže v budúcnosti k nemu nebude potrebné pristupovať prostredníctvom pripojení TLS k serveru Vault. Ďalej zvážte, aké informácie sa nachádzajú v úložisku kľúčov.

Kľúčové informácie obsahujú nasledovné:

  • ID kľúča - kľúčový identifikátor, napríklad:
    INNODBKey-764d382a-7324-11e9-ad8f-9cb6d0d5dc99-1
  • typ kľúča - typ kľúča založený na použitom šifrovacom algoritme, možné hodnoty: "AES", "RSA" alebo "DSA".
  • dĺžka kľúča - dĺžka kľúča v bajtoch, AES: 16, 24 alebo 32, RSA 128, 256, 512 a DSA 128, 256 alebo 384.
  • užívateľ je vlastníkom kľúča. Ak je kľúčom systémový kľúč, ako je hlavný kľúč, potom je toto pole prázdne. Ak je kľúč vytvorený pomocou keyring_udf, potom toto pole označuje vlastníka kľúča.
  • samotný kľúč

Kľúč je jednoznačne identifikovaný dvojicou: key_id, user.

Rozdiely sú aj v ukladaní a odstraňovaní kľúčov.

Ukladanie súborov je rýchlejšie. Môžete si myslieť, že úložisko kľúčov je len jednorazový zápis kľúča do súboru, ale nie je to tak – tu sa toho deje viac. Vždy, keď sa upraví úložisko súborov, všetok obsah sa najskôr zálohuje. Povedzme, že súbor sa volá my_biggest_secrets, potom bude záloha my_biggest_secrets.backup. Ďalej sa zmení vyrovnávacia pamäť (kľúče sa pridajú alebo odstránia) a ak je všetko úspešné, vyrovnávacia pamäť sa uloží do súboru. V zriedkavých prípadoch, ako je zlyhanie servera, sa môže zobraziť tento záložný súbor. Záložný súbor sa vymaže pri ďalšom načítaní kľúčov (zvyčajne po reštarte servera).

Pri ukladaní alebo odstraňovaní kľúča v úložisku servera sa obchod musí pripojiť k serveru MySQL pomocou príkazov „odoslať kľúč“ / „požiadať o vymazanie kľúča“.

Vráťme sa k rýchlosti spúšťania servera. Okrem toho, že samotný trezor ovplyvňuje rýchlosť spúšťania, je tu aj otázka, koľko kľúčov z trezoru je potrebné pri spustení získať. Samozrejme, toto je obzvlášť dôležité pre serverové úložiská. Pri spustení server skontroluje, ktorý kľúč je potrebný pre šifrované tabuľky/tabuľkové priestory a vyžiada kľúč z úložného priestoru. Na "čistom" serveri s hlavným kľúčom - musí existovať jeden hlavný kľúč na šifrovanie, ktorý je potrebné získať z úložiska. Môže však byť potrebných viac kľúčov, napríklad keď sa záloha z primárneho servera obnoví na záložný server. V takýchto prípadoch by sa malo poskytnúť rotovanie hlavného kľúča. Toto bude podrobnejšie diskutované v budúcich článkoch, aj keď tu by som rád poznamenal, že spustenie servera s viacerými hlavnými kľúčmi môže trvať trochu dlhšie, najmä ak používate úložisko kľúčov servera.

Teraz si povedzme trochu viac o keyring_file. Keď som navrhoval súbor keyring_file, zaujímalo ma aj to, ako skontrolovať zmeny súboru keyring_file, keď je server spustený. V 5.7 bola kontrola vykonaná na základe štatistiky súborov, čo nebolo ideálne a v 8.0 bola nahradená kontrolným súčtom SHA256.

Pri prvom spustení súboru keyring_file sa štatistika súboru a kontrolný súčet vypočítajú a zapamätajú si server a zmeny sa aplikujú iba vtedy, ak sa zhodujú. Keď sa súbor zmení, kontrolný súčet sa aktualizuje.

Už sme sa zaoberali mnohými otázkami o úložiskách kľúčov. Existuje však ďalšia dôležitá téma, na ktorú sa často zabúda alebo sa jej nerozumie – zdieľanie kľúčov medzi servermi.

To, čo mám na mysli? Každý server (napríklad server Percona) v klastri musí mať samostatné umiestnenie na serveri úschovne, v ktorom musí server Percona uložiť svoje kľúče. Každý hlavný kľúč uložený v trezore obsahuje GUID servera Percona v rámci svojho ID. Prečo je to dôležité? Predstavte si, že máte iba jeden Vault Server a všetky servery Percona v klastri používajú tento jeden Vault Server. Zdá sa, že problém je zrejmý. Ak by všetky servery Percona používali hlavný kľúč bez jedinečných identifikátorov, ako napríklad id = 1, id = 2 atď., všetky servery v klastri by používali rovnaký hlavný kľúč. Toto poskytuje GUID - rozdiel medzi servermi. Prečo potom hovoriť o zdieľaní kľúčov medzi servermi, ak už existuje jedinečný identifikátor GUID? Existuje ďalší plugin - keyring_udf. Pomocou tohto doplnku môže používateľ vášho servera uložiť svoje kľúče na serveri Vault. Problém nastane, keď používateľ vytvorí kľúč, napríklad na serveri1, a potom sa pokúsi vytvoriť kľúč s rovnakým ID na serveri2, napríklad:

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

počkaj. Oba servery používajú rovnaký Vault Server, nemala by funkcia keyring_key_store zlyhať na serveri2? Je zaujímavé, že ak sa pokúsite urobiť to isté na rovnakom serveri, zobrazí sa chyba:

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

Správne, ROB_1 už existuje.

Poďme najprv diskutovať o druhom príklade. Ako sme už povedali, keyring_vault alebo akýkoľvek iný doplnok trezora (kľúčový zväzok) ukladá všetky ID kľúčov do pamäte. Takže po vytvorení nového kľúča sa ROB_1 pridá na server1 a okrem odoslania tohto kľúča do Vaultu sa kľúč pridá aj do vyrovnávacej pamäte. Teraz, keď sa pokúsime pridať rovnaký kľúč druhýkrát, keyring_vault skontroluje, či kľúč existuje vo vyrovnávacej pamäti a vyvolá chybu.

V prvom prípade je situácia iná. Server1 a server2 majú samostatné vyrovnávacie pamäte. Po pridaní ROB_1 do vyrovnávacej pamäte kľúčov na serveri1 a serveri Vault nie je vyrovnávacia pamäť kľúčov na serveri2 synchronizovaná. Vyrovnávacia pamäť na serveri2 neobsahuje kľúč ROB_1. Kľúč ROB_1 sa teda zapíše do úložiska kľúčov kľúčov a na server Vault, čím sa v skutočnosti prepíše (!) predchádzajúca hodnota. Teraz je kľúč ROB_1 na serveri Vault 543210987654321. Zaujímavé je, že server Vault takéto akcie neblokuje a starú hodnotu ľahko prepíše.

Teraz vidíme, prečo môže byť segregácia podľa servera vo Vaulte dôležitá, keď používate keyring_udf a chcete uložiť kľúče do Vaultu. Ako zabezpečiť takéto oddelenie na serveri Vault?

Existujú dva spôsoby rozdelenia na Vault. Môžete vytvoriť rôzne body pripojenia pre každý server alebo použiť rôzne cesty v rámci toho istého bodu pripojenia. Najlepší spôsob, ako to ukázať, sú príklady. Poďme sa teda najprv pozrieť na jednotlivé body pripojenia:

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

Tu môžete vidieť, že server1 a server2 používajú rôzne body pripojenia. S oddelením ciest bude konfigurácia vyzerať takto:

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

V tomto prípade oba servery používajú rovnaký bod pripojenia "mount_point", ale rôzne cesty. Keď vytvoríte prvé tajomstvo na serveri1 pomocou tejto cesty, server Vault automaticky vytvorí adresár „server1“. Pre server2 je všetko rovnaké. Keď vymažete posledný tajný kľúč v mount_point/server1 alebo mount_point/server2, server Vault vymaže aj tieto adresáre. V prípade, že používate rozdelené cesty, musíte vytvoriť iba jeden bod pripojenia a zmeniť konfiguračné súbory tak, aby servery používali oddelené cesty. Prípojný bod je možné vytvoriť pomocou požiadavky HTTP. S CURL to možno urobiť takto:

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

Všetky polia (TOKEN, VAULT_CA, VAULT_URL, SECRET_MOUNT_POINT) zodpovedajú parametrom konfiguračného súboru. Samozrejme, na to isté môžete použiť nástroje Vault. Jednoduchšie je však automatizovať vytváranie bodu pripojenia. Dúfam, že vám tieto informácie pomôžu a uvidíme sa pri ďalších článkoch tejto série.

Šifrovanie v MySQL: Keystore

Čítaj viac:

Zdroj: hab.com

Pridať komentár