Encryptie in MySQL: Keystore

In afwachting van de start van een nieuwe inschrijving voor de opleiding "Database" Wij hebben een vertaling van een nuttig artikel voor u voorbereid.

Encryptie in MySQL: Keystore

Transparante gegevensversleuteling (TDE) verscheen in Percona-server voor MySQL en MySQL al geruime tijd. Maar heeft u er ooit over nagedacht hoe het onder de motorkap werkt en welke impact TDE kan hebben op uw server? In deze serie artikelen bekijken we hoe TDE intern werkt. Laten we beginnen met sleutelopslag, aangezien dit nodig is om codering te laten werken. Vervolgens gaan we dieper in op hoe encryptie werkt in Percona Server for MySQL/MySQL en welke extra functies Percona Server for MySQL heeft.

MySQL-sleutelhanger

Keyring zijn plug-ins waarmee de server sleutels in een lokaal bestand (keyring_file) of op een externe server (zoals HashiCorp Vault) kan opvragen, maken en verwijderen. Sleutels worden altijd lokaal in de cache opgeslagen om het ophalen ervan te versnellen.

Plug-ins kunnen in twee categorieën worden onderverdeeld:

  • Lokale opslag. Bijvoorbeeld een lokaal bestand (we noemen dit een op bestanden gebaseerde sleutelhanger).
  • Opslag op afstand. Bijvoorbeeld Vault Server (we noemen dit een servergebaseerde sleutelhanger).

Deze scheiding is belangrijk omdat verschillende soorten opslag zich enigszins anders gedragen, niet alleen bij het opslaan en ophalen van sleutels, maar ook bij het uitvoeren ervan.

Wanneer u een bestandsopslag gebruikt, wordt bij het opstarten de volledige inhoud van de opslag in de cache geladen: sleutel-ID, sleutelgebruiker, sleuteltype en de sleutel zelf.

In het geval van een opslag aan de serverzijde (zoals Vault Server) worden bij het opstarten alleen de sleutel-ID en de sleutelgebruiker geladen, zodat het verkrijgen van alle sleutels het opstarten niet vertraagt. Sleutels worden lui geladen. Dat wil zeggen dat de sleutel zelf alleen vanuit Vault wordt geladen wanneer deze daadwerkelijk nodig is. Na het downloaden wordt de sleutel in het geheugen opgeslagen, zodat deze in de toekomst niet meer via TLS-verbindingen met de Vault Server hoeft te worden geopend. Laten we vervolgens eens kijken welke informatie aanwezig is in de sleutelopslag.

De belangrijkste informatie bevat het volgende:

  • sleutel id — sleutelidentificatie, bijvoorbeeld:
    INNODBKey-764d382a-7324-11e9-ad8f-9cb6d0d5dc99-1
  • sleutel type — sleuteltype op basis van het gebruikte versleutelingsalgoritme, mogelijke waarden: “AES”, “RSA” of “DSA”.
  • sleutellengte — sleutellengte in bytes, AES: 16, 24 of 32, RSA 128, 256, 512 en DSA 128, 256 of 384.
  • gebruiker - eigenaar van de sleutel. Als de sleutel een systeemsleutel is, bijvoorbeeld een hoofdsleutel, is dit veld leeg. Als een sleutel wordt aangemaakt met keyring_udf, identificeert dit veld de eigenaar van de sleutel.
  • de sleutel zelf

De sleutel wordt uniek geïdentificeerd door het paar: key_id, user.

Er zijn ook verschillen in het opslaan en verwijderen van sleutels.

Bestandsopslag is sneller. Je zou kunnen denken dat een sleutelopslag simpelweg één keer de sleutel naar een bestand schrijft, maar nee, er is hier meer aan de hand. Telkens wanneer er een wijziging in de bestandsopslag wordt aangebracht, wordt eerst een back-up van alle inhoud gemaakt. Stel dat het bestand mijn_grootste_geheimen heet, dan zal de reservekopie mijn_grootste_geheimen.backup zijn. Vervolgens wordt de cache gewijzigd (sleutels worden toegevoegd of verwijderd) en als alles succesvol is, wordt de cache gereset naar een bestand. In zeldzame gevallen, zoals bij een serverstoring, kunt u dit back-upbestand tegenkomen. Het back-upbestand wordt verwijderd de volgende keer dat de sleutels worden geladen (meestal nadat de server opnieuw is opgestart).

Bij het opslaan of verwijderen van een sleutel in een serveropslag moet de opslag verbinding maken met de MySQL-server met de opdrachten “send the key” / “request key deletion”.

Laten we teruggaan naar de opstartsnelheid van de server. Naast het feit dat de opstartsnelheid wordt beïnvloed door de kluis zelf, is er ook de vraag hoeveel sleutels uit de kluis moeten worden opgehaald bij het opstarten. Dit is uiteraard vooral belangrijk voor serveropslag. Bij het opstarten controleert de server welke sleutel nodig is voor versleutelde tabellen/tablespaces en vraagt ​​de sleutel op bij de opslag. Op een “schone” server met Master Key-encryptie moet er één Master Key zijn, die uit de opslag moet worden gehaald. Er kan echter een groter aantal sleutels nodig zijn, bijvoorbeeld wanneer de back-upserver een back-up herstelt vanaf de primaire server. In dergelijke gevallen moet worden gezorgd voor rotatie van de hoofdsleutel. Dit zal in toekomstige artikelen gedetailleerder worden behandeld, hoewel ik hier zou willen opmerken dat het opstarten van een server die meerdere hoofdsleutels gebruikt iets langer kan duren, vooral als er een sleutelopslag op de server wordt gebruikt.

