Chiffrement dans MySQL : Keystore

En prévision du début d'une nouvelle inscription au cours "Base de données" Nous avons préparé pour vous la traduction d’un article utile.

Chiffrement dans MySQL : Keystore

Le cryptage transparent des données (TDE) est apparu dans Serveur Percona pour MySQL et MySQL depuis un certain temps. Mais avez-vous déjà réfléchi à la façon dont cela fonctionne sous le capot et à l’impact que TDE peut avoir sur votre serveur ? Dans cette série d'articles, nous verrons comment TDE fonctionne en interne. Commençons par le stockage des clés, car cela est nécessaire au fonctionnement de tout cryptage. Nous examinerons ensuite de plus près le fonctionnement du cryptage dans Percona Server pour MySQL/MySQL et les fonctionnalités supplémentaires de Percona Server pour MySQL.

Porte-clés MySQL

Les porte-clés sont des plugins qui permettent au serveur d'interroger, de créer et de supprimer des clés dans un fichier local (keyring_file) ou sur un serveur distant (tel que HashiCorp Vault). Les clés sont toujours mises en cache localement pour accélérer leur récupération.

Les plugins peuvent être divisés en deux catégories :

  • Stockage local. Par exemple, un fichier local (nous appelons cela un porte-clés basé sur un fichier).
  • Stockage à distance. Par exemple, Vault Server (nous appelons cela un trousseau de clés basé sur un serveur).

Cette séparation est importante car les différents types de stockage se comportent légèrement différemment, non seulement lors du stockage et de la récupération des clés, mais également lors de leur exécution.

Lors de l'utilisation d'un stockage de fichiers, au démarrage, tout le contenu du stockage est chargé dans le cache : identifiant de clé, utilisateur de clé, type de clé et la clé elle-même.

Dans le cas d'un magasin côté serveur (tel que Vault Server), seuls l'ID de clé et la clé utilisateur sont chargés au démarrage, donc l'obtention de toutes les clés ne ralentit pas le démarrage. Les clés sont chargées paresseusement. Autrement dit, la clé elle-même est chargée à partir de Vault uniquement lorsqu'elle est réellement nécessaire. Une fois téléchargée, la clé est mise en cache dans la mémoire afin qu'il ne soit plus nécessaire d'y accéder via des connexions TLS au serveur Vault à l'avenir. Examinons ensuite quelles informations sont présentes dans le magasin de clés.

Les informations clés contiennent les éléments suivants :

  • identifiant de clé — identifiant de clé, par exemple :
    INNODBKey-764d382a-7324-11e9-ad8f-9cb6d0d5dc99-1
  • type de clé — type de clé basé sur l'algorithme de cryptage utilisé, valeurs possibles : « AES », « RSA » ou « DSA ».
  • longueur de clé — longueur de clé en octets, AES : 16, 24 ou 32, RSA 128, 256, 512 et DSA 128, 256 ou 384.
  • utilisateur - propriétaire de la clé. Si la clé est système, par exemple Master Key, ce champ est vide. Si une clé est créée à l'aide de keyring_udf, ce champ identifie le propriétaire de la clé.
  • la clé elle-même

La clé est identifiée de manière unique par la paire : key_id, user.

Il existe également des différences dans le stockage et la suppression des clés.

Le stockage des fichiers est plus rapide. Vous pourriez penser qu'un magasin de clés écrit simplement la clé dans un fichier une seule fois, mais non, il se passe bien plus ici. Chaque fois qu'une modification du stockage de fichiers est effectuée, une copie de sauvegarde de tout le contenu est d'abord créée. Disons que le fichier s'appelle my_biggest_secrets, alors la copie de sauvegarde sera my_biggest_secrets.backup. Ensuite, le cache est modifié (des clés sont ajoutées ou supprimées) et, si tout réussit, le cache est réinitialisé dans un fichier. Dans de rares cas, comme une panne de serveur, vous pouvez voir ce fichier de sauvegarde. Le fichier de sauvegarde est supprimé lors du prochain chargement des clés (généralement après le redémarrage du serveur).

Lors de l'enregistrement ou de la suppression d'une clé dans un stockage serveur, le stockage doit se connecter au serveur MySQL avec les commandes « envoyer la clé » / « demander la suppression de la clé ».

Revenons à la vitesse de démarrage du serveur. Outre le fait que la vitesse de lancement est affectée par le coffre-fort lui-même, se pose également le problème du nombre de clés du coffre-fort qui doivent être récupérées au démarrage. Bien entendu, cela est particulièrement important pour le stockage sur serveur. Au démarrage, le serveur vérifie quelle clé est requise pour les tables/espaces de table chiffrés et demande la clé au stockage. Sur un serveur « propre » avec cryptage par clé principale, il doit y avoir une clé principale, qui doit être récupérée du stockage. Toutefois, un plus grand nombre de clés peut être requis, par exemple lorsque le serveur de sauvegarde restaure une sauvegarde à partir du serveur principal. Dans de tels cas, une rotation de la clé principale doit être prévue. Ceci sera abordé plus en détail dans les prochains articles, même si je voudrais ici noter qu'un serveur utilisant plusieurs clés principales peut prendre un peu plus de temps à démarrer, en particulier lors de l'utilisation d'un magasin de clés côté serveur.

