OpenSSL peut-il être utilisé pour déboguer une connexion SSL à un serveur MySQL?

21

Je veux que mon serveur Web parle au serveur de base de données MySQL via une connexion SSL. Le serveur Web exécute CentOS5, le serveur de base de données exécute FreeBSD. Les certificats sont fournis par un CA DigiCert intermédiaire.

MySQL devrait utiliser ssl, selon my.cnf:

# The MySQL server
[mysqld]
port            = 3306
socket          = /tmp/mysql.sock
ssl
ssl-capath = /opt/mysql/pki/CA
ssl-cert = /opt/mysql/pki/server-cert.pem
ssl-key = /opt/mysql/pki/server-key.pem

Lorsque je démarre MySQL, le démon démarre sans erreur. Cela suggère que les fichiers de certificat sont tous lisibles.

Mais lorsque j'essaie de me connecter du serveur Web au serveur de base de données, j'obtiens une erreur:

[root@webserver ~]# mysql -h mysql.example.org -u user -p
ERROR 2026 (HY000): SSL connection error

Et si j'essaye de déboguer plus avant avec openssl:

[root@webserver ~]# openssl s_client -connect mysql.example.org:3306 0>/dev/null
CONNECTED(00000003)
15706:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:588:

Est-ce un moyen valide de tester la connexion SSL à un serveur de base de données MySQL? Le SSL23_GET_SERVER_HELLO:unknown protocolmessage est étrange car c'est généralement ce que vous verriez si vous parliez SSL sur un port destiné au trafic non SSL.

Cette même commande openssl semble fonctionner correctement avec les serveurs LDAP et HTTP:

$ openssl s_client -connect ldap.example.org:636  0>/dev/null
CONNECTED(00000003)
depth=2 /C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
...
$ openssl s_client -connect www.example.org:443  0>/dev/null
CONNECTED(00000003)
depth=0 /DC=org/DC=example/OU=Services/CN=www.example.org
Stefan Lasiewski
la source
Notez que vous pouvez également utiliser Wireshark pour inspecter le trafic SSL vers un serveur MySQL, voir i.imgur.com/5uTkLqU.png .
Jaime Hablutzel

Réponses:

11

OpenSSL version 1.1.1 (publié le 11 septembre 2018) a ajouté la prise -starttls mysqlen charge de la validation dans a2d9cfbac5d87b03496d62079aef01c601193b58 . Malheureusement, je ne trouve pas la référence à cette nouvelle fonctionnalité dans le changelog OpenSSL.

Si votre distribution n'a pas encore cette version, il existe un binaire openssl compilé statiquement à https://testssl.sh/openssl-1.0.2k-dev-chacha.pm.ipv6.Linux+FreeBSD.tar.gz qui prend en charge -starttls mysql. J'en ai trouvé la référence dans http://www.danneman.org/presentations/Automating_TLS_Configuration_Verification.pdf .

Pour Windows, les binaires OpenSSL 1.1.1 peuvent être trouvés sur https://wiki.openssl.org/index.php/Binaries

J'ai généré les certificats SSL comme décrit dans https://dev.mysql.com/doc/refman/5.7/en/creating-ssl-files-using-openssl.html , essayé et cela fonctionne:

$ echo | bin/openssl.Linux.x86_64.static s_client -starttls mysql -connect spx-bionic.censored.com:3306 -CAfile /tmp/ca.pem
CONNECTED(00000003)
depth=1 C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = mysql test CA
verify return:1
depth=0 C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = spx-bionic.censored.com
verify return:1
---
Certificate chain
 0 s:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=spx-bionic.censored.com
   i:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=mysql test CA
 1 s:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=mysql test CA
   i:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=mysql test CA