Laten we nu wat meer praten over keyring_file. Toen ik keyring_file aan het ontwikkelen was, maakte ik me ook zorgen over hoe ik kon controleren op wijzigingen in keyring_file terwijl de server actief was. In 5.7 werd de controle uitgevoerd op basis van bestandsstatistieken, wat geen ideale oplossing was, en in 8.0 werd deze vervangen door een SHA256-controlesom.

De eerste keer dat u keyring_file uitvoert, worden bestandsstatistieken en een controlesom berekend, die door de server worden onthouden, en worden wijzigingen alleen toegepast als ze overeenkomen. Wanneer het bestand verandert, wordt de controlesom bijgewerkt.

We hebben al veel vragen over sleutelkluizen behandeld. Er is echter nog een ander belangrijk onderwerp dat vaak wordt vergeten of verkeerd wordt begrepen: het delen van sleutels tussen servers.

Wat ik bedoel? Elke server (bijvoorbeeld Percona Server) in het cluster moet een aparte locatie op de Vault Server hebben waarin Percona Server zijn sleutels moet opslaan. Elke Master Key die in de opslag wordt opgeslagen, bevat de GUID van de Percona Server binnen zijn identificatiecode. Waarom is het belangrijk? Stel u voor dat u slechts één Vault Server heeft en dat alle Percona Servers in het cluster die ene Vault Server gebruiken. Het probleem lijkt duidelijk. Als alle Percona-servers een hoofdsleutel zouden gebruiken zonder unieke identificatiegegevens, zoals id = 1, id = 2, etc., dan zouden alle servers in het cluster dezelfde hoofdsleutel gebruiken. Wat de GUID biedt, is het onderscheid tussen servers. Waarom praten we dan over het delen van sleutels tussen servers als er al een unieke GUID bestaat? Er is nog een plug-in: keyring_udf. Met deze plug-in kan uw servergebruiker zijn sleutels op de Vault-server opslaan. Het probleem doet zich voor wanneer een gebruiker bijvoorbeeld een sleutel op server1 maakt en vervolgens probeert een sleutel met dezelfde ID op server2 te maken, bijvoorbeeld:

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

Wachten. Beide servers gebruiken dezelfde Vault Server. Zou de functie keyring_key_store op server2 niet moeten mislukken? Interessant is dat als je hetzelfde probeert te doen op één server, je een foutmelding krijgt:

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

Dat klopt, ROB_1 bestaat al.

Laten we eerst het tweede voorbeeld bespreken. Zoals we eerder zeiden, slaat keyring_vault of een andere sleutelhangerplug-in alle sleutel-ID's in het geheugen op in de cache. Dus nadat een nieuwe sleutel is aangemaakt, wordt ROB_1 toegevoegd aan server1, en naast het verzenden van deze sleutel naar Vault, wordt de sleutel ook toegevoegd aan de cache. Wanneer we nu dezelfde sleutel een tweede keer proberen toe te voegen, controleert keyring_vault of de sleutel in de cache bestaat en genereert een foutmelding.

In het eerste geval is de situatie anders. Server1 en server2 hebben afzonderlijke caches. Na het toevoegen van ROB_1 aan de sleutelcache op server1 en de Vault-server, is de sleutelcache op server2 niet meer gesynchroniseerd. Er bevindt zich geen ROB_2-sleutel in de cache op server1. De ROB_1-sleutel wordt dus naar de keyring_key_store en naar de Vault-server geschreven, die feitelijk de vorige waarde overschrijft (!). Nu is de ROB_1-sleutel op de Vault-server 543210987654321. Interessant is dat de Vault-server dergelijke acties niet blokkeert en gemakkelijk de oude waarde overschrijft.

Nu kunnen we zien waarom serverpartitionering in Vault belangrijk kan zijn - wanneer u keyring_udf gebruikt en sleutels in Vault wilt opslaan. Hoe kan deze scheiding op een Vault-server worden bereikt?

Er zijn twee manieren om te partitioneren in Vault. U kunt voor elke server verschillende koppelpunten maken, of verschillende paden binnen hetzelfde koppelpunt gebruiken. Dit kan het beste worden geïllustreerd met voorbeelden. Laten we dus eerst naar de afzonderlijke bevestigingspunten kijken:

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

Hier kunt u zien dat server1 en server2 verschillende koppelpunten gebruiken. Bij het splitsen van de paden ziet de configuratie er als volgt uit:

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

In dit geval gebruiken beide servers hetzelfde mountpunt "mount_point", maar verschillende paden. Wanneer u het eerste geheim op server1 aanmaakt met behulp van dit pad, maakt de Vault-server automatisch een map 'server1' aan. Voor server2 is alles vergelijkbaar. Wanneer u het laatste geheim in mount_point/server1 of mount_point/server2 verwijdert, verwijdert de Vault-server ook die mappen. Als u padscheiding gebruikt, hoeft u slechts één koppelpunt aan te maken en de configuratiebestanden zo te wijzigen dat de servers afzonderlijke paden gebruiken. Een koppelpunt kan worden gemaakt met behulp van een HTTP-verzoek. Met CURL kan dit als volgt worden gedaan:

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

Alle velden (TOKEN, VAULT_CA, VAULT_URL, SECRET_MOUNT_POINT) komen overeen met de parameters van het configuratiebestand. Natuurlijk kunt u Vault-hulpprogramma's gebruiken om hetzelfde te doen. Maar het is eenvoudiger om het maken van een koppelpunt te automatiseren. Ik hoop dat je deze informatie nuttig vindt en we zien je in de volgende artikelen in deze serie.

Encryptie in MySQL: Keystore

Lees verder:

Bron: www.habr.com

Voeg een reactie