Az új kurzus indítása előtt Összeállítottuk önöknek a hasznos cikk fordítását.

A Transparent Data Encryption (TDE) már régóta létezik a és MySQL esetében. De vajon elgondolkodott már azon, hogy hogyan működik a háttérben, és milyen hatással lehet a TDE a szerverére? Ebben a cikk sorozatban megvizsgáljuk, hogyan működik a TDE a háttérben. Kezdjük a kulcsok tárolásával, mivel ez szükséges a titkosítás bármilyen formájához. Ezután részletesen áttekintjük, hogyan működik a titkosítás a Percona Server for MySQL/MySQL esetében, és milyen további lehetőségek vannak a Percona Server for MySQL-ban.
MySQL Keyring
A Keyring olyan pluginek, amelyek lehetővé teszik a szerver számára, hogy kulcsokat kérdezzen le, hozzon létre és töröljön egy helyi fájlban (keyring_file) vagy egy távoli szerveren (például a HashiCorp Vault-on). A kulcsokat mindig helyben tárolják, hogy felgyorsítsák azok lekérését.
A plugineket két kategóriára lehet osztani:
- Helyi tároló. Például egy helyi fájl (ezt hívjuk fájl alapú kulcstárolónak, file-based keyring).
- Távoli tároló. Például Vault Server (ezt hívjuk szerver alapú kulcstárolónak, server-based keyring).
Ez a megkülönböztetés fontos, mivel a különböző tárolótípusok kissé eltérően viselkednek, nemcsak a kulcsok tárolása és lekérése során, hanem a betöltéskor is.
Helyi tároló használatakor a betöltés során az összes tároló tartalma betöltődik a gyorsítótárba: key id, key user, key type és maga a kulcs.
Szerver tároló esetén (például Vault Server) a betöltés során csak a key id és key user kerül betöltésre, ezért a kulcsok lekérése nem lassítja a betöltést. A kulcsokat lustán töltjük be. Ez azt jelenti, hogy a kulcsot a Vaultból csak akkor töltjük ki, amikor ténylegesen szükség van rá. A betöltés után a kulcs a memóriában tárolódik, hogy a jövőben ne kelljen TLS kapcsolatokon keresztül lekérni a Vault Servertől. Nézzük meg, milyen információk találhatók a kulcstárolóban.
A kulcsról szóló információk a következőket tartalmazzák:
- key id — a kulcs azonosítója, például:
INNODBKey-764d382a-7324-11e9-ad8f-9cb6d0d5dc99-1 - key type — a kulcs típusa, amely a használt titkosítási algoritmus alapján áll össze, lehetséges értékek: „AES”, „RSA” vagy „DSA”.
- key length — a kulcs hossza byte-okban, AES: 16, 24 vagy 32, RSA 128, 256, 512 és DSA 128, 256 vagy 384.
- user — a kulcs tulajdonosa. Ha a kulcs rendszerkulcs, például Master Key, akkor ez a mező üres. Ha a kulcs a keyring_udf használatával jön létre, akkor ez a mező jelzi a kulcs tulajdonosát.
- maga a kulcs
A kulcs egyértelműen azonosítható a key_id, user párral.
A kulcsok tárolásában és törlésében is vannak eltérések.
A fájltároló gyorsabban működik. Feltételezhetnénk, hogy a kulcstartó egy egyszerű egyedi kulcs írása egy fájlba, de nem — itt több művelet történik. Bármilyen módosítás előtt a fájltároló egy biztonsági másolatot készít a teljes tartalomról. Mondjuk a fájl neve my_biggest_secrets, akkor a biztonsági másolat my_biggest_secrets.backup néven jön létre. Ezután a gyorsítótár módosul (kulcsok hozzáadása vagy eltávolítása), és ha minden sikeresen megtörténik, a gyorsítótár kiírásra kerül a fájlba. Ritka esetekben, például szerverhibák során, láthatjuk ezt a biztonsági másolatot. A biztonsági másolat a kulcsok következő betöltésekor törlődik (általában a szerver újraindítása után).
Amikor kulcsot mentenek vagy törölnek a szerver tárolójában, a tárolónak csatlakoznia kell a MySQL szerverhez a "kulcs küldése" / "kulcs törlésének kérése" paranccsal.
Térjünk vissza a szerver indítási sebességére. A tárolón kívül a legfontosabb kérdés, hogy indításkor hány kulcsot kell lekérni a tárolóból. Persze, ez különösen fontos szerverhordozók esetén. Indításkor a szerver ellenőrzi, hogy melyik kulcs szükséges a titkosított táblák/táblaterekhez, és lekéri a kulcsot a tárolóból. Egy „tisztán” Master Key — titkosítással rendelkező szerveren egy Master Key kell, amelyet ki kell nyerni a tárolóból. Azonban több kulcsra is szükség lehet, például amikor egy tartalék szerver állít vissza egy biztonsági másolatot az alap szerverről. Ilyen esetekben érdemes előre gondoskodni a Master Key rotálásáról. Ezzel részletesebben a jövőbeli cikkekben foglalkozunk, bár itt szeretném megjegyezni, hogy a több Master Key-t használó szerverek indítása kissé tovább tarthat, különösen, ha szerver tárolót használnak.
Most beszéljünk egy kicsit a keyring_file-ról. Amikor a keyring_file-t fejlesztettem, engem is aggasztott, hogyan ellenőrizzük a keyring_file megváltozását a szerver működése során. Az 5.7 verzióban a fájl statisztikái alapján történt az ellenőrzés, ami nem volt tökéletes megoldás, és az 8.0-ás verzióban SHA256 ellenőrző összeggel helyettesítették.
Az első indításkor a keyring_file kiszámolja a fájl statisztikáit és az ellenőrző összeget, amelyeket a szerver megjegyez, és a módosítások csak akkor lépnek érvénybe, ha azok megfelelnek. A fájl módosítása esetén az ellenőrző összeg frissül.
Már számos kérdést megvizsgáltunk a kulcstárolókkal kapcsolatban. Van azonban még egy fontos téma, amelyet gyakran elfelejtenek vagy félreértenek — a kulcsok elválasztása a szerverek között.
Mit értek ezalatt? Minden szerver (például a Percona Server) klaszterben külön helyet kell, hogy kapjon a Vault szerveren, ahol a Percona Server tárolhatja a kulcsait. Minden Master Key, amely a tárolóban van, tartalmazza a Percona Server GUID-ját saját azonosítóján belül. Miért fontos ez? Képzelje el, hogy van egyetlen Vault Server és minden Percona Server a klaszterben ezt az egyetlen Vault Szervert használja. A probléma világosnak tűnik. Ha minden Percona Server egy Master Key-t használt volna egyedi azonosítók nélkül, például id = 1, id = 2 stb., akkor minden szerver a klaszterben ugyanazt a Master Key-t használná. Ezért van szükség a GUID-ra — a szerverek közötti elhatárolásra. Miért beszélünk tehát a kulcsok elválasztásáról a szerverek között, ha már létezik egy egyedi GUID? Van még egy plugin — keyring_udf. Ezzel a pluginnal a szerver felhasználója tárolhatja kulcsait a Vault szerveren. A probléma akkor merül fel, amikor a felhasználó kulcsot hoz létre például a server1-en, majd megpróbál egy azonos azonosítóval kulcsot létrehozni a server2-n, például:
--server1:
select keyring_key_store('ROB_1','AES',"123456789012345");
1
--1 a sikeres befejezést jelenti
--server2:
select keyring_key_store('ROB_1','AES',"543210987654321");
1Várjon. Mindkét szerver ugyanazt a Vault Szervert használja, nem kéne, hogy a keyring_key_store függvény hibával záruljon a server2-n? Érdekes, hogy ha ugyanezt próbálja meg egyetlen szerveren, hibát kap:
--server1:
select keyring_key_store('ROB_1','AES',"123456789012345");
1
select keyring_key_store('ROB_1','AES',"543210987654321");
0Igen, a ROB_1 már létezik.
Először beszéljünk a második példáról. Ahogy korábban említettük, a keyring_vault vagy bármely más tároló plugin (keyring) minden kulcsazonosítót a memóriában cache-el. Így, miután egy új kulcsot létrehoztunk, a ROB_1 hozzáadódik a server1-hez, és ahelyett, hogy ezt a kulcsot a Vault-ba küldenénk, a kulcs is hozzáadódik a cache-hez. Most, amikor megpróbálunk egy ugyanilyen kulcsot másodszor hozzáadni, a keyring_vault ellenőrzi, hogy ez a kulcs létezik-e a cache-ben, és hibát ad vissza.
Az első esetben a helyzet más. A server1 és server2 külön cache-ekkel rendelkezik. Miután a ROB_1 hozzá lett adva a kulcsok cache-éhez a server1-en és a Vault szerverhez, a server2 kulcs-cache-e nincs szinkronizálva. A server2 cache-ében nincs ROB_1 kulcs. Így a ROB_1 kulcs a keyring_key_store-ba és a Vault szerverre kerül, ami lényegében felülírja (!) a korábbi értéket. Most a ROB_1 kulcs a Vault szerveren 543210987654321-et ér el. Érdekes, hogy a Vault szerver nem blokkolja az ilyen műveleteket, és simán felülírja a régi értéket.
Most látjuk, miért lehet fontos a szerverek közötti elkülönítés a Vault-nál — amikor a keyring_udf-t használod, és kulcsokat szeretnél tárolni a Vault-ban. Hogyan biztosítható ez az elkülönítés a Vault szerveren?
Két módja van az elkülönítésnek a Vault-nál. Különböző mount pontokat hozhatsz létre minden szerver számára, vagy különböző utakat használhatsz egyetlen mount ponton belül. A legjobban példákon keresztül tudjuk ezt bemutatni. Tehát nézzük meg először a különálló mount pontokat:
--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 = (...)Itt látható, hogy a server1 és server2 különböző mount pontokat használnak. Az utak elkülönítésekor a konfiguráció a következőképpen fog kinézni:
--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 = (...)Ebben az esetben mindkét szerver ugyanazt a "mount_point" mountolási pontot használja, de eltérő útvonalakat. Amikor az első titkot létrehozza az server1 szerveren ezen az útvonalon, a Vault szerver automatikusan létrehozza a "server1" könyvtárt. A server2 esetében minden hasonló. Amikor törli az utolsó titkot a mount_point/server1 vagy mount_point/server2 alatt, a Vault szerver is törli ezeket a könyvtárakat. Ha útvonalmegosztást használ, csak egyetlen mountolási pontot kell létrehoznia, és módosítania kell a konfigurációs fájlokat, hogy a szerverek különböző útvonalakat használjanak. A mountolási pontot HTTP-kérés segítségével hozhatja létre. CURL-lal a következőképpen teheti ezt meg:
curl -L -H "X-Vault-Token: TOKEN" –cacert VAULT_CA
--data '{"type":"generic"}' --request POST VAULT_URL/v1/sys/mounts/SECRET_MOUNT_POINTMinden mező (TOKEN, VAULT_CA, VAULT_URL, SECRET_MOUNT_POINT) megfelel a konfigurációs fájl paramétereinek. Természetesen használhatja a Vault segédprogramokat is, hogy ugyanezt megtegye. De így egyszerűbb automatizálni a mountolási pont létrehozását. Remélem, hasznosnak találja ezt az információt, és találkozunk a cikk sorozat következő részeiben.
Tovább olvasva:
Forrás: habr.com
