MYSQL enforcing client authentication in application - mysql

I was trying to establish tls between an app and mysql server (no mutual authentication is needed in this case)
URL passed in my Hibernate Property file:
hibernate.dialect=net.sf.hibernate.dialect.MySQLDialect
hibernate.connection.url=jdbc:mysql://mysql-0:3306/dbschema?useSSL=true&requireSSL=false&trustCertificateKeyStoreUrl=file:/opt/jks/truststore.jks&trustCertificateKeyStorePassword=test12
Also I'm passing configuration in percona server like this :
mysqld --ssl-ca=/custom_certs/ca-test.pem --ssl-cert=/custom_certs/server-cert-test.pem --ssl-key=/custom_certs/server-key-test.pem --require-secure-transport=ON
After doing all the changes and adding trust store to the app, while starting application tls ceremony is enforcing client certificate retrieval.
Network capture looks like this:
MySQL --> Login Request user= TLSv1.2 Client Hello
TLSv1.2 --> Server Hello, Certificate, Server Key Exchange, Certificate Request, Server Hello Done
TLSv1.2 --> Certificate
TLSv1.2 --> Alert (Level: Fatal, Description: Unknown CA)
I also verified the user table to see if there's requireX509 column enforced as true for the said user, but that was not the case.
What can be the root cause of the issue? Is there any missing hibernates / mysql property or some other configuration that is possible via code?
Please note: Here I don't have the access to the code of app. Only configuration files are accessible via k8s secrets.

Related

The server uses a certificate signed by an unknown authority

Any help or hint would be greatly appreciated it!!
I have windows 11 Pro.
I installed openshift.
I did "crc setup" and I did "crc start":
INFO Adding crc-admin and crc-developer contexts to kubeconfig...
ERRO Cannot update kubeconfig: x509: certificate has expired or is not yet valid: current time 2022-05-24T00:01:26-04:00 is after 2022-01-13T22:29:55Z
Started the OpenShift cluster.
The server is accessible via web console at:
https://console-openshift-console.apps-crc.testing
I get the following error when I tried to login:
C:\Users\Albert Lam>oc login -u developer https://api.crc.testing:6443
The server uses a certificate signed by an unknown authority.
You can bypass the certificate check, but any data you send to the server could be intercepted by others.
Use insecure connections? (y/n): n
error: The server uses a certificate signed by unknown authority. You may need to use the --certificate-authority flag to provide the path to a certificate file for the certificate authority, or --insecure-skip-tls-verify to bypass the certificate check and use insecure connections.
C:\Users\Albert Lam>oc login -u developer https://api.crc.testing:6443
The server uses a certificate signed by an unknown authority.
You can bypass the certificate check, but any data you send to the server could be intercepted by others.
Use insecure connections? (y/n): y
I had the same problem and it was caused by an old certificate that was expired and had nothing to do (VMware one) with Openshift.
I've found the problem by viewing the certificate inside my chrome browser after navigating to https://console-openshift-console.apps-crc.testing.
The correct certificate should have *.apps-crc.testing as CN, but mine has another one.
I suggest you to find the wrong certificate and delete it if expired.
On windows, for VMware you can find it inside C:\ProgramData\VMware\SSL.
On Windows you can look for certificates by using the "manage certificates" app.

How to send a request with SNI in k8s ingress or OpenShift route

In OpenShift platform, I created a route for https service as following. The route is https pass-through type, and hostname is "www.https.com".
oc get route
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
abc-route www.https.com abc-service 8888 passthrough None
I have a few of questions for the above, in the document https://docs.openshift.com/container-platform/3.11/architecture/networking/routes.html, it mentions the route supports https with SNI and TLS with SNI:
(1) Is hostname "www.https.com" a SNI?
(2)I am wondering how client side send a request with SNI? The above mentioned two scenarios: https with SNI and TLS with SNI.
Thanks.
From RFC 3546 and RFC 6066:
3.1. Server Name Indication
[TLS] does not provide a mechanism for a client to tell a server
the name of the server it is contacting. It may be desirable for
clients to provide this information to facilitate secure
connections to servers that host multiple 'virtual' servers at a
single underlying network address.
In order to provide the server name, clients MAY include an
extension of type "server_name" in the (extended) client hello.
Where client hello message is a part of TLS hanshake.
The 'client hello' message: The client initiates the handshake by sending a "hello" message to the server. The message will include which TLS version the client supports, the cipher suites supported, and a string of random bytes known as the "client random."
Is hostname "www.https.com" a SNI?
Any dns name can be a valid SNI. From RFC:
Currently the only server names supported are DNS hostnames, however
this does not imply any dependency of TLS on DNS, and other name
types may be added in the future (by an RFC that Updates this
document). TLS MAY treat provided server names as opaque data and
pass the names and types to the application
I am wondering how client side send a request with SNI? The above mentioned two scenarios: https with SNI and TLS with SNI.
From RFC:
In order to provide the server name, clients MAY include an
extension of type "server_name" in the (extended) client hello.
The "extension_data" field of this extension SHALL contain
"ServerNameList" where:
<<redacted for readibility>>
HTTPS with SNI and TLS with SNI are different in a way that HTTPS is L7 and TSL is L4 of OSI model.
This means that SNI can be used for domain based routing not only for http traffic but also for raw tls traffic.

