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 ISSUER
、REQUIRE SUBJECT
和 REQUIRE X509
要求客户端提供客户端证书以与所需值进行比较(在这种情况下,您需要在客户端使用 ssl-key
和 ssl-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 连接的主要内容,如果未能解决你的问题,请参考以下文章