Titkosítás MySQL-ben: kulcstároló

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

Titkosítás MySQL-ben: kulcstároló

A Transparent Data Encryption (TDE) már régóta létezik a Percona Server for MySQL é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");
1

Vá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");
0

Igen, 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_POINT

Minden 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.

Titkosítás MySQL-ben: kulcstároló

Tovább olvasva:

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster