与 RDS MySQL/Aurora 无服务器集群的 SSL 连接因 Node.js 失败

Posted

技术标签:

【中文标题】与 RDS MySQL/Aurora 无服务器集群的 SSL 连接因 Node.js 失败【英文标题】:SSL connections to RDS MySQL/Aurora serverless cluster fail with Node.js 【发布时间】:2019-03-09 03:59:08 【问题描述】:

一段时间以来,我一直在使用 Node.js LTS 和 RDS mysql 数据库。我最近启动了一个 RDS 无服务器 Aurora MySQL 5.6 集群。与我的其他 RDS 数据库不同,我无法让 Node.js 使用 Node mysql 或 mysql2 适配器通过 SSL 连接到新的无服务器集群。

从带有单个 Node.js 应用程序的单个 Ubuntu 实例:

我可以使用 SSL 成功地将 Node 应用程序连接到我的任何旧 RDS 数据库 (MySQL 5.6.40):

// 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);

在同一台机器上,我可以毫无问题地使用 MySQL 客户端通过 SSL 连接到新的 RDS 集群:

// 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

我可以成功地将 Node 应用连接到新的无服务器集群没有 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);

但是当我尝试使用 SSL 证书连接到新的无服务器集群时,我收到服务器不支持安全连接的错误:

// 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)

那么有什么不同呢?旧 RDS 数据库和新无服务器集群之间唯一明显的区别是旧实例是 MySQL 5.6.40,新 RDS 集群是 Aurora MySQL 5.6.10a。此外,旧 RDS 实例主机名解析为单个私有 IP,而新集群主机名解析为多个私有 IP。

我使用 mysql 适配器得到了相同的结果。我还尝试了 mysql 适配器中的“Amazon RDS”SSL 配置文件并获得了相同的结果。

我无法使用 IAM 数据库身份验证,因为此服务需要每秒处理超过 20 个新连接。

任何建议将不胜感激。

【问题讨论】:

当您说“我可以使用 MySQL 客户端通过 SSL 连接到新的 RDS 集群” - 来自 cli 客户端的 status 命令的结果是什么? (或者可能是SHOW STATUS LIKE 'Ssl_cipher'; 查询)?只是想仔细检查一下命令行客户端实际上是安全连接的,而不是默默地将你降级为纯文本连接,因为它是唯一可用的选项 当服务器功能不包含“安全连接”标志且客户端配置需要 ssl 时,返回“服务器不支持安全连接”错误。您可以尝试使用debug: true 标志启动您的客户端并从日志中发布一些相关行吗? (特别是服务器标志) 安德烈——你是对的。 MySQL 客户端连接正在悄悄降级为纯文本。当我设置--ssl-mode=REQUIRED 时,我会返回ERROR 2026 (HY000): SSL connection error: Server doesn't support SSL 【参考方案1】:

我可以确认,RDS Aurora MySQL(无服务器)最终支持与集群的 SSL/TLS 连接。但是,需要一个兼容 MySQL 8.0 的客户端(即使底层数据库只有 MySQL 5.6.10a,集群代理也需要一个 8.0 客户端来支持 SSL)。

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

(来自页面:)

ERROR 2026 (HY000):SSL 连接错误:SSL_CTX_set_default_verify_paths 失败或 ERROR 2026 (HY000): SSL 连接错误: ASN: bad other signature Confirmation

如果证书标识符(证书文件名)不是 正确的。如果证书标识符不受支持,您也会收到此错误 通过 MySQL 客户端,例如使用 Aurora Serverless。如果您使用 Aurora Serverless 集群并且您使用 MySQL 客户端连接到 Aurora Serverless,那么您必须 使用与 MySQL 8.0 兼容的 MySQL 命令。

【讨论】:

【参考方案2】:

自 2018 年 10 月起,Aurora Serverless 不支持 SSL。 [1]。在您的实验中,您的连接大多被降级为不安全的连接。您应该能够查询状态表来确认这一点。

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

Aurora Serverless 不支持以下功能:

从 Amazon S3 存储桶加载数据

使用 Aurora MySQL 本机函数调用 AWS Lambda 函数

高级审计

极光复制品

回溯

数据库克隆

IAM 数据库身份验证

跨区域只读副本

从 MySQL 数据库实例恢复快照

从 Amazon S3 迁移备份文件

使用安全套接字层 (SSL) 连接到数据库集群

【讨论】:

感谢您指出这一点。不幸的是,情况就是这样。我将热切地等待 SSL 支持。

以上是关于与 RDS MySQL/Aurora 无服务器集群的 SSL 连接因 Node.js 失败的主要内容,如果未能解决你的问题,请参考以下文章

在无服务器框架中创建可用于 Lambda 函数的 RDS 实例

通过 CloudFormation 堆栈部署初始化和填充无服务器 PostgreSQL RDS 实例的最佳实践

京东云数据库RDS SQL Server高可用概述

K8S服务暴露: HAProxy在RDS场景下的妙用

GCP 上的 Terraform:如何将我的集群节点列入 RDS 白名单

Terraform 在升级时会破坏 RDS 集群内的实例