Client cannot connect to remote mysql-server when the latter is configured with ssl parameters using a public CA

Bug #1890611 reported by jean-christophe manciot
260
This bug affects 1 person
Affects Status Importance Assigned to Milestone
mysql-8.0 (Ubuntu)
Expired
Undecided
Unassigned

Bug Description

Ubuntu focal
mysql-server-8.0: 8.0.21-0ubuntu0.20.04.4

in /etc/mysql/mysql.cnf (target of /etc/alternatives/my.cnf symlink):
ssl-ca=/etc/ssl/lets_encrypt/domain.chained.crt
ssl-cert=/etc/ssl/domain/domain.crt
ssl-key=/etc/ssl/domain/domain_rsakey.pem.decrypted

Those settings are read by the server:
# mysqld --verbose --help|grep ^ssl
ssl TRUE
ssl-ca /etc/ssl/lets_encrypt/domain.chained.crt
ssl-capath (No default value)
ssl-cert /etc/ssl/domain/domain.crt
ssl-key /etc/ssl/domain/domain_rsakey.pem.decrypted

Yet, they seems to have no effect:
# echo 'q' | sudo systemctl --no-pager --full status mysql
● mysql.service - MySQL Community Server
     Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2020-08-06 15:56:12 CEST; 6min ago
    Process: 93478 ExecStartPre=/usr/share/mysql/mysql-systemd-start pre (code=exited, status=0/SUCCESS)
   Main PID: 93503 (mysqld)
     Status: "Server is operational"
      Tasks: 41 (limit: 9280)
     Memory: 353.3M
     CGroup: /system.slice/mysql.service
             └─93503 /usr/sbin/mysqld
...
Aug 06 15:56:12 xxxxxxxxxxx mysqld[93503]: 2020-08-06T13:56:12.049846Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.

I am aware that some default certificates/keys are always created at each server start:
# find /var/lib/mysql/ -name "*.pem"
/media/WD320-DB/var/lib/mysql/8.0/public_key.pem
/media/WD320-DB/var/lib/mysql/8.0/ca-key.pem
/media/WD320-DB/var/lib/mysql/8.0/server-key.pem
/media/WD320-DB/var/lib/mysql/8.0/ca.pem
/media/WD320-DB/var/lib/mysql/8.0/server-cert.pem
/media/WD320-DB/var/lib/mysql/8.0/client-cert.pem
/media/WD320-DB/var/lib/mysql/8.0/private_key.pem
/media/WD320-DB/var/lib/mysql/8.0/client-key.pem

However, warning that "ca.pem is self signed" when another CA is configured seems to indicate that the latter is not used.

Also, testing the TLS connection with the mysql server across a network leads to an error (no such issue with other services running on the same host and using the same CA/wildcard certificate):

#openssl s_client -connect mysql.domain:3306 -msg -name $(hostname).$(dnsdomainname) -showcerts -state -status
CONNECTED(00000003)
SSL_connect:before SSL initialization
>>> ??? [length 0005]
    16 03 01 01 39
>>> TLS 1.3, Handshake [length 0139], ClientHello
    01 00 01 35 03 03 19 56 93 29 3b c6 43 6d d9 15
    79 99 9a aa 32 80 cc 6a df d8 03 23 ff 3d 8d 79
    08 9a 15 e4 f8 f2 20 74 54 f0 92 51 0f 27 d2 9d
    3d df fc bc 95 90 f1 0f 56 6b db 96 b2 4b 3b b4
    1b df be a3 cc 23 5a 00 3e 13 02 13 03 13 01 c0
    2c c0 30 00 9f cc a9 cc a8 cc aa c0 2b c0 2f 00
    9e c0 24 c0 28 00 6b c0 23 c0 27 00 67 c0 0a c0
    14 00 39 c0 09 c0 13 00 33 00 9d 00 9c 00 3d 00
    3c 00 35 00 2f 00 ff 01 00 00 ae 00 00 00 16 00
    14 00 00 11 6d 79 73 71 6c 2e 73 64 78 6c 69 76
    65 2e 63 6f 6d 00 0b 00 04 03 00 01 02 00 0a 00
    0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 00
    00 00 05 00 05 01 00 00 00 00 00 16 00 00 00 17
    00 00 00 0d 00 2a 00 28 04 03 05 03 06 03 08 07
    08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01
    05 01 06 01 03 03 03 01 03 02 04 02 05 02 06 02
    00 2b 00 05 04 03 04 03 03 00 2d 00 02 01 01 00
    33 00 26 00 24 00 1d 00 20 a4 a0 76 bb a9 bc b3
    cc 33 82 8e 5a b8 45 ad 95 72 42 27 f9 c6 81 32
    33 3b 35 25 ec 75 9a 1f 6a
SSL_connect:SSLv3/TLS write client hello
<<< ??? [length 0005]
    5b 00 00 00 0a
SSL_connect:error in error
139858538362176:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../ssl/record/ssl3_record.c:331:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 5 bytes and written 318 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)

information type: Private Security → Public Security
Revision history for this message
Rafael David Tinoco (rafaeldtinoco) wrote :
Download full text (3.6 KiB)

Hello Jean,

Thank you for taking the time to file a bug report.

So, in a clean Focal installation, if I do:

"""
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

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

[mysqld]
ssl-ca=/etc/mysql/ssl/ca.pem
ssl-cert=/etc/mysql/ssl/server-cert.pem
ssl-key=/etc/mysql/ssl/server-key.pem
ssl-capath=/etc/mysql/ssl/
"""

in my.cnf... I get:

2020-08-14T18:16:44.983214Z 0 [Warning] [MY-013414] [Server] Server SSL certificate doesn't verify: self signed certificate
2020-08-14T18:16:44.983499Z 0 [Warning] [MY-010068] [Server] CA certificate /etc/mysql/ssl/ca.pem is self signed.
2020-08-14T18:16:44.983822Z 0 [Warning] [MY-010068] [Server] CA certificate /etc/mysql/ssl//ca.pem is self signed.
2020-08-14T18:16:44.984106Z 0 [Warning] [MY-010068] [Server] CA certificate /etc/mysql/ssl//server-cert.pem is self signed.
2020-08-14T18:16:44.984412Z 0 [Warning] [MY-010068] [Server] CA certificate /etc/mysql/ssl//client-cert.pem is self signed.
2020-08-14T18:16:44.984777Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.

in /var/log/mysql/error.log.

Meaning that my certificate is being used. When testing:

mysql> status
--------------
mysql Ver 8.0.21-0ubuntu0.20.04.4 for Linux on x86_64 ((Ubuntu))

Connection id: 19
Current database:
Current user: root@localhost
SSL: Cipher in use is TLS_AES_256_GCM_SHA384
Current pager: less -R --chop-long-lines
Using outfile: ''
Using delimiter: ;
Server version: 8.0.21-0ubuntu0.20.04.4 (Ubuntu)
Protocol version: 10
Connection: Localhost via UNIX socket
Server characterset: utf8mb4
Db characterset: utf8mb4
Client characterset: utf8mb4
Conn. characterset: utf8mb4
UNIX socket: /var/run/mysqld/mysqld.sock
Binary data as: Hexadecimal
Uptime: 7 min 57 sec

and all certificates were created using Example 1 of https://dev.mysql.com/doc/refman/5.7/en/creating-ssl-files-using-openssl.html.

Permissions are:

$ ls -lahR ssl
ssl:
total 40K
drwxr-x--- 2 mysql root 4.0K Aug 14 18:31 .
drwxr-xr-x 5 root root 4.0K Aug 14 17:40 ..
-rw------- 1 mysql root 1.7K Aug 14 18:29 ca-key.pem
-rw-r--r-- 1 mysql root 1.4K Aug 14 18:29 ca.pem
-rw-r--r-- 1 mysql root 1.2K Aug 14 18:29 client-cert.pem
-rw-r--r-- 1 mysql root 1.7K Aug 14 18:29 client-key.pem
-rw------- 1 mysql root 1001 Aug 14 18:29 client-req.pem
-rw------- 1 mysql root 1.2K Aug 14 18:29 server-cert.pem
-rw------- 1 mysql root 1.7K Aug 14 18:29 server-key.pem
-rw------- 1 mysql root 1001 Aug 14 18:29 server-req.pem

