PHP到MySQL的SSL连接

时间:2010-09-07 10:25:20

标签: php mysql ssl mysqli

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

警告:mysqli_real_connect():( HY000 / 2026):第18行/var/www/html/test.php中的SSL连接错误

我的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();

?>

3 个答案:

答案 0 :(得分:7)

这里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 null,除非您想使用真正应该与您的服务器证书不同的客户端证书。 (我不记得这是否有效。)
  • 可能更容易,完全省略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要求客户端提供客户端证书以与所需值进行比较(在您需要使用{{1}的情况下}和ssl-key在客户端(配置或在ssl-cert内)。

答案 1 :(得分:0)

也许你的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";

打印?

答案 2 :(得分:0)

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

  

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

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/