---
Server certificate
-----BEGIN CERTIFICATE-----
CENSORED
-----END CERTIFICATE-----
subject=/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=spx-bionic.censored.com
issuer=/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=mysql test CA
---
No client certificate CA names sent
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA+SHA224:RSA+SHA1:DSA+SHA1:ECDSA+SHA1
Shared Requested Signature Algorithms: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA+SHA224:RSA+SHA1:DSA+SHA1:ECDSA+SHA1
Peer signing digest: SHA512
Server Temp Key: ECDH, P-521, 521 bits
---
SSL handshake has read 2599 bytes and written 632 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: AD25B7C3018E4715F262188D982AAE141A232712316E0A3292B0C14178E0F505
    Session-ID-ctx: 
    Master-Key: C121967E8FAEC4D0E0157419000660434D415251B0281CCBFC6D7A2AE8B0CC63AEFE22B332E91D31424C1BF03E5AF319
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 7200 (seconds)
    TLS session ticket:
    0000 - 82 db 03 0f c0 ce f2 26-62 bd 1b 18 71 03 88 db   .......&b...q...
    0010 - a6 66 7c 71 94 0c d5 ec-96 30 46 53 4a e6 cd 76   .f|q.....0FSJ..v
    0020 - 66 b3 22 86 7d 9f 7e 2c-14 1d 66 f2 46 8f d2 d3   f.".}.~,..f.F...
    0030 - f7 0a 0b f5 9e 05 97 e1-2b b3 ba 79 78 16 b8 59   ........+..yx..Y
    0040 - dc c5 0d a8 de 0b 3a df-4b ec f9 73 3f 4c c3 f1   ......:.K..s?L..
    0050 - 86 b6 f7 aa a7 92 84 77-9f 09 b2 cc 5d dd 35 41   .......w....].5A
    0060 - 23 5d 77 74 e1 96 91 ac-28 81 aa 83 fe fc d2 3c   #]wt....(......<
    0070 - f9 23 09 6d 00 e0 da ef-48 69 92 48 54 61 69 e8   .#.m....Hi.HTai.
    0080 - 30 0e 1f 49 7d 08 63 9e-91 70 fc 00 9f cd fe 51   0..I}.c..p.....Q
    0090 - 66 33 61 24 42 8f c2 16-57 54 48 ec 6a 87 dc 50   f3a$B...WTH.j..P

    Start Time: 1537350458
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
DONE

Il existe également un -starttlssupport pour postgres et ldap dans OpenSSL 1.1.1. Voir https://github.com/openssl/openssl/blob/OpenSSL_1_1_1-stable/apps/s_client.c#L815-L831 pour la liste complète.

Paul Tobias
la source
12

Répondre à ma propre question. Si vous avez une meilleure réponse avec de bonnes sources faisant autorité, veuillez poster une réponse.

Réponse courte; Non, OpenSSL ne peut pas être utilisé pour déboguer les connexions SSL MySQL. En effet, MySQL démarre la session en utilisant du texte en clair et passe ensuite à SSL.

En lisant https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase.html , MySQL démarre avec une connexion en clair, puis le SSL réel est ensuite initié. Cela explique comment MySQL est capable d'écouter sur un port (port 3306) à la fois les connexions en clair et les connexions cryptées. Comparez cela à un serveur HTTP ou LDAP, où un port est utilisé pour les connexions en texte brut et un second port est utilisé pour les connexions cryptées.

Il commence par la connexion () du client au serveur qui peut envoyer un paquet ERR et terminer la prise de contact ou envoyer un paquet de prise de contact initial auquel le client répond avec un paquet de réponse de prise de contact. À ce stade, le client peut demander une connexion SSL, auquel cas un canal de communication SSL est établi avant que le client envoie sa réponse d'authentification

Stefan Lasiewski
la source
1
C'est la même chose que le fonctionnement de SMTP lorsque vous utilisez STARTTLS, et cela vous permet également d'utiliser une connectivité chiffrée et non chiffrée sur le même port.
Synchro
Hm, je suppose que le comportement dont je parle est le fonctionnement de STARTTLS, selon en.wikipedia.org/wiki/STARTTLS .
Stefan Lasiewski, du
2
Bien que MySQL fonctionne " comme STARTTLS", il n'implémente pas réellement STARTTLS, du moins pas du tout avec lequel j'ai trouvé qu'OpenSSL pouvait interagir avec succès.
Christopher Schultz
0

Je rencontre un problème similaire avec le client MacOS X communiquant avec un serveur Ubuntu.

Pouvez-vous vérifier si la connexion fonctionnera si vous omettez le certificat côté client et la clé client, simplement en ayant l'AC pour le certificat de serveur? Pouvez-vous établir une connexion cryptée? Cela nécessite normalement le paramètre ANY pour la colonne ssl_type de l'utilisateur associé.

user1204270
la source
0

Je voulais juste noter pour la postérité que si vous souhaitez utiliser un équilibreur de charge (comme un F5 ou HAProxy) entre MySQL et le client, vous voudrez importer votre certificat SSL de l'équilibreur de charge dans le serveur MySQL. Cela est dû au démarrage de la connexion de type STARTTLS.

Stephen
la source