PHP 到 MySQL SSL 连接

Posted

技术标签:

【中文标题】PHP 到 MySQL SSL 连接【英文标题】:PHP to MySQL SSL Connections 【发布时间】:2010-09-07 10:25:20 【问题描述】:

我已经在一个网络上的一台服务器上成功设置了启用 SSL 的 mysql 安装,并且可以使用 SSL 和 Linux 命令行 mysql 客户端在不同网络上的不同服务器上连接到它,但是每次我尝试连接时(使用 php 5.3.3)我不断得到:

警告:mysqli_real_connect(): (HY000/2026): SSL connection error in /var/www/html/test.php on line 18

我的PHP如下我做错了吗?证书为 777(仅在测试时),相同的代码适用于不同用户的未加密连接(已注释掉 SSL 设置,即mysqli 绝对可以普遍连接到数据库)

<?php

error_reporting(E_ALL);
ini_set("display_errors", "1");

$obj = mysqli_init();

mysqli_options($obj, MYSQLI_OPT_CONNECT_TIMEOUT, 5);

mysqli_ssl_set($obj,
               '/mysql-ssl-certs/server-key.pem',
               '/mysql-ssl-certs/server-cert.pem',
               '/mysql-ssl-certs/ca-cert.pem',
               NULL,
               NULL);

$link = mysqli_real_connect($obj, 'localhost', 'ssluser', 'some_password', 'test');

if (!$link)

    die('<br /><br />Connect Error (' . mysqli_connect_errno() . ') '.mysqli_connect_error());


echo 'Success... ' . mysqli_get_host_info($obj) . "\n";

$obj->close();

?>

【问题讨论】:

注意:这表示 localhost,因为我现在也在本地机器上尝试它,所以我 100% 确定这不是防火墙问题 - 我在那里遇到同样的错误...... 不 - 我知道它们在一个奇怪的位置,但 / 中有一个有效的文件夹,它被 chmodded 为 777 以进行测试 MySQL 服务器的错误日志中是否有相关内容?如果可能,使用 --log-warnings=2(或 3 或 99,大于 1)启动 MySQL 服务器,请参阅dev.mysql.com/doc/refman/5.0/en/communication-errors.html 顺便说一句:您使用哪个版本的 MySQL?也许有关您的系统的其他一些说明?例如。操作系统版本,这些证书是如何创建的……不知道这是否相关,但可能是…… 【参考方案1】:

这里 PHP(和mysqli_real_connect)是客户端而不是服务器。您正在使用 mysqli_ssl_set 对其进行配置以进行客户端证书身份验证(并使用服务器密钥和证书)。

我不确定您是如何配置 MySQL 服务器的,但配置的 (MySQL) 服务器部分应该有类似的内容:

ssl-key=/mysql-ssl-certs/server-key.pem
ssl-cert=/mysql-ssl-certs/server-cert.pem
ssl-ca=/mysql-ssl-certs/ca-cert.pem

这些无论如何都不属于客户端(只有 CA 证书,但绝对不是服务器的私钥)。

完成此操作后,您可以尝试使用命令行客户端查看服务器是否配置正确:

mysql --ssl-verify-server-cert --ssl-ca=/mysql-ssl-certs/ca-cert.pem --ssl -h hostname ...

或者这个(虽然验证服务器证书确实应该启用,以便 SSL/TLS 有用)

mysql --ssl-ca=/mysql-ssl-certs/ca-cert.pem --ssl -h hostname ...

这至少应该在命令行上工作。

然后,从 PHP 中,您有两个选择:

使用mysqli_ssl_set 就像你已经做的那样,但留下$key$cert 为空,除非你想使用一个真正应该与你的服务器证书不同的客户端证书。 (我不记得这是否有效。)

可能更简单,完全省略 mysqli_ssl_set 并在您的全局 MySQL 客户端配置文件中配置它(PHP 应该能够在其中提取它,可能是 /etc/mysql/my.cnf,但这可能因您的发行版而异):

[client]
ssl-ca=/mysql-ssl-certs/ca-cert.pem

(这类似于服务器配置,但在客户端/客户端部分。)

授权部分(GRANT):

REQUIRE SSL 只需要使用 SSL/TLS REQUIRE ISSUERREQUIRE SUBJECTREQUIRE X509 要求客户端提供客户端证书以与所需值进行比较(在这种情况下,您需要在客户端使用 ssl-keyssl-cert(配置或在mysqli_ssl_set 内)。

【讨论】:

(您还应该在客户端配置中启用ssl-verify-server-cert。) 我现在已经开始工作了 大部分已经如前所述进行了设置,但我喜欢 [client] 的想法 - 没有想到这一点。证书的生成是按照 mysql 手册页中的说明完成的,但奇怪的是,如果我只在 mysqli 连接中设置 ca 变量并将其设置为server-cert.pem 知道为什么吗?这是 [mysqld] ssl=1 ssl-ca=/mysql-ssl-certs/ca-cert.pem ssl-capath=/mysql-ssl-certs ssl-cert=/mysql-ssl-certs/server- 的 ssl 位cert.pem ssl-key=/mysql-ssl-certs/server-key.pem 感谢您的授权评论。我使用了 REQUIRE SSL:建立了 SSL 连接,但所有本地证书都被忽略了。设置 REQUIRE X509 后,至少需要客户端密钥和证书文件。 我遇到了这个确切的问题。我将 mysqli_ssl_set($db, null, null, '/path/to/ca-cert.pem', null, null) 设置为 ca-cert.pem,但得到 Warning: mysqli_real_connect(): Unable to locate peer certificate CN in /MySQLConnection.php on line 31 请注意,my.cnf 解决方案仅适用于 PHP php.net/manual/en/…【参考方案2】:

也许您的 php 版本使用 mysqlnd 作为不支持 ssl 的传输驱动程序(还没有?)。 是什么

<?php
error_reporting(E_ALL);
ini_set("display_errors", "1");
echo 'version: ', phpversion(), "\n";
echo function_exists('mysqli_fetch_all') ? 'mysqlnd' : '--', "\n";

打印?

【讨论】:

【参考方案3】:

如果您使用的是 5.7.3 之前的 MySQL 和标准 PHP 库,则应该小心:

在 MySQL 5.7.3 之前,--ssl 允许但不要求客户端 使用 SSL 连接到服务器。因此,该选项不 本身足以导致使用 SSL 连接。为了 例如,如果您为客户端程序指定此选项,但 服务器尚未配置为允许 SSL 连接, 使用未加密的连接。

http://dev.mysql.com/doc/refman/5.7/en/ssl-options.html#option_general_ssl

在 PHP 的情况下,如果服务器不支持 SSL,MySQL 将静默失败

https://www.idontplaydarts.com/2015/03/mysql-with-ssl-does-not-protect-against-active-mitm/

【讨论】:

以上是关于PHP 到 MySQL SSL 连接的主要内容,如果未能解决你的问题,请参考以下文章

mysql workbench ssl连接问题

PHP Web套接字未在SSL中连接

MySQL启用SSL连接

具有指定证书的 Java MySQL SSL 连接

谁用过SSL连接mysql,2026错误怎么解决

mysql 加密连接SSL