MariaDB
 sql >> Base de données >  >> RDS >> MariaDB

Chiffrement MariaDB complet au repos et en transit pour une protection maximale des données - Deuxième partie

Dans la première partie de cette série, nous avons couvert la configuration du chiffrement en transit pour les serveurs de réplication MariaDB, où nous avons configuré les chiffrements client-serveur et de réplication. Tiré du premier article, où nous avions partiellement configuré notre cryptage complet (comme indiqué par les flèches vertes à gauche dans le diagramme) et dans ce billet de blog, nous allons terminer la configuration du cryptage avec un cryptage au repos pour créer un configuration de la réplication MariaDB entièrement chiffrée.

Le schéma suivant illustre notre configuration actuelle et la configuration finale que nous allons réaliser :

Chiffrement au repos

Le chiffrement au repos signifie que les données au repos telles que les fichiers de données et les journaux sont chiffrées sur le disque, ce qui rend presque impossible pour quelqu'un d'accéder ou de voler un disque dur et d'avoir accès aux données d'origine (à condition que la clé soit sécurisée et non stockée localement). Le chiffrement des données au repos, également connu sous le nom de chiffrement transparent des données (TDE), est pris en charge dans MariaDB 10.1 et versions ultérieures. Notez que l'utilisation du chiffrement entraîne une surcharge d'environ 5 à 10 %, selon la charge de travail et le type de cluster.

Pour MariaDB, les composants MariaDB suivants peuvent être chiffrés au repos :

  • Fichier de données InnoDB (espace de table partagé ou espace de table individuel, par exemple, *.ibd et ibdata1)
  • Fichiers de données et d'index Aria.
  • Annuler/rétablir les journaux (fichiers journaux InnoDB, par exemple, ib_logfile0 et ib_logfile1).
  • Journaux binaires/relais.
  • Fichiers et tableaux temporaires.

Les fichiers suivants ne peuvent pas être chiffrés pour le moment :

  • Fichier de métadonnées (par exemple, fichiers .frm).
  • Journal général basé sur des fichiers/journal des requêtes lentes. Le journal général basé sur une table/le journal des requêtes lentes peut être chiffré.
  • Journal des erreurs.

Le chiffrement des données au repos de MariaDB nécessite l'utilisation de plugins de gestion de clés et de chiffrement. Dans cet article de blog, nous allons utiliser le plugin File Key Management Encryption, qui est fourni par défaut depuis MariaDB 10.1.3. Notez qu'il existe un certain nombre d'inconvénients à l'utilisation de ce plugin, par exemple, la clé peut toujours être lue par l'utilisateur root et MySQL, comme expliqué dans la page MariaDB Data-at-Rest Encryption.

Génération du fichier clé

Créons un répertoire dédié pour stocker nos éléments de chiffrement au repos :

$ mkdir -p /etc/mysql/rest
$ cd /etc/mysql/rest

Créer un fichier clé. C'est le cœur du chiffrement :

$ openssl rand -hex 32 > /etc/mysql/rest/keyfile

Ajouter une chaîne "1 ;" comme identifiant de clé dans le fichier de clés :

$ echo '1;' 
sed -i '1s/^/1;/' /etc/mysql/rest/keyfile

Ainsi, lors de la lecture du fichier clé, il devrait ressembler à ceci :

$ cat /etc/mysql/rest/keyfile
1;4eb5770dcfa691bc634cbcd3c6bed9ed4ccd0111f3d3b1dae2c51a90fbf16ed7

Ce qui précède signifie simplement que pour l'identifiant de clé 1, la clé est 4eb... Le fichier de clé doit contenir deux informations pour chaque clé de chiffrement. Tout d'abord, chaque clé de chiffrement doit être identifiée par un entier 32 bits comme identifiant de clé. Deuxièmement, la clé de chiffrement elle-même doit être fournie sous forme codée en hexadécimal. Ces deux informations doivent être séparées par un point-virgule.

Créez un mot de passe pour chiffrer la clé ci-dessus. Ici, nous allons stocker le mot de passe dans un fichier appelé "keyfile.passwd":

$ echo -n 'mySuperStrongPassword' > /etc/mysql/rest/keyfile.passwd

Vous pouvez ignorer l'étape ci-dessus si vous souhaitez spécifier le mot de passe directement dans le fichier de configuration à l'aide de l'option file_key_management_filekey. Par exemple :file_key_management_filekey=mySuperStrongPassword

Mais dans cet exemple, nous allons lire le mot de passe qui est stocké dans un fichier, nous devons donc définir la ligne suivante dans le fichier de configuration ultérieurement : 

file_key_management_filekey=FILE:/etc/mysql/encryption/keyfile.passwd

Nous allons chiffrer le fichier de clé en texte clair dans un autre fichier appelé keyfile.enc, en utilisant le mot de passe dans le fichier de mot de passe :

$  openssl enc -aes-256-cbc -md sha1 -pass file:/etc/mysql/rest/keyfile.passwd -in /etc/mysql/rest/keyfile -out /etc/mysql/rest/keyfile.enc

Lorsque vous répertoriez le répertoire, nous devrions voir ces 3 fichiers :

$ ls -1 /etc/mysql/rest/
keyfile
keyfile.enc
keyfile.passwd

Le contenu du fichier keyfile.enc est simplement une version chiffrée du fichier clé :

Pour tester, nous pouvons déchiffrer le fichier chiffré à l'aide d'OpenSSL en fournissant le fichier de mot de passe (keyfile.passwd) :

$ openssl aes-256-cbc -d -md sha1 -pass file:/etc/mysql/rest/keyfile.passwd -in /etc/mysql/rest/keyfile.enc
1;4eb5770dcfa691bc634cbcd3c6bed9ed4ccd0111f3d3b1dae2c51a90fbf16ed7

Nous pouvons alors supprimer la clé en clair car nous allons utiliser celle chiffrée (.enc) avec le fichier de mot de passe :

$ rm -f /etc/mysql/encryption/keyfile

Nous pouvons maintenant procéder à la configuration du chiffrement MariaDB au repos.

Configuration du chiffrement au repos

Nous devons déplacer le fichier de clé chiffré et le mot de passe vers les esclaves à utiliser par MariaDB pour chiffrer/déchiffrer les données. Sinon, une table chiffrée sauvegardée à partir du maître à l'aide d'une sauvegarde physique comme MariaDB Backup aurait un problème à lire par les esclaves (en raison d'une combinaison clé/mot de passe différente). Une sauvegarde logique comme mysqldump devrait fonctionner avec des clés et des mots de passe différents.

Sur les esclaves, créez un répertoire pour stocker les éléments de chiffrement au repos :

(slave1)$ mkdir -p /etc/mysql/rest
(slave2)$ mkdir -p /etc/mysql/rest

Sur le maître, copiez le fichier de clé chiffré et le fichier de mot de passe vers les autres esclaves :

(master)$ cd /etc/mysql/rest
(master)$ scp keyfile.enc keyfile.passwd [email protected]:/etc/mysql/rest/
(master)$ scp keyfile.enc keyfile.passwd [email protected]:/etc/mysql/rest/

Protéger les fichiers de l'accès global et attribuer l'utilisateur "mysql" comme propriétaire :

$ chown mysql:mysql /etc/mysql/rest/*
$ chmod 600 /etc/mysql/rest/*

Ajoutez ce qui suit dans le fichier de configuration de MariaDB sous la section [mysqld] ou [mariadb] :

# at-rest encryption
plugin_load_add              = file_key_management
file_key_management_filename = /etc/mysql/rest/keyfile.enc
file_key_management_filekey  = FILE:/etc/mysql/rest/keyfile.passwd
file_key_management_encryption_algorithm = AES_CBC

innodb_encrypt_tables            = ON
innodb_encrypt_temporary_tables  = ON
innodb_encrypt_log               = ON
innodb_encryption_threads        = 4
innodb_encryption_rotate_key_age = 1
encrypt-tmp-disk-tables          = 1
encrypt-tmp-files                = 1
encrypt-binlog                   = 1
aria_encrypt_tables              = ON

Attention à la variable file_key_management_filekey, si le mot de passe est dans un fichier, vous devez préfixer le chemin avec "FILE:". Vous pouvez également spécifier directement la chaîne de mot de passe (non recommandé en raison de sa verbosité) : 

file_key_management_filekey=mySuperStrongPassword

Redémarrez le serveur MariaDB un nœud à la fois, en commençant par les esclaves :

(slave1)$ systemctl restart mariadb
(slave2)$ systemctl restart mariadb
(master)$ systemctl restart mariadb

Observez le journal des erreurs et assurez-vous que le chiffrement MariaDB est activé au démarrage :

$ tail -f /var/log/mysql/mysqld.log
...
2019-12-17  6:44:47 0 [Note] InnoDB: Encrypting redo log: 2*67108864 bytes; LSN=143311
2019-12-17  6:44:48 0 [Note] InnoDB: Starting to delete and rewrite log files.
2019-12-17  6:44:48 0 [Note] InnoDB: Setting log file ./ib_logfile101 size to 67108864 bytes
2019-12-17  6:44:48 0 [Note] InnoDB: Setting log file ./ib_logfile1 size to 67108864 bytes
2019-12-17  6:44:48 0 [Note] InnoDB: Renaming log file ./ib_logfile101 to ./ib_logfile0
2019-12-17  6:44:48 0 [Note] InnoDB: New log files created, LSN=143311
2019-12-17  6:44:48 0 [Note] InnoDB: 128 out of 128 rollback segments are active.
2019-12-17  6:44:48 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2019-12-17  6:44:48 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2019-12-17  6:44:48 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2019-12-17  6:44:48 0 [Note] InnoDB: Waiting for purge to start
2019-12-17  6:44:48 0 [Note] InnoDB: 10.4.11 started; log sequence number 143311; transaction id 222
2019-12-17  6:44:48 0 [Note] InnoDB: Creating #1 encryption thread id 139790011840256 total threads 4.
2019-12-17  6:44:48 0 [Note] InnoDB: Creating #2 encryption thread id 139790003447552 total threads 4.
2019-12-17  6:44:48 0 [Note] InnoDB: Creating #3 encryption thread id 139789995054848 total threads 4.
2019-12-17  6:44:48 0 [Note] InnoDB: Creating #4 encryption thread id 139789709866752 total threads 4.
2019-12-17  6:44:48 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
2019-12-17  6:44:48 0 [Note] Plugin 'FEEDBACK' is disabled.
2019-12-17  6:44:48 0 [Note] Using encryption key id 1 for temporary files
...

Vous devriez voir des lignes indiquant l'initialisation du chiffrement dans le journal des erreurs. À ce stade, la majorité de la configuration du chiffrement est maintenant terminée.

Tester votre chiffrement

Créez une base de données de test à tester sur le maître :

(master)MariaDB> CREATE SCHEMA sbtest;
(master)MariaDB> USE sbtest;

Créez une table standard sans chiffrement et insérez une ligne :

MariaDB> CREATE TABLE tbl_plain (id INT AUTO_INCREMENT PRIMARY KEY, data VARCHAR(255));
MariaDB> INSERT INTO tbl_plain SET data = 'test data';

Nous pouvons voir les données stockées en texte clair lors de la navigation dans le fichier de données InnoDB à l'aide d'un outil de vidage hexadécimal :

$ xxd /var/lib/mysql/sbtest/tbl_plain.ibd | less
000c060: 0200 1c69 6e66 696d 756d 0002 000b 0000  ...infimum......
000c070: 7375 7072 656d 756d 0900 0000 10ff f180  supremum........
000c080: 0000 0100 0000 0000 0080 0000 0000 0000  ................
000c090: 7465 7374 2064 6174 6100 0000 0000 0000  test data.......
000c0a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

Créez une table chiffrée et insérez une ligne :

MariaDB> CREATE TABLE tbl_enc (id INT AUTO_INCREMENT PRIMARY KEY, data VARCHAR(255)) ENCRYPTED=YES;
MariaDB> INSERT INTO tbl_enc SET data = 'test data';

Nous ne pouvons pas dire ce qui est stocké dans le fichier de données InnoDB pour les tables chiffrées :

$ xxd /var/lib/mysql/sbtest/tbl_enc.ibd | less
000c060: 0c2c 93e4 652e 9736 e68a 8b69 39cb 6157  .,..e..6...i9.aW
000c070: 3cd1 581c 7eb9 84ca d792 7338 521f 0639  <.X.~.....s8R..9
000c080: d279 9eb3 d3f5 f9b0 eccb ed05 de16 f3ac  .y..............
000c090: 6d58 5519 f776 8577 03a4 fa88 c507 1b31  mXU..v.w.......1
000c0a0: a06f 086f 28d9 ac17 8923 9412 d8a5 1215  .o.o(....#......

Notez que le fichier de métadonnées tbl_enc.frm n'est pas chiffré au repos. Seul le fichier de données InnoDB (.ibd) est crypté.

Lors de la comparaison des journaux binaires ou de relais "simples", nous pouvons clairement voir le contenu de celui-ci à l'aide de l'outil hexdump :

$ xxd binlog.000002 | less
0000560: 0800 0800 0800 0b04 726f 6f74 096c 6f63  ........root.loc
0000570: 616c 686f 7374 0047 5241 4e54 2052 454c  alhost.GRANT REL
0000580: 4f41 442c 4c4f 434b 2054 4142 4c45 532c  OAD,LOCK TABLES,
0000590: 5245 504c 4943 4154 494f 4e20 434c 4945  REPLICATION CLIE
00005a0: 4e54 2c45 5645 4e54 2c43 5245 4154 4520  NT,EVENT,CREATE
00005b0: 5441 424c 4553 5041 4345 2c50 524f 4345  TABLESPACE,PROCE
00005c0: 5353 2c43 5245 4154 452c 494e 5345 5254  SS,CREATE,INSERT
00005d0: 2c53 454c 4543 542c 5355 5045 522c 5348  ,SELECT,SUPER,SH
00005e0: 4f57 2056 4945 5720 4f4e 202a 2e2a 2054  OW VIEW ON *.* T

Alors que pour un journal binaire chiffré, le contenu semble charabia :

$ xxd binlog.000004 | less
0000280: 4a1d 1ced 2f1b db50 016a e1e9 1351 84ba  J.../..P.j...Q..
0000290: 38b6 72e7 8743 7713 afc3 eecb c36c 1b19  8.r..Cw......l..
00002a0: 7b3f 6176 208f 0000 00dc 85bf 6768 e7c6  {?av .......gh..
00002b0: 6107 5bea 241c db12 d50c 3573 48e5 3c3d  a.[.$.....5sH.<=
00002c0: 3179 1653 2449 d408 1113 3e25 d165 c95b  1y.S$I....>%.e.[
00002d0: afb0 6778 4b26 f672 1bc7 567e da96 13f5  ..gxK&.r..V~....
00002e0: 2ac5 b026 3fb9 4b7a 3ef4 ab47 6c9f a686  *..&?.Kz>..Gl...

Chiffrer les tables Aria

Pour le moteur de stockage Aria, il ne prend pas en charge l'option ENCRYPTED dans l'instruction CREATE/ALTER car il suit l'option globale aria_encrypt_tables. Par conséquent, lors de la création d'une table Aria, créez simplement la table avec l'option ENGINE=Aria :

MariaDB> CREATE TABLE tbl_aria_enc (id INT AUTO_INCREMENT PRIMARY KEY, data VARCHAR(255)) ENGINE=Aria;
MariaDB> INSERT INTO tbl_aria_enc(data) VALUES ('test data');
MariaDB> FLUSH TABLE tbl_aria_enc;

Nous pouvons ensuite vérifier le contenu du fichier de données de la table (tbl_aria_enc.MAD) ou du fichier d'index (tbl_aria_enc.MAI) avec l'outil hexdump. Pour chiffrer une table Aria existante, la table doit être reconstruite :

MariaDB> ALTER TABLE db.aria_table ENGINE=Aria ROW_FORMAT=PAGE;

Cette instruction amène Aria à reconstruire la table à l'aide de l'option de table ROW_FORMAT. Dans le processus, avec le nouveau paramètre par défaut, il crypte la table lorsqu'il écrit sur le disque.

Chiffrement du journal général/du journal des requêtes lentes

Pour chiffrer les journaux des requêtes générales et lentes, nous pouvons définir l'option MariaDB log_output sur 'TABLE' au lieu du 'FILE' par défaut :

MariaDB> SET GLOBAL log_ouput = 'TABLE';

Cependant, MariaDB créera par défaut les tables nécessaires à l'aide du moteur de stockage CSV, qui n'est pas chiffré par MariaDB. Aucun moteur autre que CSV, MyISAM ou Aria n'est légal pour les tables de log. L'astuce consiste à reconstruire la table CSV par défaut avec le moteur de stockage Aria, à condition que l'option aria_encrypt_tables soit définie sur ON. Cependant, l'option de journal correspondante doit être désactivée pour que la modification de la table réussisse.

Ainsi, les étapes pour chiffrer la table de journal générale sont :

MariaDB> SET GLOBAL general_log = OFF;
MariaDB> ALTER TABLE mysql.general_log ENGINE=Aria;
MariaDB> SET GLOBAL general_log = ON;

De même, pour le journal des requêtes lentes :

MariaDB> SET GLOBAL slow_query_log = OFF;
MariaDB> ALTER TABLE mysql.slow_log ENGINE=Aria;
MariaDB> SET GLOBAL slow_query_log = ON;

Vérifiez la sortie des journaux généraux au sein du serveur :

MariaDB> SELECT * FROM mysql.general_log;
+----------------------------+---------------------------+-----------+-----------+--------------+------------------------------+
| event_time                 | user_host                 | thread_id | server_id | command_type | argument                     |
+----------------------------+---------------------------+-----------+-----------+--------------+------------------------------+
| 2019-12-17 07:45:53.109558 | root[root] @ localhost [] |        19 |     28001 |        Query | select * from sbtest.tbl_enc |
| 2019-12-17 07:45:55.504710 | root[root] @ localhost [] |        20 |     28001 |        Query | select * from general_log    |
+----------------------------+---------------------------+-----------+-----------+--------------+------------------------------+

Ainsi que le contenu crypté du fichier de données Aria dans le répertoire de données à l'aide de l'outil hexdump :

$ xxd /var/lib/mysql/mysql/general_log.MAD | less
0002040: 1d45 820d 7c53 216c 3fc6 98a6 356e 1b9e  .E..|S!l?...5n..
0002050: 6bfc e193 7509 1fa7 31e2 e22a 8f06 3c6f  k...u...1..*..<o
0002060: ae71 bb63 e81b 0b08 7120 0c99 9f82 7c33  .q.c....q ....|3
0002070: 1117 bc02 30c1 d9a7 c732 c75f 32a6 e238  ....0....2._2..8
0002080: d1c8 5d6f 9a08 455a 8363 b4f4 5176 f8a1  ..]o..EZ.c..Qv..
0002090: 1bf8 113c 9762 3504 737e 917b f260 f88c  ...<.b5.s~.{.`..
00020a0: 368e 336f 9055 f645 b636 c5c1 debe fbe7  6.3o.U.E.6......
00020b0: d01e 028f 8b75 b368 0ef0 8889 bb63 e032  .....u.h.....c.2

Le chiffrement au repos de MariaDB est maintenant terminé. Combinez cela avec le chiffrement en transit que nous avons fait dans le premier message, notre architecture finale ressemble maintenant à ceci :

Conclusion

Il est désormais possible de sécuriser totalement vos bases de données MariaDB via le cryptage pour une protection contre les violations physiques et virtuelles ou le vol. ClusterControl peut également vous aider à maintenir ce type de sécurité et vous pouvez le télécharger gratuitement ici.