Šifrování v MySQL: Keystore

V očekávání zahájení nového zápisu do kurzu "Databáze" připravili pro vás překlad užitečného článku.

Šifrování v MySQL: Keystore

Objevilo se Transparent Data Encryption (TDE). Percona Server pro MySQL a MySQL už nějakou dobu. Ale přemýšleli jste někdy o tom, jak to funguje pod kapotou a jaký dopad může mít TDE na váš server? V této sérii článků se podíváme na to, jak TDE interně funguje. Začněme úložištěm klíčů, protože je vyžadováno pro fungování jakéhokoli šifrování. Poté se blíže podíváme na to, jak funguje šifrování v Percona Server pro MySQL/MySQL a jaké další funkce jsou dostupné v Percona Server pro MySQL.

Klíčenka MySQL

Klíčenky jsou zásuvné moduly, které umožňují serveru dotazovat se, vytvářet a odstraňovat klíče v místním souboru (soubor_klíče) nebo na vzdáleném serveru (například v HashiCorp Vault). Klíče jsou vždy lokálně ukládány do mezipaměti, aby se urychlilo načítání.

Pluginy lze rozdělit do dvou kategorií:

  • Místní úložiště. Například místní soubor (říkáme tomu souborový svazek klíčů).
  • vzdálené úložiště. Například Vault Server (říkáme tomu serverový svazek klíčů).

Toto oddělení je důležité, protože různé typy úložišť se chovají mírně odlišně nejen při ukládání a získávání klíčů, ale také při jejich spouštění.

Při použití úložiště souborů se veškerý obsah úložiště načte do mezipaměti při spuštění: ID klíče, uživatel klíče, typ klíče a samotný klíč.

V případě úložiště typu back-end (například server Vault) se při spuštění načte pouze ID klíče a uživatel klíče, takže získání všech klíčů spuštění nezpomalí. Klíče se načítají líně. To znamená, že samotný klíč se z Vaultu načte pouze tehdy, když je skutečně potřeba. Po stažení se klíč uloží do mezipaměti, takže v budoucnu k němu nebude potřeba přistupovat prostřednictvím připojení TLS k serveru Vault. Dále zvažte, jaké informace jsou přítomny v úložišti klíčů.

Klíčové informace obsahují následující:

  • id klíče - identifikátor klíče, například:
    INNODBKey-764d382a-7324-11e9-ad8f-9cb6d0d5dc99-1
  • typ klíče - typ klíče na základě použitého šifrovacího algoritmu, možné hodnoty: "AES", "RSA" nebo "DSA".
  • délka klíče - délka klíče v bajtech, AES: 16, 24 nebo 32, RSA 128, 256, 512 a DSA 128, 256 nebo 384.
  • uživatel je vlastníkem klíče. Pokud je klíčem systémový klíč, jako je hlavní klíč, je toto pole prázdné. Pokud je klíč vytvořen pomocí keyring_udf, pak toto pole označuje vlastníka klíče.
  • samotný klíč

Klíč je jednoznačně identifikován dvojicí: key_id, user.

Rozdíly jsou také v ukládání a mazání klíčů.

Ukládání souborů je rychlejší. Možná si myslíte, že úložiště klíčů je jen jednorázový zápis klíče do souboru, ale není tomu tak – tady se toho děje víc. Při každé úpravě úložiště souborů se nejprve zálohuje veškerý obsah. Řekněme, že soubor se jmenuje my_biggest_secrets, pak záloha bude my_biggest_secrets.backup. Dále se změní mezipaměť (klíče se přidají nebo odeberou) a pokud je vše úspěšné, vyrovnávací paměť se uloží do souboru. Ve vzácných případech, jako je selhání serveru, se může zobrazit tento záložní soubor. Záložní soubor se smaže při příštím načtení klíčů (obvykle po restartu serveru).

Při ukládání nebo mazání klíče v úložišti serveru se úložiště musí připojit k serveru MySQL pomocí příkazů "odeslat klíč" / "požádat o smazání klíče".

Vraťme se k rychlosti spouštění serveru. Kromě toho, že samotný trezor ovlivňuje rychlost spouštění, je zde také otázka, kolik klíčů z trezoru je potřeba při startu získat. To je samozřejmě důležité zejména pro serverová úložiště. Při spuštění server zkontroluje, který klíč je potřebný pro šifrované tabulky/tabulkové prostory, a vyžádá si klíč z úložiště. Na "čistém" serveru s hlavním klíčem - musí existovat jeden hlavní klíč pro šifrování, který je nutné získat z úložiště. Může však být vyžadováno více klíčů, například když se záloha z primárního serveru obnovuje na záložní server. V takových případech by měla být poskytnuta rotace hlavního klíče. To bude podrobněji diskutováno v budoucích článcích, i když zde bych rád zdůraznil, že spuštění serveru využívajícího více hlavních klíčů může trvat o něco déle, zejména při použití úložiště klíčů serveru.

