node-mysql2 icon indicating copy to clipboard operation
node-mysql2 copied to clipboard

ERR_TLS_CERT_ALTNAME_INVALID error when using CNAME as host name for RDS connection

Open pawelusfr opened this issue 2 years ago • 7 comments

We have a CNAME set in Route53 for our RDS cluster. When using that CNAME as host for MySQL connection we are getting ERR_TLS_CERT_ALTNAME_INVALID error (Hostname/IP does not match certificate's altnames).

SSL option in configuration is set to ssl: 'Amazon RDS'.

This is because the certificate from RDS doesn't have the CNAME listed as altname and AFAIK there is no way to do that in RDS.

This was working fine in mysql2 3.5.0 and broke in 3.5.1 with #2119 and the switch to Tls.connect.

pawelusfr avatar Aug 14 '23 10:08 pawelusfr

Are you able to connect if you set rejectUnauthorized to false?

Is the error coming from https://github.com/sidorares/node-mysql2/blob/48c2b8de9010ac18954c2c39ade410ba45dfa29d/lib/connection.js#L375-L377 or from https://github.com/sidorares/node-mysql2/blob/48c2b8de9010ac18954c2c39ade410ba45dfa29d/lib/connection.js#L385 ?

sidorares avatar Aug 15 '23 15:08 sidorares

Maybe we need to add SNICallback to handle your scenario

sidorares avatar Aug 15 '23 15:08 sidorares

Yes I can connect with rejectUnauthorized: false.

The error is coming from https://github.com/sidorares/node-mysql2/blob/48c2b8de9010ac18954c2c39ade410ba45dfa29d/lib/connection.js#L385

One possible workaround would be allowing to pass custom checkServerIdentity function to Tls.connect() (I did a quick check and it will connect if that custom function allows it). This way clients could write their own identity handling for such cases (I believe that's what e.g. pg allows for Postgres). Though it couldn't be used in conjunction with ssl: 'Amazon RDS' as one would have to pass an object to ssl. That means the client would need a string version of the Amazon certs. Maybe you could add an export of it from mysql2 for such cases?

pawelusfr avatar Aug 16 '23 06:08 pawelusfr

I'm actually thinking to deprecate "Amazon RDS" and move it to a separate package, something along the line

import amazonRdsSslProfile from "amozon-rds-certs";  // package name TBD


const conn = mysql.createConnection({
   ssl: {
      ...amazonRdsSslProfile,
      checkServerIdentity: () => null,
   }
}

Maybe you could add an export of it from mysql2 for such cases? I'd rather go with separate package, not worth exporting if there is a plan to deprecate built in buntle

What needs to be done:

  • publish a "rds profile only" package ( with updated certs from https://github.com/sidorares/node-mysql2/pull/2131
  • use a "rds profile only" package as a dependency
  • add a warning when "Amazon RDS" string is passed as ssl parameter, with instructions on how to switch to external package ( minor version )
  • remove "rds profile only" package dependency, throw an error when "Amazon RDS" string is passed as ssl parameter, with instructions on how to switch to external package ( major version )

sidorares avatar Aug 16 '23 15:08 sidorares

@dougwilson wdyt about above, with profile repo under mysqljs org, and mysqjs/mysql referencing it in a similar way ( with similar deprecation steps )

sidorares avatar Aug 16 '23 15:08 sidorares

Hi @sidorares that ia a good idea! Sorry I was away, but I am just getting back now and replying to issues 😅. I'll actually set it up here this weekend. I figure it just is an export of the list in the same format Node.js accepts, of course.

dougwilson avatar Sep 15 '23 13:09 dougwilson