Mysql – Cryptage SSL des connexions sous Debian Jessie

Pour plusieurs raisons propres, vous devez ouvrir votre serveur mysql vers l’extérieur. Vous trouverez de nombreux tutoriels afin de le faire. Mais ici, nous allons voir comment sécuriser vos communications entre le client et le serveur rendant ainsi impossible d’intercepter par sniffage un mot de passe ou le résultat de vos requêtes.
Il serait gênant de devoir expliquer à vos clients que leurs informations personnelles sont entre les mains de hackers malins.

Pre-requis

Serveur Debian 8 jessie dont l’ip sera 192.168.0.1
le package mysql-server installé

Information Importante

La documentation de mysql 5.5 décrit la manière de sécuriser les connexions, vous trouverez aussi de nombreux tutoriels décrivant les processus. Néanmoins, ces dernières ne fonctionnent pas sous Debian 8 à cause d’openssl. La version actuelle d’openssl sous jessie est la 1.0.1t alors que lors de l’écriture des tutoriels officiels, la version était 0.9.8. Il en découle une différence dans les protocoles PKS. La procédure décrite ci dessous en tient compte.

Ouvrir les connexions distantes

En premier lieu, nous allons modifier le fichier /etc/my.cnf afin de dire à mysql d’ouvrir son port 3306 vers l’extérieur.

sed -i '/bind-address/ s/^/# /' /etc/mysql/my.cnf
service mysql restart

Il faut maintenant faire deux choses.
La première : vérifiez que vous n’avez pas déjà un utilisateur ayant pour attribut un host % (signifiant que vous acceptez des connexions de partout) et la deuxième, de savoir créer un utilisateur.

mysql -u root -p

puis dans le shell mysql on commence par vérifier

select user,host from mysql.user;
sortie bash mysql requete
Comme on peut le voir, pas d’utilisateur ouvert vers l’extérieur.

On créé maintenant un utilisateur ssl_user provenant de l’adresse 192.168.0.10.

CREATE USER "ssl_user"@"192.168.0.10" IDENTIFIED BY "mot_de_passe";
GRANT SELECT, SHOW DATABASES ON *.* TO "ssl_user"@"192.168.0.10" REQUIRE SSL;
FLUSH PRIVILEGES;

On vérifie le tout :
select user,host,ssl_type from mysql.user;
sortie bash mysql requete
On peut voir le champ ssl_type avec la valeur ANY qui montre que l’utilisateur sssl_user accepte n’importe quel type de chiffrement ssl.

Création et déploiement des certificats SSL

Nous allons en premier lieu vérifier que votre serveur mysql est bien compilé avec le support SSL. Normalement, si vous êtes passé par les dépôts, pas de soucis à se faire

toujours depuis le shell mysql tapez :
show variables LIKE "%ssl%";
sortie bash mysql requete

Comme vous pouvez le voir, on est en etat DISABLED.
Jusque là rien d’anormal, si vous aviez eu NO à la place cela vous indiquerait alors que votre serveur Mysql n’est pas compilé avec openssl.

Géneration des certificats

Personnellement, je range mes certificats dans le même dossier que la configuration mysql


cd /etc/mysql && mkdir MysqlCertif
cd MysqlCertif

Nous allons y stocker les certificats de l’autorité de certification, du serveur et du client.

Autorité de certification


openssl genrsa 2048 > ca-key.pem
openssl req -new -x509 -nodes -days 1825 -key ca-key.pem > ca-cert.pem

On génère donc une clé de 2048 bits (le maximum légal en France, perso je mets plus …) valable 1825 jours soit 5 ans.

Certificat serveur


openssl req -newkey rsa:2048 -days 1825 -nodes -keyout serverMysql-key.pem > serverMysql-req.pem
openssl x509 -req -in serverMysql-req.pem -days 1825 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > serverMysql-cert.pem
openssl rsa -in serverMysql-key.pem -out serverMysql-key.pem

Certificat Client


openssl req -newkey rsa:2048 -days 30 -nodes -keyout clientMysql-key.pem > clientMysql-req.pem
openssl x509 -req -in clientMysql-req.pem -days 30 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > clientMysql-cert.pem
openssl rsa -in clientMysql-key.pem -out clientMysql-key.pem

j’ai modifié la validité du certificat client à 30 jours afin de vous montrer que vous pouvez donner ainsi une date de péremption et bloquer la connexion au bout de 30 jours

Cela évite aussi de laisser traîner des certificats valides dans la nature trop longtemps.

on fini en mettant les certificats avec les droits mysql

chown -R mysql:mysql /etc/mysql/MysqlCertif

Configuration du serveur mysql

Editez le fichier /etc/mysql/my.cnf

dans la section [mysqld] ajoutez :

ssl-ca=/etc/mysql/MysqlCertif/ca-cert.pem
ssl-cert=/etc/mysql/MysqlCertif/serverMysql-cert.pem
ssl-key=/etc/mysql/MysqlCertif/serverMysql-key.pem

Il ne reste plus qu’à redémarrer le service

service mysql restart

Vérifions maintenant que tout fonctionne :

Dans la console mysql :
show variables LIKE "%ssl%";

sortie bash mysql requete serveur ok

On a bien la confirmation que tout est ok.

Configuration cote client

En premier lieu, il faut récupérer les fichiers pour le certificat client

Les fichiers à transmettre sont :

  • /etc/mysql/MysqlCertif/ca-cert.pem
  • /etc/mysql/MysqlCertif/clientMysql-cert.pem
  • /etc/mysql/MysqlCertif/clientMysql-key.pem

Pour le client, vous avez deux manières de vous connecter.

Soit en ligne de commandes :
mysql -u ssl_user -p -h 192.168.0.1 --ssl-ca=/etc/mysql/MysqlCertif/ca-cert.pem --ssl-cert=/etc/mysql/MysqlCertif/clientMysql-cert.pem --ssl-key=/etc/mysql/MysqlCertif/clientMysql-key.pem

Soit directement dans le fichier my.cnf du client sous la section [client] :

éditez le fichier my.cnf

vim /etc/mysql/my.cnf

ssl-ca=/etc/mysql/MysqlCertif/ca-cert.pem
ssl-cert=/etc/mysql/MysqlCertif/clientMysql-cert.pem
ssl-key=/etc/mysql/MysqlCertif/clientMysql-key.pem

redémarrer le service

service mysql restart

on teste la connexion :

mysql -u ssl_user -p -h 192.168.0.1

Si tout fonctionne en tapant \s dans la console mysql on aura :

Que voit t’on la dedans? Première chose, le SSL fonctionne car on a le Cipher in use is DHE-RSA-AES256-SHA, la deuxième chose, je vous laisse la deviner et la mettre en commentaire.

Vérifier la sécurité

On pourrait s’arrêter là, mais on va aller un peu plus loin en regardant de plus près ce que l’on a avec mysql 5.5

dans votre console mysql :

SHOW GLOBAL STATUS where Variable_name like "Ssl%";

sortie bash mysql requete option global

On voit donc que la version ssl est TLSv1, ce qui est une bonne chose.
Le cipher est calé sur DHE-RSA-AES256-SHA ce qui est bon aussi.

Maintenant il faudra passer sous mysql 5.7 pour pouvoir modifier les valeurs et forcer par exemple le serveur en TLSv1.2.

Conclusion

Voila vos connexions extérieures cryptées.
Le cryptage de la connexion va un peu consommer de ressources mais d’après plusieurs benchmark cela est minime. Vous aurez par contre une latence augmentant proportionnellement avec le nombre de connexion actives.
Autre désavantage à prendre en compte, certains logiciels, sondes de monitoring ne fonctionnent pas avec une connexion cryptée ssl.

Laisser un commentaire