Parlons maintenant un peu plus de keyring_file. Lorsque je développais keyring_file, je me demandais également comment vérifier les modifications de keyring_file pendant l'exécution du serveur. Dans la version 5.7, la vérification était effectuée sur la base des statistiques des fichiers, ce qui n'était pas une solution idéale, et dans la version 8.0, elle a été remplacée par une somme de contrôle SHA256.

La première fois que vous exécutez keyring_file, les statistiques du fichier et une somme de contrôle sont calculées, qui sont mémorisées par le serveur, et les modifications ne sont appliquées que si elles correspondent. Lorsque le fichier change, la somme de contrôle est mise à jour.

Nous avons déjà abordé de nombreuses questions sur les coffres de clés. Cependant, il existe un autre sujet important qui est souvent oublié ou mal compris : le partage de clés entre serveurs.

Ce que je veux dire? Chaque serveur (par exemple, Percona Server) du cluster doit avoir un emplacement distinct sur le serveur Vault dans lequel Percona Server doit stocker ses clés. Chaque clé principale enregistrée dans le stockage contient le GUID du serveur Percona dans son identifiant. Pourquoi c'est important? Imaginez que vous n'ayez qu'un seul serveur Vault et que tous les serveurs Percona du cluster utilisent ce seul serveur Vault. Le problème semble évident. Si tous les serveurs Percona utilisaient une clé principale sans identifiants uniques, tels que id = 1, id = 2, etc., alors tous les serveurs du cluster utiliseraient la même clé principale. Ce que le GUID fournit, c'est la distinction entre les serveurs. Pourquoi alors parler de partage de clés entre serveurs si un GUID unique existe déjà ? Il existe un autre plugin - keyring_udf. Avec ce plugin, l'utilisateur de votre serveur peut stocker ses clés sur le serveur Vault. Le problème se produit lorsqu'un utilisateur crée une clé sur le serveur1, par exemple, puis tente de créer une clé avec le même ID sur le serveur2, par exemple :

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

Attendez. Les deux serveurs utilisent le même serveur Vault, la fonction keyring_key_store ne devrait-elle pas échouer sur le serveur2 ? Fait intéressant, si vous essayez de faire la même chose sur un serveur, vous recevrez une erreur :

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

C'est vrai, ROB_1 existe déjà.

Discutons d'abord du deuxième exemple. Comme nous l'avons dit plus tôt, keyring_vault ou tout autre plugin de trousseau de clés met en cache tous les identifiants de clé en mémoire. Ainsi, après avoir créé une nouvelle clé, ROB_1 est ajouté au serveur1, et en plus d'envoyer cette clé à Vault, la clé est également ajoutée au cache. Désormais, lorsque nous essayons d'ajouter la même clé une deuxième fois, keyring_vault vérifie si la clé existe dans le cache et renvoie une erreur.

Dans le premier cas, la situation est différente. Server1 et server2 ont des caches distincts. Après avoir ajouté ROB_1 au cache de clés sur le serveur1 et sur le serveur Vault, le cache de clés sur le serveur2 est désynchronisé. Il n'y a pas de clé ROB_2 dans le cache sur le serveur1. Ainsi, la clé ROB_1 est écrite dans keyring_key_store et sur le serveur Vault, ce qui écrase (!) la valeur précédente. Désormais, la clé ROB_1 sur le serveur Vault est 543210987654321. Fait intéressant, le serveur Vault ne bloque pas de telles actions et écrase facilement l'ancienne valeur.

Nous pouvons maintenant voir pourquoi le partitionnement du serveur dans Vault peut être important - lorsque vous utilisez keyring_udf et que vous souhaitez stocker des clés dans Vault. Comment réaliser cette séparation sur un serveur Vault ?

Il existe deux manières de partitionner dans Vault. Vous pouvez créer différents points de montage pour chaque serveur ou utiliser différents chemins au sein du même point de montage. Ceci est mieux illustré par des exemples. Examinons donc d'abord les points de montage individuels :

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

Ici, vous pouvez voir que server1 et server2 utilisent des points de montage différents. Lors du fractionnement des chemins, la configuration ressemblera à ceci :

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

Dans ce cas, les deux serveurs utilisent le même point de montage « mount_point », mais des chemins différents. Lorsque vous créez le premier secret sur le serveur1 à l'aide de ce chemin, le serveur Vault crée automatiquement un répertoire « serveur1 ». Pour le serveur2, tout est similaire. Lorsque vous supprimez le dernier secret dans mount_point/server1 ou mount_point/server2, le serveur Vault supprime également ces répertoires. Si vous utilisez la séparation des chemins, vous devez créer un seul point de montage et modifier les fichiers de configuration afin que les serveurs utilisent des chemins distincts. Un point de montage peut être créé à l'aide d'une requête HTTP. En utilisant CURL, cela peut être fait comme ceci :

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

Tous les champs (TOKEN, VAULT_CA, VAULT_URL, SECRET_MOUNT_POINT) correspondent aux paramètres du fichier de configuration. Bien entendu, vous pouvez utiliser les utilitaires Vault pour faire de même. Mais il est plus simple d’automatiser la création d’un point de montage. J'espère que vous trouverez ces informations utiles et à bientôt dans les prochains articles de cette série.

Chiffrement dans MySQL : Keystore

Lire la suite:

Source: habr.com

Ajouter un commentaire