4
votes

I've been using Node.js LTS with RDS MySQL databases for some time. I recently spun up a RDS serverless Aurora MySQL 5.6 cluster. Unlike my other RDS databases, I can't get Node.js to connect to the new serverless cluster with SSL using the Node mysql or mysql2 adapters.

From a single Ubuntu instance with a single Node.js app:

I can successfully connect the Node app to any of my older RDS databases (MySQL 5.6.40) using SSL:

// works with other RDS databases:
const fs = require('fs');
const mysql = require('mysql2');
const config = require('../config');

var connectionArgs = {
  host: config.old_rds_host,
  database: config.old_rds_database,
  user: config.old_rds_user,
  password: config.old_rds_password,
  port: config.rds.port,
  ssl: {
    ca: fs.readFileSync(__dirname + '/../rds-combined-ca-bundle.pem')
  }
}

var connection = mysql.createConnection(connectionArgs);

From the same machine, I can connect with SSL to the new RDS cluster using the MySQL client without issues:

// Works with new RDS serverless cluster:
mysql -u rds_serverless_user -p -h new-rds-serverless-cluster.us-west-2.rds.amazonaws.com -P 3306 --ssl --ssl-ca=./rds-combined-ca-bundle.pem

I can successfully connect the Node app to the new serverless cluster without SSL:

// Works with new RDS serverless cluster:
const fs = require('fs');
const mysql = require('mysql2');
const config = require('../config');

var connectionArgs = {
  host: config.rds_host,
  database: config.rds_serverless_database,
  user: config.rds_serverless_user,
  password: config.rds_serverless_password,
  port: config.rds.port
}

var connection = mysql.createConnection(connectionArgs);

But when I try to connect to the new serverless cluster with the SSL cert, I get an error that the server does not support a secure connection:

// Fails with new RDS serverless cluster:
const fs = require('fs');
const mysql = require('mysql2');
const config = require('../config');

var connectionArgs = {
  host: config.rds_host,
  database: config.rds_serverless_database,
  user: config.rds_serverless_user,
  password: config.rds_serverless_password,
  port: config.rds.port,
  ssl: {
    ca: fs.readFileSync(__dirname + '/../rds-combined-ca-bundle.pem')
  }
}


var connection = mysql.createConnection(connectionArgs);

Debug: internal, implementation, error 
Error: Server does not support secure connnection
at ClientHandshake.handshakeInit (/home/deploy_user/my-node-rds-app/node_modules/mysql2/lib/commands/client_handshake.js:120:17)
at ClientHandshake.Command.execute (/home/deploy_user/my-node-rds-app/node_modules/mysql2/lib/commands/command.js:40:20)
at Connection.handlePacket (/home/deploy_user/my-node-rds-app/node_modules/mysql2/lib/connection.js:513:28)
at PacketParser.onPacket (/home/deploy_user/my-node-rds-app/node_modules/mysql2/lib/connection.js:81:16)
at PacketParser.executeStart (/home/deploy_user/my-node-rds-app/node_modules/mysql2/lib/packet_parser.js:76:14)
at Socket.<anonymous> (/home/deploy_user/my-node-rds-app/node_modules/mysql2/lib/connection.js:89:29)
at emitOne (events.js:116:13)
at Socket.emit (events.js:211:7)
at addChunk (_stream_readable.js:263:12)
at readableAddChunk (_stream_readable.js:250:11)
at Socket.Readable.push (_stream_readable.js:208:10)
at TCP.onread (net.js:601:20)

So what's different? The only obvious difference between the older RDS databases and the new serverless cluster is that the old instances are MySQL 5.6.40 and the new RDS cluster is Aurora MySQL 5.6.10a. Also the older RDS instance hostnames resolve to a single private IP while the new cluster hostname resolves to multiple private IPs.

I get the same results using the mysql adapter. I've also tried the "Amazon RDS" SSL profile in the mysql adapter and get the same results.

I cannot use the IAM database auth because this service will need to handle more than 20 new connections/second.

Any advice would be greatly appreciated.

2
When you say "I can connect with SSL to the new RDS cluster using the MySQL client " - what's result of status command from cli client? ( or maybe SHOW STATUS LIKE 'Ssl_cipher'; query )? Just trying to double check that command line client is actually connected securely and not silently downgraded you to plaintext connection as it's only available optionAndrey Sidorov
"Server does not support secure connnection" error is returned when server capabilities does not include 'secure connection' flag and client config requires ssl. Can you try to start your client with debug: true flag and post some relevant lines from logs? ( esp server flags )Andrey Sidorov
Andrey -- You're right. The MySQL client connection is getting silently downgraded to plaintext. When I set --ssl-mode=REQUIRED I get back ERROR 2026 (HY000): SSL connection error: Server doesn't support SSL.user2700992

2 Answers

2
votes

I can confirm that RDS Aurora MySQL (Serverless) does finally support SSL/TLS connections to the cluster. However, a MySQL 8.0-compatible client is required (even though the underlying DB is only MySQL 5.6.10a, the cluster proxy requires an 8.0 client for SSL support).

https://aws.amazon.com/premiumsupport/knowledge-center/rds-error-2026-ssl-connection/

(from the page: )

ERROR 2026 (HY000): SSL connection error: SSL_CTX_set_default_verify_paths failed or ERROR 2026 (HY000): SSL connection error: ASN: bad other signature confirmation

You can receive this error if the certificate identifier (certificate file name) isn't correct. You can also receive this error if the certificate identifier isn't supported by the MySQL client, for example with Aurora Serverless. If you use Aurora Serverless clusters and you use the MySQL client to connect to Aurora Serverless, then you must use the MySQL 8.0-compatible MySQL commands.

1
votes

As of October 2018, Aurora Serverless does not support SSL. [1]. Your connections are mostly getting downgraded to insecure connections in your experiment. You should be able query status tables to confirm this.

[1] https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/aurora-serverless.html

Aurora Serverless doesn't support the following features:

Loading data from an Amazon S3 bucket

Invoking an AWS Lambda function with an Aurora MySQL native function

Advanced auditing

Aurora Replicas

Backtrack

Database cloning

IAM database authentication

Cross-region read replicas

Restoring a snapshot from a MySQL DB instance

Migrating backup files from Amazon S3

Connecting to a DB cluster with Secure Socket Layer (SSL)