Note that some files are +r just so my user can read them when executing mysql client.

With all that said, could you point out where you think the bug is and/or a way to reproduce what you are facing ?

Note: your openssl s_client command should change CA and verification paths to the place where you're placing the SSL certificates for mysql server. Nevertheless, its much easier to simply test it using the mysql client using the same configuration changes as [mysqld] in my.cnf.

Since it seems likely to me that t...

Read more...

Changed in mysql-8.0 (Ubuntu):
status: New → Incomplete
Revision history for this message
jean-christophe manciot (manciot-jeanchristophe) wrote :

I appreciate the time you took to answer.
However, your example is a different use case: you're using a self-signed certificate with a private CA.

My use case use a public CA (namely let's encrypt, but it could be anything else).
In my setup, client and servers are on totally different machines. They should be able to communicate over TLS like you're using your browser right now to communicate over https with the remote server https://bugs.launchpad.net/ which happens to also use let's encrypt as a public certificate.

I am aware that the official mysql doc only displays SSL examples using only a private CA.
I suspect this issue to come from an inability to perform correctly with a public CA/certificate.

Changed in mysql-8.0 (Ubuntu):
status: Incomplete → New
Revision history for this message
jean-christophe manciot (manciot-jeanchristophe) wrote :

I meant let's encrypt as a public certificate ... authority.

Also, if it is of any help:
mysql> status
--------------
mysql Ver 8.0.21-0ubuntu4 for Linux on x86_64 ((Ubuntu))

Connection id: 31
Current database:
Current user: root@localhost
SSL: Not in use
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server version: 8.0.21-0ubuntu4 (Ubuntu)
Protocol version: 10
Connection: Localhost via UNIX socket
Server characterset: utf8mb4
Db characterset: utf8mb4
Client characterset: utf8mb4
Conn. characterset: utf8mb4
UNIX socket: /var/run/mysqld/mysqld.sock
Binary data as: Hexadecimal
Uptime: 15 hours 45 min 24 sec

Revision history for this message
Robie Basak (racb) wrote :

There is no fundamental difference between a "public" and a "private" CA. The only difference is in what root certificates (if any) are trusted.

Since your report is "mysql-server does not take into account configured ssl parameters" I see no reason why a simple reproduction of your case with self-signed certificates should not be possible.

I suggest you start by trying to provide full steps to reproduce your problem using self-signed certificates. If you cannot, but the same configuration steps do not work when adjusted to use certificates signed by Let's Encrypt, then that would demonstrate that the problem somehow only exhibits itself when using a "public CA". Either way, please provide such reproduction steps and then we can look again.

Changed in mysql-8.0 (Ubuntu):
status: New → Incomplete
Revision history for this message
jean-christophe manciot (manciot-jeanchristophe) wrote :

I changed the title to better reflect the core issue of this thread.

summary: - mysql-server does not take into account configured ssl parameters
+ Client cannot connect to remote mysql-server when the latter is
+ configured with ssl parameters using a public CA
Revision history for this message
jean-christophe manciot (manciot-jeanchristophe) wrote :

I suggest you try to configure your mysql-server with SSL parameters using a public CA, since this is the use case of this issue.

Changed in mysql-8.0 (Ubuntu):
status: Incomplete → New
Revision history for this message
Paride Legovini (paride) wrote :

Hi,

I'd say that the problem is with mysqld using a different CA certificate from the one specified by the ssl-ca option. I doubt it's the letsencrypt certificate the one being used, correct me if I'm wrong (y can check with e.g. `openssl c_client`).

Could you please:

1. share the ssl config snippet from mysql.cnf?

2. confirm that you don't need the client part to reproduce the problem, as the "CA is self-signed" message is a mysqld log message that is printed before any connection attempt? This is mostly to verify that I correctly understood the problem.

3. Set ssl-capath to /etc/ssl/lets_encrypt/ and see if it behaves differently?

Please change the report status back to New after commenting back. Thanks!

Changed in mysql-8.0 (Ubuntu):
status: New → Incomplete
Revision history for this message
jean-christophe manciot (manciot-jeanchristophe) wrote :

1. already shared in my first post
2. You don't seem to understand this issue.
Not a problem, because in the meantime, I have upgraded to groovy with:

mysql-server-8.0:
  Installed: 8.0.21-0ubuntu4

Now I get:
...
SSL_connect:SSLv3/TLS write finished
---
Certificate chain
 0 s:CN = *.domain
   i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
-----BEGIN CERTIFICATE-----

This issue has been solved on groovy.

FYI, the systemd service continues to show an incorrect warning:
[Warning] [MY-010068] [Server] CA certificate ca.pem is self signed

Changed in mysql-8.0 (Ubuntu):
status: Incomplete → Fix Released
Changed in mysql-8.0 (Ubuntu):
status: Fix Released → New
Revision history for this message
jean-christophe manciot (manciot-jeanchristophe) wrote :

Sorry: I have inadvertently tested with a port matching another service (853 instead of 3306), so my previous post must be ignored.

This issue is still there, even on groovy. Let me answer your questions again:

0) with a service answering correctly to TLS connections requests, we get with a wildcard server certificate:
...
SSL_connect:SSLv3/TLS write finished
---
Certificate chain
 0 s:CN = *.domain
   i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
