如何通过 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?
使用 MySQL Workbench 安全组通过 EC2 实例连接到 Amazon RDS 实例