Classé | Boulot

Data-in-Transit Encryption with MariaDB

Sécuriser les données au repos c’est important, mais sécuriser les flux l’est tout autant.

Donc, après une petite synthèse sur Data-at-Rest Encryption avec Transparent Data Encryption, voyons comment mettre un peu de confidentialité dans le transport.

Un peu de cuisine pour commencer … En ces temps de confinement, cet article servira de support à un TP que nous jouerons avec les LP DLIS de l’IUT de Vannes semaine prochaine.

On va ouvrir un accès sur une base MariaDB exposée sur Internet … ouais, on des fous 🙂

Bon, on va quand même avant toute chose activer les logs sur le fameux SGBD histoire de voir qui attaque sans passer par un proxy. Attention malgré tout car dans les fameux fichiers de logs on retrouve aussi en particulier, les requêtes de création de comptes avec si on n’y prends pas garde le mot de passe en clair (et accessoirement toutes les commandes pourries)  :

logs mariaDB

logs mariaDB

root@vpsxxxxxx:/etc/mysql/mariadb.conf.d# ls /var/log/mysql/mysql.log -lart
-rw-rw—- 1 mysql adm 182 Mar 27 11:56 /var/log/mysql/mysql.log

 

 

Pour faire les choses un petit peu sérieusement, on n’ouvrira qu’une base sur internet avec un seul compte dédié créé pour l’occasion, histoire d’avoir un peu de cloisonnement.

Forcément et heureusement, dans un premier temps ça ne passe pas. Il faut modifier la configuration par défaut qui n’autorise que les connexions depuis le poste local.

can't connect to mariaDB

can’t connect to mariaDB

 

 

 

 

 

 

Et puis, après quelques efforts, la connexion peut enfin être établie…

mysql from everywher for everyone

mysql from everywher for everyone

 

 

 

Faudrait pas croire que votre mot de passe circule en clair (contrairement au trafic suivant l’authentification) .

Il se dit que le mot de passe suivrait  le mécanisme de chiffrement détaillé ici  :

https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase_authentication_methods_native_password_authentication.html

Malheureusement, à cet instant (20200329151524) je n’arrive pas à retrouver dans mon pcap les 20 octets de nonce (on nous ment ?)

Scramble data

Scramble data

 

 

 

 

 

 

 

Bref, quoi, qu’il en soit et au delà de la vérification de l’implémentation de ce mécanisme, revenons au chiffrement du flux …

Etape 1 – Créer le certificat racine de l’autorité de certification (CA)

 

Créons un dossier tls dans le répertoire /etc/mysql/  (parce que ssl c’est tellement vingtième siècle):

$ cd /etc/mysql
$ sudo mkdir tls
$ cd tls

Note: La valeur du Common Name (CN) utilisée pour les certificats serveur MariaDB et le client doivent être différents du Common Name utilisé pour le certificat racine de l’autorité de certification. Pour éviter tour problème, j’ai utilisé les valeurs suivantes :
Common Name de la CA : MariaDB admin
Common Name du serveur : MariaDB server
Common Name du client : MariaDB client

Dans la vraie vie, la CA serait hébergée sur une autre machine.

Génération de la paire de clefs RSA

$ sudo openssl genrsa 2048 > BZHITSCA-key.pem

Génération du certificat de la clef publique ( tip : pour être très précis, on parle donc de certificat DE clef publique)

$ sudo openssl req -new -x509 -nodes -days 365000 -key BZHITSCA-key.pem -out BZHITSCA-cert.pem

On lui donne une validité de 1 000 ans, ce qui nous donnera le temps de jouer.

 

Par abus de langage on associe souvent la commande précédente à une simple génération de clef privée. Mais en fait le fichier .pem produit permet aussi d’exporter la clef publique.

$ sudo openssl rsa -in BZHITSCA-key.pem -pubout -out BZHITSCA-pubkey.pem

Etape 2 – Créer le certificat du serveur MariaDB

Génération de la clef et de la Certificate Signing Request

$ sudo openssl req -newkey rsa:2048 -days 365 -nodes -keyout SERVER-key.pem -out SERVER-req.pem

Le deuxième objet créé est la requête de demande de signature de certificat (Certificate Signing Request = CSR). Donc, généralement on peut dire qu’un certificat c’est un fichier contenant des « informations » relatives à une entité et la clef publique de cette même entité ayant subi une signature numérique par l’autorité de certification (qui certifie donc que la clef publique représente bien l’entité en question). Capito ?

Export de la clef RSA

$ sudo openssl rsa -in SERVER-key.pem -out SERVER-key.pem

Signature du certificat du serveur

$ sudo openssl x509 -req -in SERVER-req.pem -days 365000 -CA BZHITSCA-cert.pem -CAkey BZHITSCA-key.pem -set_serial 01 -out SERVER-cert.pem

Etape 3 – Générer les certificats du client

Génération de la clef et de la Certificate Signing Request

$ sudo openssl req -newkey rsa:2048 -days 365 -nodes -keyout SERVER-key.pem -out SERVER-req.pem

Le deuxième objet créé est la requête de demande de signature de certificat (Certificate Signing Request = CSR). Donc, généralement on peut dire qu’un certificat c’est un fichier contenant des « informations » relatives à une entité et la clef publique de cette même entité ayant subi une signature numérique par l’autorité de certification (qui certifie donc que la clef publique représente bien l’entité en question). Capito ?

Export de la clef RSA

$ sudo openssl rsa -in SERVER-key.pem -out SERVER-key.pem

Signature du certificat du serveur

$ sudo openssl x509 -req -in SERVER-req.pem -days 365000 -CA BZHITSCA-cert.pem -CAkey BZHITSCA-key.pem -set_serial 01 -out SERVER-cert.pem

Etape 4 – Copier les certificats sur le client

Configuration du client

mkdir /etc/mysql/client-ssl && cd /etc/mysql/client-ssl

# Copy the following files: CLIENT-cert.pem, CLIENT-key.pem and BZHITSCA-cert.pem
scp root@REMOTE_SERVER_IP:~/cert/{client-cert.pem,client-key.pem,ca-cert.pem} ./

chmod -R 700 /etc/mysql/client-ssl

Editer my.cnf pour configurer les chemins vers les certificats:

nano /etc/mysql/my.cnf

et ajouter:

[client]
ssl-ca =   /etc/mysql/client-ssl/ca-cert.pem
ssl-cert = /etc/mysql/client-ssl/client-cert.pem
ssl-key =  /etc/mysql/client-ssl/client-key.pem

 

Etape 5 – Configurer le serveur MariaDB

Editer  le fichier /etc/mysql/mariadb.conf.d/50-server.cnf ou bien /etc/mysql/mariadb.cnf comme suit:

$ sudo vi /etc/mysql/mariadb.conf.d/50-server.cnf

Ajouter dans le bloc [mysqld]:

### MySQL Server ###
## Securing the Database with ssl option and certificates ##
## There is no control over the protocol level used. ##
##  mariadb will use TLSv1.0 or better.  ##
ssl
ssl-ca=/etc/mysql/ssl/ca-cert.pem
ssl-cert=/etc/mysql/ssl/server-cert.pem
ssl-key=/etc/mysql/ssl/server-key.pem

Savegarder le fichier etredémarrer mariadb :
$ sudo /etc/init.d/mysql restart

Etape 6 – Créer un nouvel utilisateur et se connecter

 

CREATE USER 'secure_user'@'%' IDENTIFIED BY 'my_password';
GRANT ALL PRIVILEGES ON votre_base.* TO securee_user@'%' REQUIRE SSL;
FLUSH PRIVILEGES;

 

Vous pouvez alors en principe vous connecter avec TLS:

mysql -h REMOTE_SERVER_IP -u remote_user -p"my_password"
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 5
Server version: 10.1.26-MariaDB-0+deb9u1 Debian 9.1

Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> Bye

 

Pour mémoire (pas mal de liens qui m’ont permis de comprendre) :

https://stackoverflow.com/questions/38167587/how-to-use-wireshark-to-capture-mysql-query-sql-clearly

How to get the network packets between MySQL client and server?


tcpdump -nnei any port 3306 -w tmp.pcap
https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase_authentication_methods_native_password_authentication.html

http://databaseblog.myname.nl/2017/03/network-attacks-on-mysql-part-1.html

https://www.cyberciti.biz/faq/how-to-setup-mariadb-ssl-and-secure-connections-from-clients/

https://www.gab.lc/articles/mysql_with_ssl/

capture wireshark

capture wireshark

Répondre

You must be logged in to post a comment.