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;
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;
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%";
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%";
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%";
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.