Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SSL tunnel connection mode #44

Closed
elefeint opened this issue Sep 27, 2022 · 2 comments · Fixed by #48
Closed

Add SSL tunnel connection mode #44

elefeint opened this issue Sep 27, 2022 · 2 comments · Fixed by #48

Comments

@elefeint
Copy link

Google Cloud SQL uses a pre-existing SSL tunnel to connect to MySQL. In the past, Spring Cloud GCP and Google Cloud Socket Factory relied on the 3rd party MySQL driver, but with Spring Boot 2.7 recommending to use the MariaDB driver, we started looking into the integration (GoogleCloudPlatform/cloud-sql-jdbc-socket-factory#990).

Because of the need to use a pre-existing SSL tunnel, some changes are needed in this driver:

  1. The socket factory uses a callback to modify SslContextBuilder, injecting the correct key/trust managers on demand, based on an ephemeral certificate retrieved from the backend. MariadbConnectionConfiguration needs to accept this as an option, and SslConfig needs to call the customizer to get the correct SSL configuration.
  2. The existing SSL modes support either "no SSL" or "establish SSL and use it" modes. Tunneling requires a hybrid -- SSL is used, but not established in the driver. This neccesitates introduction of a new SslMode.
  3. I could not figure out a good way to build SSL context injection into the AuthenticationFlow because the initial server-side handshake needs to be received over an already-established SSL tunnel, and not in plain-text. I added the SSL context establishment into SimpleClient constructor, but that seems inelegant. I'd love advice for a better place to add this logic.
  4. Ideally, certificate and hostname verification should be done in tunneling mode based on the information received from the callback in (1). I haven't done that in the proof-of-concept; advice would be very welcome.

Would this be an acceptable approach? I have a working proof of concept that I could turn into a pull request.

FYI @mp911de.

@mp911de
Copy link

mp911de commented Sep 28, 2022

Generally, the approach of post-processing SslContextBuilder is a neat way to introduce SSL customization or SSL tunneling features without diving too much into the driver internals.

@rusher
Copy link
Collaborator

rusher commented Nov 22, 2022

It seems a good PR to have.

About the proof of concept, that would be a good base for a PR.

Some remarks :

  • TUNNEL("tunnel", new String[0]); => TUNNEL("tunnel", new String[]{"TUNNEL}); would permit to use connection string with "sslMode=TUNNEL", not only "sslMode=tunnel" since other SSL configuration permit lower AND uppercase.
  • About the SSL tunnelling part in SimpleClient constructor, it might be better to have a dedicated method registerSslTunnelIfNeededor something like that before the constructor call, like there
  • in order to have tunnel verification: host must be provided when creating an SslContext newEngine, and in order to force name verification, setEndpointIdentificationAlgorithm must not be null. So here is a quick example:
      SslContext sslContext = configuration.getSslConfig().getSslContext();
      SSLEngine engine;
      if (this.hostAddress == null) {
        engine = sslContext.newEngine(connection.channel().alloc(), this.hostAddress.getHost(), this.hostAddress.getPort());
        SSLParameters sslParameters = engine.getSSLParameters();
        sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
        engine.setSSLParameters(sslParameters);
      } else {
        engine = sslContext.newEngine(connection.channel().alloc());
      }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants