如何通过 SSL 连接到 Amazon RDS?

Posted

技术标签:

【中文标题】如何通过 SSL 连接到 Amazon RDS?【英文标题】:How to connect to Amazon RDS via SSL? 【发布时间】:2015-10-27 17:20:30 【问题描述】:

我正在尝试建立与通过 Amazon RDS 托管的 mysql 数据库的 SSL 连接。我对如何连接感到困惑。

根据亚马逊的documentation,我需要下载一个名为“rds-ca-2015-root.pem”的 CA 证书并在我的 SSL 连接中使用它。 我将要连接的数据库用户设置为需要 SSL。

php 中,我包含以下代码来启动连接:

$mysqli = mysqli_init();
mysqli_options($mysqli, MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, true);
$mysqli->ssl_set(NULL, NULL, "/path/to/pem", NULL, NULL);
$mysqli->real_connect("host", "username", "password", "name", 3306, NULL, MYSQLI_CLIENT_SSL);

但是,无论我在 ssl_set() 中将哪个路径指定为第三个参数(即使路径无效),都成功建立了 SSL 连接。第三个参数不能设置为NULL。

我通过运行以下查询来验证这一点:SHOW STATUS LIKE 'Ssl_cipher';。输出验证连接是否已加密 (Ssl_cipher => AES256-SHA)。

有人可以向我解释一下这是如何工作的吗?我对为什么当路径不正确时连接继续成功工作感到困惑。如何验证 RDS 服务器?

【问题讨论】:

如果你在 Unix 机器上运行它,这取决于你使用的 OpenSSL 的风格和配置,有一个目录保存你的系统范围的证书。 Openssl 将在该路径中查找适当的证书。这里不清楚的是(假设您在 unix 机器上)您是否已将证书放在该目录中。如果您已成功连接,则必须拥有。您可以在此处获取有关特定目录位置的更多信息:serverfault.com/questions/62496/… 我在这里(来自 EC2)实例进行了相当多的测试,看起来甚至不需要设置 PEM 公钥路径的行,也不需要包含AWS 文档中的 PEM,用于通过命令行进行连接。这意味着@mba12 是正确的,因为 RDS 证书必须已经存在于实例中的某个位置,并且不需要被引用。如果我不正确地引用它们,那么是的,它会中断。您是否从 AWS VPC 外部对此进行测试? @RobbieAverill 自从我经常使用 AWS 以来已经有一年左右的时间了,但是当我这样做时,我总是使用 PEM 文件并指定路径。我从未尝试将 PEM 文件集成到专门用于 AWS 的 openssl 中。但是对于其他将证书放入 OpenSSL 默认目录的通用 linux 机器来说效果很好。你只需要小心让你的特定盒子的 openssl 配置正确。那是唯一让我有点问题的东西。正如我提到的,openssl 有几种口味。 @Jack Humphries,你现在有很多后续/后续问题。如果你能回答他们会很好,这样我们就可以尝试回答你的问题。 您将 .pem 文件上传到服务器的哪个位置? 【参考方案1】:

RDS 文档实际上解释了为什么会发生这种情况,并建议您甚至不需要 CA 证书:

Amazon RDS 开始更新所有数据库实例上的 SSL 证书 2015 年 3 月 23 日,但未启动实例重启。不 更新这些更新时会产生运营影响或停机时间 执行,并且在许多情况下,我们将在您的 维护窗口。 Amazon RDS 不会更新证书 如果您已经执行了更新,您的实例。另请注意 Amazon RDS 未更新 AWS GovCloud(美国)中的证书 和中国(北京)地区。

无论您是手动更新证书还是亚马逊 RDS 更新了证书,必须重启数据库实例 新证书生效。您可以决定何时 手动重启数据库实例,但您必须更新证书 并在旧证书之前重启实例 (rds-ca-2010) 将于 2015 年 4 月 3 日到期。

您可以检查您的数据库正在使用的证书颁发机构 (CA) 使用 Amazon RDS 控制台的实例。 CA 列在 数据库实例详细信息的安全和网络部分。如果你的 实例显示rds-ca-2015,则新证书已 成功申请。您仍然需要重新启动数据库实例 并更新您的客户端应用程序以使用新的 SSL 证书。

如果 Amazon RDS 控制台将您的实例 CA 显示为 rds-ca-2010,则 新证书尚未应用于您的数据库实例 然而。使用以下说明更新 SSL 证书 您的数据库实例。

第三个参数基本上被客户端忽略了。我打赌将第三个参数设置为NULL,如果所有参数都为空,则调用mysqli::ssl_set() 是没有意义的。

尝试完全删除该函数调用。

【讨论】:

您从 RDS 文档中引用的引用是指 服务器,这绝不是说明为什么他的 php 代码在 EC2 实例上作为客户端运行,成功连接到服务器尽管他打了ssl_set 电话。 OP 问题是关于正在连接的 client,而不是关于 RDS。【参考方案2】:

据我所知 - 如果您要求或要求与 RDS MySQL 建立 SSL 连接,您将获得一个 - 无论证书的本地副本是否有效或可读。

我在 Drupal 中使用以下配置,无论我在证书路径中的何处或放置什么,我都会获得 SSL 连接:

$databases['default']['default'] = [
  'database' => 'drupal_db',
  'username' => 'db_user',
  'password' => 'db_password',
  'host' => 'hostname',
  'port' => '3306',
  'driver' => 'mysql',
  'prefix' => '',
  'pdo' => array(
      PDO::MYSQL_ATTR_SSL_CA => '/etc/ssl/certs/rds-combined-ca-bundle.pem',
      PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,
  ),  
];

但是,如果我将 MYSQL_ATTR_SSL_VERIFY_SERVER_CERT 值设置为“false”,则会收到连接错误并且 Drupal 失败。到目前为止,我还没有找到任何解释为什么这不会验证证书和/或如何使它成功验证!

【讨论】:

以上是关于如何通过 SSL 连接到 Amazon RDS?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 MySQL Workbench 连接到 Amazon RDS?

如何在 Spring Boot / Spring Data 中为 Amazon RDS Mysql 启用 SSL?

如何从本地使用 SSL 加密连接到 AWS RDS?

使用 MySQL Workbench 安全组通过 EC2 实例连接到 Amazon RDS 实例

使用 MySQL Workbench 通过 EC2 实例连接到 Amazon RDS 实例

如何使用 Multi-AZ 将 Node Sequelize 连接到 Amazon RDS MySQL