mysqli_real_connect()获取SSL3_GET_SERVER_CERTIFICATE:证书验证失败


mysqli_real_connect() getting SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

我们刚刚从php 5.4升级到php5.6,使用MySQLi和SSL连接的MySQL一切正常。

我们的连接看起来像:

mysqli_real_connect($db, $host, $username, $password, $database, $port, $socket, MYSQLI_CLIENT_SSL);
mysqli_set_charset($db, "utf8");

然而,现在,当我们尝试使用php5.6通过SSL连接MySQL时,我们得到的是:

警告:mysqli_real_connect():SSL操作失败,代码为1。OpenSSL错误消息:错误:14090086:SSL例程:SSL3_GET_SERVER_CERTIFICATE:中的证书验证失败/第29行的MySQLConnection.php

警告:mysqli_real_connect():无法使用SSL连接到MySQLin/MySQLConnection.php中的第29行

警告:mysqli_real_connect():[2002](尝试通过连接tcp://mysql1.ourdomain.com:3306)in/MySQLConnection.php中的第29行

警告:mysqli_real_connect():(HY000/2002):在/MySQLConnection.php中在线29

我尝试设置:

mysqli_options($db, MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, false);

但这无济于事。

更新

我补充道:

$mysql_certs_path = "/full/path/to/certs/mysql";
mysqli_ssl_set($db, $mysql_certs_path . "/client-key.pem", $mysql_certs_path . "/client-cert.pem", $mysql_certs_path . "/ca-cert.pem", null, null);

并且仍然得到:

警告:mysqli_real_connect():SSL操作失败,代码为1。OpenSSL错误消息:错误:14090086:SSL例程:SSL3_GET_SERVER_CERTIFICATE:中的证书验证失败/第31行的MySQLConnection.php

Warning: mysqli_real_connect(): Cannot connect to MySQL by using SSL in /MySQLConnection.php on line 31

@jww,我写了一篇文章,分享了@Justin在这里面临的问题。根据我的帖子,Google Cloud SQL颁发的证书的CN具有以下模式:

CN=project-name:instance-id

我也遇到过类似的事情。当我将PHP升级到5.6时,它成功了。但当我进入:

sudo apt-get install php5-mysqlnd

在Ubuntu 15.04上,SSL到AWS RDS停止工作,尽管它与libmysql驱动程序一起工作。运行:

sudo apt-get install php5-mysql

安装了旧的驱动程序,它又开始工作了。据我所知,它没有通过连接RDS的对等名称验证。我不知道如何解决这个问题,因为它使用PHP流进行连接,所以你传入的设置似乎无关紧要

这是一个已知的错误:

https://bugs.php.net/bug.php?id=68344

所以我写了这个方法,从这里修改:如何知道MySQLnd是否是活动驱动程序?

public function getMySQLIType()
{
    $mysqlType = [
        'mysql' => false,
        'mysqli' => false,
        'mysqlnd' => false,
    ];
    if (function_exists('mysql_connect')) {
        $mysqlType['mysql'] = true;
    }
    if (function_exists('mysqli_connect')) {
        $mysqlType['mysqli'] = true;
    }
    if (function_exists('mysqli_get_client_stats')) {
        $mysqlType['mysqlnd'] = true;
    }
    return $mysqlType;
}

如果mysqlnd的数组返回true,则禁用SSL。如果返回false,那么我启用它。到目前为止,它是有效的。是的,这是一个黑客修复,但我不知道如何合法地修复这个问题。