-----BEGIN CERTIFICATE-----

As my first post shows, there is an initial error in the connection preventing openssl to show the CA used or the server certificate:
...
SSL_connect:error in error
139858538362176:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../ssl/record/ssl3_record.c:331:
---
no peer certificate available
---

1) The full SSL configuration (besides the 3 parameters already described in my first post) also includes the following parameters which are IMHO not relevant because his issue still happens if I remove them:
ssl-cipher=...
tls-version=...
require_secure_transport=ON

2) You don't seem to understand this issue. The client don't need special configuration, other than at least one matching cipher and required TLS version if they are specified on the server side.

3)I have already tried that: same issue.

Revision history for this message
Lucas Kanashiro (lucaskanashiro) wrote :

Hi Jean-Christophe,

Sorry for this back and forth, I tried again to reproduce what you mentioned but with a self-signed CA (like Rafael did in the first comment) and it worked like a charm. Before you saying this is not the same scenario you are facing, as far as I can see you are reporting a problem when setting the ssl parameters (if the logs are saying "CA certificate ca.pem is self signed" is because it is likely not reading the files from your Let's Encrypt directory). In this case it does not matter if it's a private or public CA. If you can confirm it is reading your Let's Encrypt files and it is reporting that the certificate is self signed share the logs and config files here and it will likely be an upstream issue.

You might be tired of us asking for reproduction steps but there is no way around that, we can't reproduce your problem. Try to add as much details as you can, for instance, create a new container/VM of Ubutu Focal/Groovy, install mysql-server, run command X, edit these files adding these content, restart mysql service and so on.

I am marking this bug again as Incomplete, when you have more input for us please change the status back to New.

Changed in mysql-8.0 (Ubuntu):
status: New → Incomplete
Revision history for this message
jean-christophe manciot (manciot-jeanchristophe) wrote :

Same issue with mysql-server 8.0.21-1 on groovy.

Revision history for this message
Launchpad Janitor (janitor) wrote :

[Expired for mysql-8.0 (Ubuntu) because there has been no activity for 60 days.]

Changed in mysql-8.0 (Ubuntu):
status: Incomplete → Expired
To post a comment you must log in.
This report contains Public Security information  
Everyone can see this security related information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.