News

Configurer une connection SSL sur MySQL 8.0.

le 3 Octobre 2018

Voici une procédure permettant de sécuriser les connexions MySQL 8.0 à l'aide de certificats SSL autosignés. Très utile pour des serveurs isolés, elle ne s'applique pas dans une infrastructure comportant une autorité de certification.

Cette procédure est fonctionnelle sur Centos 7.x et MySQL 8.0 mais elle doit fonctionner sans accroc sur les autres distributions Linux, et pour les versions 5.x de MySQL et sur MariaDB.

  1. Création des certificats

  2. Nous travaillons dans un répertoire temporaire puis nous copierons les fichiers aux bon endroits à la fin.

    Commencons par créer un jeu de certificats et de clés RSA 2048 valide 10 ans :

    mkdir /tmp/cert
    cd /tmp/cert
    openssl genrsa 2048 > /tmp/cert/mysqld-ca-key.pem
    openssl req -sha1 -new -x509 -nodes -days 3650 -key /tmp/cert/mysqld-ca-key.pem -subj "/C=FR/ST=/L=/O=mysqld/CN=mysqld-CA" > /tmp/cert/mysqld-ca-cert.pem
                        

    Nous générons ensuite les certificats du serveur avec les mêmes paramètres :

    openssl req -sha1 -newkey rsa:2048 -days 3650 -nodes -keyout /tmp/cert/mysqld-server-key.pem -subj "/C=FR/ST=/L=/O=mysqld/CN=mysqld-server" > /tmp/cert/mysqld-server-req.pem
    openssl rsa -in /tmp/cert/mysqld-server-key.pem -out /tmp/cert/mysqld-server-key.pem
    openssl x509 -sha1 -req -in /tmp/cert/mysqld-server-req.pem -days 3650 -CA /tmp/cert/mysqld-ca-cert.pem -CAkey /tmp/cert/mysqld-ca-key.pem -set_serial 01 > /tmp/cert/mysqld-server-cert.pem
                        

    Pour chaque utilisateur, Nous pouvons générer les certificats de la manière suivante :
    mkdir /tmp/client-cert
    cd /tmp/client-cert
    openssl req -sha1 -newkey rsa:2048 -days 3650 -nodes -keyout /tmp/client-cert/mysql-client-key.pem > /tmp/client-cert/mysql-client-req.pem -subj "/C=FR/ST=/L=/O=mysql-client/CN=mysql-client"
    openssl rsa -in /tmp/client-cert/mysql-client-key.pem -out /tmp/client-cert/mysql-client-key.pem
    openssl x509 -sha1 -req -in /tmp/client-cert/mysql-client-req.pem -days 3650 -CA /tmp/cert/mysqld-ca-cert.pem -CAkey /tmp/cert/mysqld-ca-key.pem -set_serial 01 > /tmp/client-cert/mysql-client-cert.pem
    

  3. Installation

  4. Les certificats et les clés doivent être déployés dans un répertoire correspondant aux paramètres 'ssl-ca', 'ssl-cert' et 'ssl-key' dans les fichiers de configuration de MySQL. Dans cet article, nous utilisons le répertoire /var/lib/mysql-keyring

    mkdir -p /var/lib/mysql-keyring
    cp /tmp/cert/mysqld-ca-cert.pem /tmp/cert/mysqld-server-cert.pem /tmp/cert/mysqld-server-key.pem /var/lib/mysql-keyring
    cp /tmp/cert/mysqld-ca-key.pem /var/lib/mysql-keyring
    chown -R mysql: /var/lib/mysql-keyring
    chmod 750 /var/lib/mysql-keyring
    chmod 640 /var/lib/mysql-keyring/*
    

    Puis ajoutez les lignes suivantes dans le fichier de configuration serveur (/etc/my.cnf par défaut)
    # SSL configuration
    ssl-ca = /var/lib/mysql-keyring/mysqld-ca-cert.pem
    ssl-cert = /var/lib/mysql-keyring/mysqld-server-cert.pem
    ssl-key = /var/lib/mysql-keyring/mysqld-server-key.pem
    


    Pour les utilisateur, nous utilisons le répertoire home : ~/.mysql-ssl :
    mkdir ~/.mysql-ssl
    cp /tmp/client-cert/mysql-client-key.pem /tmp/cert/mysqld-ca-cert.pem /tmp/client-cert/mysql-client-cert.pem ~/.mysql-ssl
    chmod 750 ~/.mysql-ssl
    chmod 640 ~/.mysql-ssl/*
    

    Puis ajoutez les lignes suivantes dans la section [client] du fichier de configuration client (~/.my.cnf par défaut)
    [client]
    ssl-ca = ~/.mysql-ssl/mysqld-ca-cert.pem
    ssl-cert = ~/.mysql-ssl/mysql-client-cert.pem
    ssl-key = ~/.mysql-ssl/mysql-client-key.pem 
    

  5. Activation et test

  6. Pour activer le SSL, rechargez simplement le démon MySQL :

    systemctl restart mysqld
    

    Pour tester, connectez vous à l'aide du client mysql puis vérifiez le cipher utilisé
    mysql
    mysql> SHOW STATUS LIKE 'Ssl%cipher%'\G
    *************************** 1. row ***************************
    Variable_name: Ssl_cipher
            Value: DHE-RSA-AES128-GCM-SHA256
    *************************** 2. row ***************************
    Variable_name: Ssl_cipher_list
            Value: ECDHE-ECDSA.... 
    2 rows in set (0,01 sec)
    

    En cas de problème, MySQL est très mal docummenté à ce jour (le bug est ouvert ici) et vous devriez rencontrer cette erreur :
    ERROR 2026 (HY000): SSL connection error: error:00000001:lib(0):func(0):reason(1)
    

    Cela indique très vraisemblablement une erreur dans la configuration de vos certificats et clés. Commencez par vérifier leur validité :
    openssl verify -CAfile /var/lib/mysql-keyring/mysqld-ca-cert.pem /var/lib/mysql-keyring/mysqld-server-cert.pem ~/.mysql-ssl/mysql-client-cert.pem
    server-cert.pem: OK
    client-cert.pem: OK
    

    Vérifiez ensuite que vous avez bien respecté les prérequis MySQL, notamment les Common Names qui doivent impérativement être différents : https://dev.mysql.com/doc/refman/8.0/en/creating-ssl-files-using-openssl.html

    Enfin, vous pouvez toujours vous connecter pour contrôler votre configuration en désactivant le SSL :
    mysql --ssl-mode=DISABLED