Mettre en place le chiffrement au repos de MySQL

Temps de lecture estimé : 3 minutes

Dans l’article précédent, nous avons vu qu’une table non chiffrée « at rest » pouvait être considérée comme librement accessible : la facilité avec laquelle nous l’avons piraté était insolente.

Chiffrer une base de données MySQL 8 au repos signifie que le chiffrement se fait de façon totalement transparente : les données en clair ne sont qu’en RAM, les fichiers sur le disque sont chiffrés avant écriture, et déchiffrés avant lecture. La consommation habituelle reste inchangée.

Pour permettre ça, il faut activer le plugin associé via un fichier de configuration :

# /etc/mysql/conf.d/encryption.cnf
[mysqld]
early-plugin-load = keyring_file.so

Puis redémarrer le serveur :

$ service mysql restart

NB: Une nouvelle table se chiffre ainsi :

create table new_table (id int) ENCRYPTION='Y';

Tandis qu’une pré-existante se chiffre ainsi :

alter table old_table ENCRYPTION='Y';

Notre fichier est-il exploitable désormais ? Voyons ça :

$ strings ./utilisateurs.ibd
0eb37388-ee69-11ec-ad8d-0242ac110005
[hP=
E>_b
[...]
$ ibd2sdi ./utilisateurs.ibd
[ERROR] ibd2sdi: Page [page id: space=3, page number=3] is corrupted. Checksum verification failed.
[ERROR] ibd2sdi: Couldn't read page 3.
[ERROR] ibd2sdi: Couldn't reach upto level zero.

Il nous est impossible de déduire la structure de notre table : première embûche.

Imaginons que nous puissions le faire quand même.

Le chiffrement at-rest, dans le détail, fonctionne en deux temps :

  1. une clé unique par table est située dans l’en-tête du fichier de table,
  2. une clé maîtresse située à /var/lib/mysql-keyring/keyring chiffre toutes les clés de table.

Cette clé maîtresse est une chaîne simplement constituée de INNODBKey-UUID-KEY_ID ; dans le lot, l’UUID est une donnée importante. On le trouve dans le fichier /var/lib/mysql/auto.cnf et il est tout bonnement infalsifiable. Même en le forçant, le serveur l’écrase avec sa valeur : deuxième embûche.

Faisons semblant de connaître la table :

CREATE TABLE utilisateurs (
  `id` int(11) PRIMARY KEY AUTO_INCREMENT NOT NULL,
  `nom` varchar(50) NOT NULL,
  `prenom` varchar(50) NOT NULL,
  `maj_at` varchar(50) NOT NULL,
  `creation_at` datetime,
  `creditLimit` decimal(10,2) NOT NULL
) ENCRYPTION="Y";

Procédons alors comme dans l’article précédent :

mysql> alter table utilisateurs discard tablespace;
$ cp [source]/utilisateurs.ibd /var/lib/mysql/madatabase/
$ chown mysql: /var/lib/mysql/madatabase/utilisateurs.ibd
mysql> alter table utilisateurs import tablespace;
ERROR 1808 (HY000): Schema mismatch (Table is in an encrypted tablespace, but the encryption meta-data file cannot be found while importing.)

Aïe, fichier manquant : troisième embûche.

Bilan : accès au disque ou non, le chiffrement at-rest empêche de reconstruire une table, et permet réellement de se protéger du vol de disque. Il est simple à mettre en place et les benchmarks annoncent une perte de performance inférieure à 10%. Alors pourquoi s’en priver ?

Comme d’habitude, vous pouvez retrouver le code pour essayer par vous-même sur le dépôt d’exemple.


Sources :


    Ce billet vous a plu ? Partagez-le sur les réseaux…


    … Ou inscrivez-vous à la newsletter pour ne manquer aucun article (Si vous ne voyez pas le formulaire, désactivez temporairement uBlock).

    Voir aussi