How to use SSL with the MySQL tile
search cancel

How to use SSL with the MySQL tile

book

Article ID: 428995

calendar_today

Updated On:

Products

VMware Tanzu for MySQL

Issue/Introduction

Following documentation https://mysqlconnector.net/connection-options/#ssltls-options

There are several options to establish SSL connection with mysql service:

This option has the following values:

Preferred - (this is the default). Use SSL if the server supports it.
Disabled (or None) - Do not use SSL.
Required - Always use SSL. Deny connection if server does not support SSL. Does not validate CA or hostname.
VerifyCA - Always use SSL. Validates the CA but tolerates hostname mismatch.
VerifyFull - Always use SSL. Validates CA and hostname.

When using VerifyCA .Net application can connect successfully, however using VerifyFull fails.

How to identify the problem and be able to connect successfully

Environment

EAR 10.2.x

VMware Tanzu for MySQL on Tanzu Platform 10.x

Cause

The difference between the two methods are in the level of verification.

VerifyCA - Always use SSL. Validates the CA but tolerates hostname mismatch.  This method verify only if the CA is trusted and then establishes connection, this method will not complete full verification of the server certificates and if they match the connection name 

VerifyFull - Always use SSL. Validates CA and hostname. This method checks the CA but also verify if the connection to the server matches the server certificate Canonical Name or Subject Alternative Name.

For example test with curl can easily confirm the difference. 

Steps:

Connect to mysql instance in bosh and go to path: 

bosh -d service-instance_<ID> ssh mysql/<ID>
sudo -i
cd /var/vcap/jobs/mysql/certificates/
/var/vcap/jobs/mysql/certificates# ll
total 20
drwxr-x--- 2 root vcap 4096 Feb  5 10:14 ./
drwxr-x--- 8 root vcap 4096 Feb  5 10:14 ../
-rw-r----- 1 root vcap 1196 Feb  5 10:14 ca.pem
-rw-r----- 1 root vcap 1375 Feb  5 10:14 server-cert.pem
-rw-r----- 1 root vcap 1675 Feb  5 10:14 server-key.pem

Confirm the server certificate CN and SAN names:

openssl x509 -in server-cert.pem -noout -subject -ext subjectAltName
subject=CN = 70bdfe4a-xxxx-xxxx-xxxx-b505ac622c3e.mysql.service.internal
X509v3 Subject Alternative Name:
    IP Address:127.0.0.1, DNS:70bdfe4a-xxxx-xxxx-xxxx-b505ac622c3e.mysql.service.internal, DNS:*.q-g117.bosh

Simulate mysql connection with strict verify such request if using the SAN or CN from above will complete:

openssl s_client -CAfile ca.pem -starttls mysql -connect 70bdfe4a-xxxx-xxxx-xxxx-b505ac622c3e.mysql.service.internal:3306 -verify_hostname 70bdfe4a-xxxx-xxxx-xxxx-b505ac622c3e.mysql.service.internal

Simulate invalid request where instead of FQDN use the IP of the mysql instance this IP is not defined in the certificate therefore the verification will wail:

openssl s_client -CAfile ca.pem -starttls mysql -connect 192.168.xx.xx:3306 -verify_hostname 192.168.xx.xx
.....
---
SSL handshake has read 1803 bytes and written 765 bytes
Verification error: hostname mismatch
---

Resolution

There could be multiple reasons that such communication can fail, however verifying the communication between source and destination should help to determine the what the possible reason could be

Common issues found this way:

1. Hostname Mismatch (The "SAN" Issue)
This is the most common cause. The certificate generated by the MySQL tile often uses internal platform hostnames that could be a mismatch with the actual request. 

2. Connecting via IP Address instead of Hostname
If your .NET application is configured to connect to an IP address (common in some tiled environments where DNS isn't perfectly propagated), VerifyFull will fail unless that specific IP address is explicitly listed in the certificate's SAN field.

3. Wildcard Certificate Limitations
If the MySQL tile uses a wildcard certificate (e.g., *.mysql.internal), SSL/TLS verification rules state that a wildcard only covers one level of subdomains.

Example: *.mysql.internal matches db1.mysql.internal but does not match node1.clusterA.mysql.internal.