MySQL TLS verification via OpenSSL Fails

I have my MySQL instance configured to use TLS. I have verified this by intentionally using untrusted certificates and watching the clients fail to connect (with an appropriate error message) and then restarting the MySQL service with trusted certificates configured and having the clients connect successfully.
I wanted to do a final check using openssl's s_client but I can't get it to work. When I execute the command below, I get an error saying "SSL23_GET_SERVER_Hello:unknown protocol" followed by "no peer certificate available" followed by some more text. However, when I use the same command against a TLS-enabled Tomcat instance and against the Remote Desktop port, I am able to establish the connection and view the server's certificate. What am I doing wrong? Does MySQL do some extra pre-negotiation before the TLS handshake starts?
openssl s_client -showcerts -connect host:port
While MySQL may use TLS, it isn't the total outside layer. There is a small amount of preamble that occurs before TLS starts. The openssl command line isn't aware of this.
Use the mysql client with its TLS options to test the client certificate.
I marked the response from #danblack correct as he did answer the question. However, I want to provide more information in case it helps anyone else. The
small amount of preamble that occurs before TLS starts
that he refers to can be found on GitHub here.

SSL encrypted connection to MySQL container not possible over AWS elastic load balancer

I am trying to establish a SSL-encrypted connection to a my MySQL Docker service running on a AWS VPC (setup up by the Docker for AWS cloud formation template). The elastic load balancer is configured to redirect port 3306. There is no problem to connect to the container (e.g. by using MySQLWorkbench, mysql-client, ..) as long as SSL is not turned on (adding AWS's own certificates (ACM) or my custom certificates to the ELB listener). In case SSL is enabled, the client starts hanging / freezing, without returning a proper error. I added the ca-certs from ACM, generated my own certificates (with and without additonal key / cert for the client) but nothing seems to resolve my problem.
Now I am well aware of the fact, that this setup is not that usual. I guess the standard way of doing this is to configure the MySQL-Server itself. AFAIK, in this case only the connection between client and ELB is encrypted, but I do not understand why this causes a problem?
I am grateful for answers!
In MySQL's client/server protocol, the server talks first. It advertises its capabilities (including whether it supports SSL). Then the client requests that the connection switch to SSL mode. Only then does SSL negotiation take place.
For this reason, it is not possible to offload SSL in front of MySQL.
Your connection hangs because the client is waiting for the initial packet from the server, while the ELB is waiting for the client to start negotiating SSL -- because unlike the MySQL client/server protocol, the client talks first on standard SSL negotiation.
You have to have a certificate on the MySQL Server, and not on the ELB, for this to work.
An AWS Network Load Balancer is a more appropriate solution for exposing MySQL, but you still need the SSL cert on the MySQL Server itself.

MariaDB Replication SSL Certificate Verification

I am attempting to establish MariaDB replication using SSL Certificates for authentication. Reading the documentation about setting up the master server with a slave user which uses the GRANT command.
At the following link ( https://mariadb.com/kb/en/mariadb/grant/#per-account-ssltls-options ), the part to set up authentication on the account uses REQUIRE ISSUER and REQUIRE SUBJECT. These take in string representations of part of the SSL Certificates.
My question is, how is the client certificate, which will be provided on connection by the slave server, verified by the master? I cannot see in config where the master server is provided with a client certificate chain that the slave's certificate is issued off. Have I missed where the master is loaded with CA/chain certificates or even just the client certificate?
If it does not, the replication does not seem to be using any of the crypographic properties of the certificate. Just string matching on the certificate subject/issuer.