Nyní si povíme něco více o keyring_file. Když jsem navrhoval soubor keyring_file, také mě zajímalo, jak zkontrolovat změny v souboru keyring_file, když je server spuštěný. Ve verzi 5.7 byla kontrola prováděna na základě statistiky souborů, což nebylo ideální, a ve verzi 8.0 byla nahrazena kontrolním součtem SHA256.

Při prvním spuštění keyring_file jsou statistiky souboru a kontrolní součet vypočteny a zapamatovány serverem a změny jsou aplikovány pouze v případě, že se shodují. Když se soubor změní, kontrolní součet se aktualizuje.

Již jsme probrali mnoho otázek týkajících se úložiště klíčů. Existuje však další důležité téma, na které se často zapomíná nebo je špatně pochopeno – sdílení klíčů mezi servery.

To, co mám na mysli? Každý server (například Percona Server) v clusteru musí mít samostatné umístění na serveru Vault Server, ve kterém musí Percona Server uložit své klíče. Každý hlavní klíč uložený v úschovně obsahuje GUID serveru Percona v rámci svého ID. Proč je to důležité? Představte si, že máte pouze jeden Vault Server a všechny servery Percona v clusteru používají tento jediný Vault Server. Problém se zdá zřejmý. Pokud by všechny servery Percona používaly hlavní klíč bez jedinečných identifikátorů, jako je id = 1, id = 2 atd., pak by všechny servery v clusteru používaly stejný hlavní klíč. To je to, co GUID poskytuje - rozdíl mezi servery. Proč tedy mluvit o sdílení klíčů mezi servery, když již existuje jedinečný GUID? Existuje další plugin - keyring_udf. Pomocí tohoto pluginu může uživatel vašeho serveru uložit své klíče na serveru Vault. Problém nastane, když uživatel vytvoří klíč, například na server1, a poté se pokusí vytvořit klíč se stejným ID na serveru2, například:

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

Počkejte. Oba servery používají stejný Vault Server, neměla by funkce keyring_key_store selhat na serveru2? Je zajímavé, že pokud se pokusíte udělat totéž na stejném serveru, zobrazí se chyba:

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

Správně, ROB_1 již existuje.

Nejprve proberme druhý příklad. Jak jsme řekli dříve, keyring_vault nebo jakýkoli jiný zásuvný modul vault (klíčenka) ukládá všechna ID klíčů do paměti. Po vytvoření nového klíče se tedy ROB_1 přidá na server1 a kromě odeslání tohoto klíče do úložiště je klíč přidán také do mezipaměti. Nyní, když se pokusíme přidat stejný klíč podruhé, keyring_vault zkontroluje, zda klíč existuje v mezipaměti, a vyvolá chybu.

V prvním případě je situace jiná. Server1 a server2 mají samostatné mezipaměti. Po přidání ROB_1 do mezipaměti klíčů na serveru1 a serveru úschovny není mezipaměť klíčů na serveru2 synchronizována. Mezipaměť na serveru2 neobsahuje klíč ROB_1. Klíč ROB_1 je tedy zapsán do úložiště klíčů_klíčů a na server Vault, čímž se ve skutečnosti přepíše (!) předchozí hodnota. Nyní je klíč ROB_1 na serveru Vault 543210987654321. Zajímavé je, že server Vault takové akce neblokuje a snadno přepíše starou hodnotu.

Nyní vidíme, proč může být segregace podle serveru ve Vaultu důležitá, když používáte keyring_udf a chcete ukládat klíče do Vaultu. Jak zajistit takové oddělení na serveru Vault?

Existují dva způsoby rozdělení na Vault. Pro každý server můžete vytvořit různé přípojné body nebo použít různé cesty v rámci stejného přípojného bodu. Nejlepší způsob, jak to ukázat, je na příkladech. Pojďme se tedy nejprve podívat na jednotlivé 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 můžete vidět, že server1 a server2 používají různé přípojné body. S oddělením cest bude konfigurace vypadat 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 případě oba servery používají stejný přípojný bod "mount_point", ale různé cesty. Když vytvoříte první tajný klíč na serveru1 pomocí této cesty, server úložiště automaticky vytvoří adresář „server1“. Pro server2 je vše stejné. Když odstraníte poslední tajný klíč v připojovacím_bodu/server1 nebo připojovacím_bodu/server2, server úschovny také odstraní tyto adresáře. V případě, že používáte rozdělené cesty, musíte vytvořit pouze jeden přípojný bod a změnit konfigurační soubory tak, aby servery používaly samostatné cesty. Přípojný bod lze vytvořit pomocí požadavku HTTP. S CURL to lze provést 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šechna pole (TOKEN, VAULT_CA, VAULT_URL, SECRET_MOUNT_POINT) odpovídají parametrům konfiguračního souboru. K tomu samozřejmě můžete použít nástroje Vault. Ale je jednodušší automatizovat vytvoření přípojného bodu. Doufám, že vám tyto informace pomohou a uvidíme se u dalších článků této série.

Šifrování v MySQL: Keystore

Přečtěte si více:

Zdroj: www.habr.com

Přidat komentář