V předvečer zahájení nového zápisu do kurzu připravili jsme pro vás překlad užitečného článku.

Transparentní šifrování dat (Transparent Data Encryption, TDE) se objevilo v MySQL už poměrně dlouho. Přemýšleli jste ale někdy o tom, jak funguje pod kapotou a jaký vliv může TDE mít na váš server? V této sérii článků se podíváme na to, jak TDE funguje uvnitř. Začneme ukládáním klíčů, protože je to nezbytné pro fungování jakéhokoli šifrování. Dále se podrobně podíváme na to, jak funguje šifrování v Percona Server for MySQL/MySQL a jaké další možnosti má Percona Server for MySQL.
MySQL Keyring
Keyring je plugin, který umožňuje serveru vyžadovat, vytvářet a mazat klíče v místním souboru (keyring_file) nebo na vzdáleném serveru (například v HashiCorp Vault). Klíče jsou vždy ukládány do mezipaměti lokálně, aby se urychlilo jejich získávání.
Pluginy lze rozdělit do dvou kategorií:
- Lokální úložiště. Například místní soubor (tomu říkáme úložiště klíčů založené na souboru, file-based keyring).
- Vzdálené úložiště. Například Vault Server (tomu říkáme úložiště klíčů na serveru, server-based keyring).
Toto rozdělení je důležité, protože různé typy úložišť se chovají poněkud odlišně nejen při ukládání a získávání klíčů, ale i při spuštění.
Při použití úložiště založeného na souboru se při spuštění do mezipaměti načte veškerý obsah úložiště: key id, key user, key type a samotný klíč.
V případě serverového úložiště (například server Vault) se při spuštění načítá pouze key id a key user, takže získání všech klíčů nezpomalí spuštění. Klíče se načítají lenivě. To znamená, že se samotný klíč načte z Vaultu pouze tehdy, když je skutečně potřeba. Po načtení je klíč uložen do mezipaměti, aby v budoucnu nebylo nutné se na něj obracet přes TLS spojení k Vault Serveru. Nyní se podíváme, jaké informace jsou obsaženy v úložišti klíčů.
Informace o klíči obsahují následující:
- key id — identifikátor klíče, například:
INNODBKey-764d382a-7324-11e9-ad8f-9cb6d0d5dc99-1 - key type — typ klíče, určený podle použitého šifrovacího algoritmu, možné hodnoty: „AES“, „RSA“ nebo „DSA“.
- key length — délka klíče v bajtech, AES: 16, 24 nebo 32, RSA 128, 256, 512 a DSA 128, 256 nebo 384.
- uživatel — vlastník klíče. Pokud je klíč systémový, například Master Key, je toto pole prázdné. Pokud je klíč vytvořen pomocí keyring_udf, toto pole označuje vlastníka klíče.
- samotný klíč
Klíč je jednoznačně identifikován dvojicí: key_id, user.
Existují také rozdíly ve skladování a odstraňování klíčů.
Pokladna souborů funguje rychleji. Dalo by se předpokládat, že pokladna klíčů je pouze jednoduchý jednorázový záznam klíče v souboru, ale není tomu tak — zde probíhá více operací. Při jakékoliv úpravě pokladny souborů se nejprve vytvoří záloha celého obsahu. Předpokládejme, že soubor se jmenuje my_biggest_secrets, pak záloha bude my_biggest_secrets.backup. Dále se upravuje cache (přidávají se nebo odstraňují klíče) a pokud vše proběhne úspěšně, cache se resetuje do souboru. Ve vzácných případech, jako je selhání serveru, můžete tento záložní soubor vidět. Záložní soubor se odstraní při následném načtení klíčů (obvykle po restartu serveru).
Při ukládání nebo odstraňování klíče v serverové pokladně se pokladna musí připojit k serveru MySQL s příkazy "odeslat klíč" / "žádat o odstranění klíče" ("send the key" / "request key deletion").
Vraťme se ke rychlosti spouštění serveru. Kromě toho, že na rychlost spouštění má vliv samotná pokladna, je zde také otázka, kolik klíčů je třeba z pokladny získat při spuštění. Samozřejmě, že to je zvláště důležité pro serverové pokladny. Při spuštění server zkontroluje, který klíč je potřebný pro šifrované tabulky / tabulková prostory a požaduje klíč z pokladny. Na "čistém" serveru s Master Key — šifrovaním by měl být jeden Master Key, který je třeba vyjmout z pokladny. Nicméně, může být zapotřebí i větší množství klíčů, například když se na záložním serveru obnovuje záloha z hlavního serveru. V takových případech by mělo být zváženo rotování Master Key. Podrobněji se tím budeme zabývat v budoucích článcích, přičemž bych zde chtěl poznamenat, že server používající několik Master Key může být spuštěn o něco déle, zejména při použití serverové pokladny klíčů.
Nyní si ještě pohovoříme o keyring_file. Když jsem vyvíjel keyring_file, také mě zajímalo, jak kontrolovat změnu keyring_file během provozu serveru. Ve verzi 5.7 byla kontrola prováděna na základě statistik souboru, což nebylo ideální řešení, a ve verzi 8.0 byla nahrazena kontrolním součtem SHA256.
Při prvním spuštění se v keyring_file vypočítají statistiky souboru a kontrolní součet, které si server zapamatuje, a změny se použijí pouze v případě, že se shodují. Při změně souboru se kontrolní součet aktualizuje.
Ji už jsme probrali mnohé otázky o úložištích klíčů. Existuje však ještě jedno důležité téma, na které se často zapomíná nebo které se špatně chápe — oddělení klíčů podle serverů.
Co tím myslím? Každý server (například Percona Server) v clusteru by měl mít vyhrazené místo na serveru Vault, kde by Percona Server měl uchovávat své klíče. V každém Master Key uloženém v úložišti se nachází GUID serveru Percona Server uvnitř jeho identifikátoru. Proč je to důležité? Představte si, že máte pouze jeden server Vault a všechny Percona servery v clusteru používají tento jediný server Vault. Problém se zdá být zřejmý. Kdyby všechny Percona servery používaly Master Key bez unikátních identifikátorů, například id = 1, id = 2 atd., pak by všechny servery v clusteru používaly stejný Master Key. Což je zajišťováno GUID — rozhraním mezi servery. Proč tedy hovořit o oddělení klíčů mezi servery, když už existuje unikátní GUID? Existuje ještě jeden plugin — keyring_udf. Pomocí tohoto pluginu může uživatel vašeho serveru uchovávat své klíče na serveru Vault. Problém nastává, když uživatel vytvoří klíč, například na serveru server1, a poté se pokusí vytvořit klíč se stejným identifikátorem na serveru server2, například:
--server1:
select keyring_key_store('ROB_1','AES',"123456789012345");
1
--1 znamená úspěšné dokončení
--server2:
select keyring_key_store('ROB_1','AES',"543210987654321");
1Počkejte. Oba servery používají stejný server Vault, neměla by funkce keyring_key_store na serveru server2 skončit chybou? Zajímavé je, že pokud se pokusíte to samé udělat na jednom serveru, dostanete chybu:
--server1:
select keyring_key_store('ROB_1','AES',"123456789012345");
1
select keyring_key_store('ROB_1','AES',"543210987654321");
0Správně, ROB_1 již existuje.
Nejprve si probereme druhý příklad. Jak jsme již dříve zmiňovali, keyring_vault nebo jakýkoli jiný plugin úložiště (keyring) ukládá všechny identifikátory klíčů do paměti. Jakmile tedy vytvoříme nový klíč, ROB_1 je přidán na server1, a kromě odeslání tohoto klíče do Vault, klíč je také přidán do cache. Nyní, když se pokoušíme přidat stejný klíč podruhé, keyring_vault kontroluje, zda tento klíč existuje v cache a vyhodí chybu.
V prvním případě je situace jiná. Na serverech server1 a server2 jsou oddělené cache. Po přidání ROB_1 do cache klíčů na serveru server1 a do serveru Vault, cache klíčů na server2 není synchronizována. V cache na server2 není klíč ROB_1. Jakmile to začne, klíč ROB_1 se zapíše do keyring_key_store a na server Vault, což v podstatě přepisuje (!) předchozí hodnotu. Nyní je klíč ROB_1 na serveru Vault roven 543210987654321. Je zajímavé, že server Vault neblokuje takové akce a bez problému přepisuje starou hodnotu.
Nyní vidíme, proč může být rozdělení podle serverů na Vault důležité — když používáte keyring_udf a chcete ukládat klíče do Vault. Jak zajistit takové rozdělení na serveru Vault?
Existují dva způsoby rozdělení na Vault. Můžete vytvořit různé body připojení pro každý server nebo použít různé cesty v rámci jednoho bodu připojení. Nejlépe to předvedeme na příkladech. Nejprve se podíváme na oddělené body připojení:
--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 = (...)Zde je vidět, že server1 a server2 používají různé body připojení. Při dělení cest bude konfigurace vypadat následovně:
--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 případě oba servery používají stejný bod připojení „mount_point“, ale různé cesty. Při vytvoření prvního tajemství na serveru server1 na této cestě server Vault automaticky vytvoří adresář „server1“. Pro server2 to platí stejně. Když odstraníte poslední tajemství v mount_point/server1 nebo mount_point/server2, server Vault také tyto adresáře odstraní. Pokud používáte rozdělení cest, měli byste vytvořit pouze jeden bod připojení a změnit konfigurační soubory, aby servery používaly oddělené cesty. Bod připojení lze vytvořit pomocí HTTP požadavku. Pomocí CURL to lze provést následujícím způsobem:
curl -L -H "X-Vault-Token: TOKEN" –cacert VAULT_CA
--data '{"type":"generic"}' --request POST VAULT_URL/v1/sys/mounts/SECRET_MOUNT_POINTVšechny pole (TOKEN, VAULT_CA, VAULT_URL, SECRET_MOUNT_POINT) odpovídají parametrům konfiguračního souboru. Samozřejmě můžete použít nástroje Vault, abyste udělali totéž. Ale takto je snadnější automatizovat vytvoření bodu připojení. Doufám, že vás tyto informace osloví, a setkáme se v dalších článcích této série.
Číst víc:
Zdroj: habr.com
