Node-mysql2: SSL support does not work with Node v12+

Created on 16 Dec 2019  路  14Comments  路  Source: sidorares/node-mysql2

When using Node v12+ you will always get an error when trying to connect with SSL.

SSL routines:ssl_choose_client_version:unsupported protocol

The minimum TLS version in node 12 is 1.2, and this module needs to add support for this.

Most helpful comment

While above error might be probably solved with added entry to exports, I would prefer to change all deep requires to top level import + property or getters
Some things to consider while doing this:

  • avoid impact on startup time and memory ( getters and lazy require vs requiring everything upfront )
  • need to think about good and consistent names. possible future examples:
import mysql from 'mysql2'

mysql.constants.commandCodes.COM_QUIT; // instead of require('mysql2/lib/constants/commands.js')
mysql.sslProfiles['Amazon RDS']; //  instead of require('mysql2/lib/constants/ssl_profiles')
mysql.constants.capabilityFlags.SSL_VERIFY_SERVER_CERT; // instead of require('mysql2/lib/constants/client.js')

All 14 comments

I am able to get this working using a connection object similar to this:

const connConfig = {
  user: 'username',
  password: 'password',
  host: 'hostname',
  ssl: {
    rejectUnauthorized: false,
    minVersion: 'TLSv1'
  }
}

However, this isn't ideal. I think it's worth making an effort to make this work properly.

does it fail with minVersion: 'TLSv1' but rejectUnauthorized unset?

related: #961 #960

Yes it does fail, btw this is using Amazon RDS. Came up with another solution that pulls the ca bundle from lib/constants/ssl_profiles.js

Came up with another solution

this one? https://github.com/sidorares/node-mysql2/issues/960#issuecomment-562342922

@stephen-dahl did that work for you without setting rejectUnauthorized to false?

Came up with another solution

this one? #960 (comment)

@stephen-dahl did that work for you without setting rejectUnauthorized to false?

Yes that's what we ended up doing. It's pretty hacky though. I can look into making it work properly with TLS 1.3 in node 12 if you don't have a plan to get this resolved

I don't have a plan yet. Do you think RDS bundled configs need to be updated to include minVersion: 'TLSv1'?

I don't think it can be the default because it is only a problem with mysql < 5.6.46 and aurora mysql 5.6. Newer versions of mysql and aurora support the newer ssl versions. We don't want to make newer versions insecure to make older versions a little easier.

We could add a new profile Amazon RDS TLSv1
or, change it so that you can also set a profile value like this

ssl: {
  profile: 'Amazon RDS'
  ...otherconfigs
}

Seems like a good idea, I think just adding some documentation on this for supporting older MySQL versions in newer node versions would suffice, and improving how to load the Amazon RDS cert.

Keep in mind this is only an issue on Node 12+, works fine as documented in the module on node 10 and below

I got this to work like so:

import * as sslProfiles from 'mysql2/lib/constants/ssl_profiles';

ssl: {
  ...sslProfiles['Amazon RDS'],
  minVersion: 'TLSv1',
}

I doubt the author meant for that module to be imported that way, but this seems a good deal better than setting rejectUnauthorized to false.

eta: I see the same advice is given at one of the links above. Want to make this just part of the docs?

I got this to work like so:

import * as sslProfiles from 'mysql2/lib/constants/ssl_profiles';

ssl: {
  ...sslProfiles['Amazon RDS'],
  minVersion: 'TLSv1',
}

I doubt the author meant for that module to be imported that way, but this seems a good deal better than setting rejectUnauthorized to false.

eta: I see the same advice is given at one of the links above. Want to make this just part of the docs?

This workaround no longer works since the exports section was added to the package.json file here

Getting this error now when importing the ssl_profiles file:

Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './lib/constants/ssl_profiles' is not defined by "exports"

Edit: Worth noting that this is happening when using commonjs const sslProfiles = require('mysql2/lib/constants/ssl_profiles');

While above error might be probably solved with added entry to exports, I would prefer to change all deep requires to top level import + property or getters
Some things to consider while doing this:

  • avoid impact on startup time and memory ( getters and lazy require vs requiring everything upfront )
  • need to think about good and consistent names. possible future examples:
import mysql from 'mysql2'

mysql.constants.commandCodes.COM_QUIT; // instead of require('mysql2/lib/constants/commands.js')
mysql.sslProfiles['Amazon RDS']; //  instead of require('mysql2/lib/constants/ssl_profiles')
mysql.constants.capabilityFlags.SSL_VERIFY_SERVER_CERT; // instead of require('mysql2/lib/constants/client.js')

Any idea when this issue will be addressed?

Was this page helpful?
0 / 5 - 0 ratings