Le cryptage est l'une des fonctionnalités de sécurité les plus importantes pour garder vos données aussi sécurisées que possible. Selon les données que vous manipulez, ce n'est pas toujours indispensable, mais vous devriez au moins le considérer comme une amélioration de la sécurité dans votre organisation, et il est en fait recommandé d'éviter le vol de données ou l'accès non autorisé.
Dans ce blog, nous décrirons deux types de chiffrement de base et comment le configurer sur un serveur MariaDB.
Qu'est-ce que le chiffrement des données ?
Il existe deux types de base de chiffrement des données :au repos et en transit. Voyons ce qu'ils signifient.
Cryptage des données au repos
Les données stockées dans un système sont appelées données au repos. Le cryptage de ces données consiste à utiliser un algorithme pour convertir du texte ou du code en illisible. Vous devez disposer d'une clé de cryptage pour décoder les données cryptées.
Le chiffrement d'une base de données entière doit être fait avec prudence car cela peut avoir un impact sérieux sur les performances. Il est donc judicieux de chiffrer uniquement des champs ou des tables individuels.
Le chiffrement des données au repos protège les données contre le vol physique des disques durs ou l'accès non autorisé au stockage des fichiers. Ce cryptage est également conforme aux réglementations sur la sécurité des données, en particulier si des données financières ou de santé sont stockées sur le système de fichiers.
Cryptage des données en transit
Les données transférées ou se déplaçant entre les transactions sont appelées données en transit. Les données se déplaçant entre le serveur et le client lors de la navigation sur des pages Web sont un bon exemple de ce type de données.
Puisqu'il est toujours en mouvement, il doit être protégé par un cryptage approprié pour éviter tout vol ou altération des données avant qu'il n'atteigne sa destination.
La situation idéale pour protéger les données en transit est de chiffrer les données avant qu'elles ne se déplacent et de ne les déchiffrer que lorsqu'elles atteignent la destination finale.
Cryptage des données au repos MariaDB
Le chiffrement des tables et des espaces de table a été ajouté dans MariaDB à partir de la version 10.1, et il prend en charge le chiffrement pour les moteurs de stockage XtraDB, InnoDB et Aria, ainsi que pour les journaux binaires.
Vous pouvez choisir différentes méthodes de chiffrement :
- Tous les tableaux
- Tableaux individuels
- Tout, à l'exception des tableaux individuels
Selon la documentation, l'utilisation du chiffrement a une surcharge d'environ 3 à 5 %, il est donc important d'avoir un environnement de test pour le stresser et voir comment il réagit, afin d'éviter les problèmes en production.
Comment configurer le chiffrement des données au repos sur MariaDB
Vérifions une table "ville" existante dans une base de données MariaDB :
$ strings city.ibd |head
infimum
supremum
infimum
supremum
3ABW
3KHM
infimum
supremum
Kabul AFGKabol
Qandahar AFGQandahar
Comme vous pouvez le voir, vous pouvez lire des données à partir de là sans aucun problème en utilisant la commande strings Linux par exemple. Voyons maintenant comment le chiffrer.
Générez une clé de chiffrement à l'aide de la commande openssl rand :
$ mkdir -p /etc/mysql/encryption
$ for i in {1..4}; do openssl rand -hex 32 >> /etc/mysql/encryption/keyfile; done;
Modifiez le fichier généré /etc/mysql/encryption/keyfile et ajoutez les ID de clé qui seront référencés lors de la création des tables chiffrées. Le format doit être le suivant :
<encryption_key_id1>;<hex-encoded_encryption_key1>
<encryption_key_id2>;<hex-encoded_encryption_key2>
Vous pouvez le modifier à l'aide de la commande sed linux de cette manière :
$ for i in {1..4}; do sed -i -e "$i s/^/$i;/" keyfile; done
Ainsi, le fichier devrait ressembler à ceci :
$ cat /etc/mysql/encryption/keyfile
1;f237fe72e16206c0b0f6f43c3b3f4accc242564d77f5fe17bb621de388c193af
2;0c0819a10fb366a5ea657a71759ee6a950ae8f25a5ba7400a91f59b63683edc5
3;ac9ea3a839596dbf52492d9ab6b180bf11a35f44995b2ed752c370d920a10169
4;72afc936e16a8df05cf994c7902e588de0d11ca7301f9715d00930aa7d5ff8ab
Maintenant, générez un mot de passe aléatoire à l'aide de la commande openssl similaire à celle que vous avez vue précédemment :
$ openssl rand -hex 128 > /etc/mysql/encryption/keyfile.key
Avant de passer à l'étape suivante, il est important de connaître les détails suivants concernant le chiffrement du fichier de clé :
- Le seul algorithme actuellement pris en charge par MariaDB pour chiffrer le fichier de clé est le mode Cipher Block Chaining (CBC) de Advanced Encryption Standard (AES).
- La taille de la clé de chiffrement peut être de 128 bits, 192 bits ou 256 bits.
- La clé de chiffrement est créée à partir du hachage SHA-1 du mot de passe de chiffrement.
- Le mot de passe de chiffrement a une longueur maximale de 256 caractères.
Maintenant, pour chiffrer le fichier de clé à l'aide de la commande openssl enc, exécutez la commande suivante :
$ openssl enc -aes-256-cbc -md sha1 -pass file:/etc/mysql/encryption/keyfile.key -in /etc/mysql/encryption/keyfile -out /etc/mysql/encryption/keyfile.enc
Enfin, vous devez ajouter les paramètres suivants dans votre fichier de configuration my.cnf (situé dans /etc/ sur un système d'exploitation basé sur RedHat ou /etc/mysql/ sur un système d'exploitation basé sur Debian) :
[mysqld]
…
#################### DATABASE ENCRYPTION ####################
plugin_load_add = file_key_management
file_key_management_filename = /etc/mysql/encryption/keyfile.enc
file_key_management_filekey = FILE:/etc/mysql/encryption/keyfile.key
file_key_management_encryption_algorithm = aes_cbc
encrypt_binlog = 1
innodb_encrypt_tables = ON
innodb_encrypt_log = ON
innodb_encryption_threads = 4
innodb_encryption_rotate_key_age = 0
…
Et redémarrez le service MariaDB pour prendre les modifications :
$ systemctl restart mariadb
À ce stade, tout est prêt pour utiliser la fonction de cryptage. Chiffrez le même tableau que nous avons montré plus tôt, "ville". Pour cela, vous devez utiliser l'instruction ALTER TABLE en définissant le paramètre ENCRYPTED à YES :
MariaDB [world]> ALTER TABLE city ENCRYPTED=YES;
Query OK, 0 rows affected (0.483 sec)
Records: 0 Duplicates: 0 Warnings: 0
Maintenant, si vous essayez d'accéder à la table directement depuis le système de fichiers, vous verrez quelque chose comme ceci :
$ strings city.ibd |head
PU%O
!ybN)b
9,{9WB4
T3uG:
?oiN
,35sz
8g)Q
o(o
q_A1
k=-w
Comme vous pouvez le voir, le tableau est illisible. Vous pouvez également spécifier l'ID de clé de chiffrement en ajoutant le paramètre ENCRYPTION_KEY_ID =
Les nouvelles tables seront chiffrées par défaut car nous définissons le paramètre innodb_encrypt_tables sur ON dans le fichier de configuration my.cnf.
Cryptage des données en transit MariaDB
MariaDB vous permet de chiffrer les données en transit entre le serveur et les clients à l'aide du protocole Transport Layer Security (TLS), anciennement connu sous le nom de Secure Socket Layer ou SSL.
Tout d'abord, vous devez vous assurer que votre serveur MariaDB a été compilé avec le support TLS. Vous pouvez le vérifier en exécutant l'instruction SHOW GLOBAL VARIABLES suivante :
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'version_ssl_library';
+---------------------+----------------------------+
| Variable_name | Value |
+---------------------+----------------------------+
| version_ssl_library | OpenSSL 1.1.1 11 Sep 2018 |
+---------------------+----------------------------+
1 row in set (0.001 sec)
Et vérifiez s'il n'est pas actuellement utilisé à l'aide de l'instruction SHOW VARIABLES :
MariaDB [(none)]> SHOW VARIABLES LIKE '%ssl%';
+---------------------+----------------------------+
| Variable_name | Value |
+---------------------+----------------------------+
| have_openssl | YES |
| have_ssl | DISABLED |
| ssl_ca | |
| ssl_capath | |
| ssl_cert | |
| ssl_cipher | |
| ssl_crl | |
| ssl_crlpath | |
| ssl_key | |
| version_ssl_library | OpenSSL 1.1.1 11 Sep 2018 |
+---------------------+----------------------------+
10 rows in set (0.001 sec)
Vous pouvez également vérifier le statut SSL à l'aide de la commande status MariaDB :
MariaDB [(none)]> status
--------------
mysql Ver 15.1 Distrib 10.4.13-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2
Connection id: 22
Current database:
Current user: [email protected]
SSL: Not in use
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server: MariaDB
Server version: 10.4.13-MariaDB-1:10.4.13+maria~bionic-log mariadb.org binary distribution
Protocol version: 10
Connection: Localhost via UNIX socket
Server characterset: latin1
Db characterset: latin1
Client characterset: utf8
Conn. characterset: utf8
UNIX socket: /var/lib/mysql/mysql.sock
Uptime: 4 hours 28 min 25 sec
Threads: 11 Questions: 111668 Slow queries: 0 Opens: 92 Flush tables: 1 Open tables: 85 Queries per second avg: 6.933
--------------
Comment configurer le chiffrement des données en transit sur MariaDB
Créons le répertoire certs pour stocker tous les certificats :
$ mkdir -p /etc/mysql/certs
Maintenant, générons les certificats CA qui seront configurés pour chiffrer la connexion :
$ openssl genrsa 2048 > ca-key.pem
$ openssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca-cert.pem
Cette dernière commande vous demandera de compléter les informations suivantes :
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:
Maintenant, vous devez générer les certificats du serveur :
$ openssl req -newkey rsa:2048 -nodes -keyout server-key.pem -out server-req.pem
Cette commande vous demandera de remplir les mêmes informations qu'avant plus un mot de passe de certificat facultatif.
$ openssl rsa -in server-key.pem -out server-key.pem
$ openssl x509 -req -in server-req.pem -days 365000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
Et enfin, vous devez générer les certificats clients :
$ openssl req -newkey rsa:2048 -nodes -keyout client-key.pem -out client-req.pem
Cela vous demandera également de compléter les informations et un mot de passe de certificat facultatif.
$ openssl rsa -in client-key.pem -out client-key.pem
$ openssl x509 -req -in client-req.pem -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem
Assurez-vous d'utiliser un nom commun différent sur chaque certificat, sinon cela ne fonctionnera pas et vous recevrez un message du type :
ERROR 2026 (HY000): SSL connection error: self signed certificate
À ce stade, vous aurez quelque chose comme ceci :
$ ls /etc/mysql/certs/
ca-cert.pem ca-key.pem client-cert.pem client-key.pem client-req.pem server-cert.pem server-key.pem server-req.pem
Et vous pouvez valider les certificats en utilisant la commande suivante :
$ openssl verify -CAfile ca-cert.pem server-cert.pem client-cert.pem
server-cert.pem: OK
client-cert.pem: OK
Alors maintenant, configurons-le dans le fichier de configuration my.cnf (situé dans /etc/ sur un système d'exploitation basé sur RedHat ou /etc/mysql/ sur un système d'exploitation basé sur Debian) :
[mysqld]
ssl_ca=/etc/mysql/certs/ca-cert.pem
ssl_cert=/etc/mysql/certs/server-cert.pem
ssl_key=/etc/mysql/certs/server-key.pem
[client-mariadb]
ssl_ca =/etc/mysql/certs/ca-cert.pem
ssl_cert=/etc/mysql/certs/client-cert.pem
ssl_key=/etc/mysql/certs/client-key.pem
Assurez-vous de l'ajouter dans la section correspondante (mysqld et client-mariadb).
Modifiez le propriétaire du certificat et redémarrez le service de base de données :
$ chown mysql.mysql /etc/mysql/certs/
$ systemctl restart mariadb
Après cela, si vous regardez la sortie SHOW VARIABLES, vous devriez avoir ceci :
MariaDB [(none)]> SHOW VARIABLES LIKE '%ssl%';
+---------------------+----------------------------------+
| Variable_name | Value |
+---------------------+----------------------------------+
| have_openssl | YES |
| have_ssl | YES |
| ssl_ca | /etc/mysql/certs/ca-cert.pem |
| ssl_capath | |
| ssl_cert | /etc/mysql/certs/server-cert.pem |
| ssl_cipher | |
| ssl_crl | |
| ssl_crlpath | |
| ssl_key | /etc/mysql/certs/server-key.pem |
| version_ssl_library | OpenSSL 1.1.1 11 Sep 2018 |
+---------------------+----------------------------------+
10 rows in set (0.001 sec)
Maintenant, créons un utilisateur avec le paramètre REQUIRE SSL pour l'utiliser :
MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 's9s'@'%' IDENTIFIED BY 'root123' REQUIRE SSL;
Query OK, 0 rows affected (0.005 sec)
Si vous utilisez cet utilisateur pour accéder à la base de données et vérifiez la commande d'état, vous verrez le SSL utilisé :
MariaDB [(none)]> status
--------------
mysql Ver 15.1 Distrib 10.4.13-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2
Connection id: 15
Current database:
Current user: [email protected]
SSL: Cipher in use is TLS_AES_256_GCM_SHA384
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server: MariaDB
Server version: 10.4.13-MariaDB-1:10.4.13+maria~bionic-log mariadb.org binary distribution
Protocol version: 10
Connection: 127.0.0.1 via TCP/IP
Server characterset: latin1
Db characterset: latin1
Client characterset: utf8
Conn. characterset: utf8
TCP port: 3306
Uptime: 16 sec
Threads: 11 Questions: 136 Slow queries: 0 Opens: 17 Flush tables: 1 Open tables: 11 Queries per second avg: 8.500
--------------
Comment activer le cryptage SSL avec ClusterControl
Un autre moyen, et même un moyen plus simple, d'activer SSL sur votre base de données MariaDB consiste à utiliser ClusterControl. Nous supposerons que vous avez installé ClusterControl et que vous gérez votre base de données MariaDB en l'utilisant, alors allez dans ClusterControl -> Sélectionnez votre cluster MariaDB -> Sécurité -> Cryptage SSL -> Activer.
Et voilà, votre cryptage SSL sera activé dans votre base de données MariaDB sans aucune tâche manuelle.
Limitations du chiffrement au repos dans MariaDB
Certaines limitations liées au chiffrement MariaDB au repos doivent être prises en compte :
- Les métadonnées (par exemple les fichiers .frm) et les données envoyées au client ne sont pas chiffrées.
- Seul le serveur MariaDB sait décrypter les données, en particulier
- mysqlbinlog peut lire les journaux binaires chiffrés uniquement lorsque --read-from-remote-server est utilisé.
- Percona XtraBackup ne peut pas sauvegarder les instances qui utilisent InnoDB chiffré. Cependant, Mariabackup peut sauvegarder des instances chiffrées.
- Le gcache Galera sur disque n'est pas chiffré dans la version communautaire de MariaDB Server, cependant, ce fichier est chiffré dans MariaDB Enterprise Server 10.4.
- Le plug-in Audit ne peut pas créer de sortie chiffrée. Envoyez-le à syslog et configurez-y la protection à la place.
- Le journal des requêtes générales basé sur des fichiers et le journal des requêtes lentes ne peuvent pas être chiffrés.
- Le journal Aria n'est pas chiffré. Cela n'affecte que les tables Aria non temporaires.
- Le journal des erreurs MariaDB n'est pas chiffré. Le journal des erreurs peut contenir du texte et des données de requête dans certains cas, y compris les plantages, les échecs d'assertion et les cas où InnoDB/XtraDB écrit la sortie du moniteur dans le journal pour faciliter le débogage. Il peut également être envoyé à syslog si nécessaire.
Conclusion
La protection des données en transit est aussi importante que la protection des données au repos, et même si ce n'est pas un must dans votre organisation, vous devriez envisager de l'appliquer car cela peut vous aider à éviter les données vol ou accès non autorisé.
MariaDB a un moyen assez simple de l'implémenter en suivant les étapes mentionnées précédemment, mais c'est encore plus facile en utilisant ClusterControl à coup sûr.