无法使用ssl与PDO连接,但使用mysqli与ssl连接

时间:2014-04-28 13:35:06

标签: php mysql ssl pdo mysqli

我们通过创建证书,更新my.cnf,创建具有正确权限的用户并需要ssl,重新启动服务,并通过连接验证它在服务器端和客户端(通过mysql命令行)工作,使用SSL设置mysql远程。我还验证了PDO使用完全相同的设置正常工作,但在mysql中禁用了用户帐户上的“require ssl”,因为它只是静默失败并使用非ssl连接。

然而,当使用PHP应用程序连接它时,使用PDO强制ssl无法正常工作,但使用强制ssl的mysqli工作。我以为他们使用相同的驱动程序,两者都应该正常工作。我收到的错误消息是“连接到数据库失败[SQLSTATE [28000] [1045]用户拒绝访问”,但用户存在且此连接与mysqli(强制ssl)一起使用,并且仅当我删除时,连接才适用于PDO在mysql中需要来自用户的ssl'。

php 5.5.9 CentOS 6.5版(最终版) pdo_mysql 5.5.31

如果我能提供任何其他信息,请告诉我。以下是连接示例

//mysqli
$conn=mysqli_init();
mysqli_ssl_set($conn, $clientkey, $clientcert, $sharedca, NULL, NULL);
if (!mysqli_real_connect($conn, $host, $user, $pass, $db))
{
    die("Failed connecting to ssl mysql via mysqli");
}

$res = mysqli_query($conn, "SHOW STATUS like 'Ssl_cipher'");
print_r(mysqli_fetch_row($res));
mysqli_close($conn);

//pdo
$options = array_merge($options, array(
PDO::MYSQL_ATTR_SSL_KEY           => $sslkey,
PDO::MYSQL_ATTR_SSL_CERT          => $sslcert,
PDO::MYSQL_ATTR_SSL_CA            => $sslca,
));

try
{
    $pdo = new PDO("mysql:dbname={$db};host={$host}", $user, $pass, $options);  
}
catch( PDOException $e )
{
  die("Failed connecting");
}

关于如何使用SSL与PDO正确连接,我应该知道些什么吗?或者我被迫切换到mysqli,因为PDO支持SSL可能会有问题吗?

感谢。

2 个答案:

答案 0 :(得分:0)

以下代码将解决您的问题,
 新的PDO('mysql:host ='。HOST。'; dbname ='。DBNAME。'; charset = utf8',USER,PASSWORD,                                     阵列(                                             PDO :: MYSQL_ATTR_SSL_KEY =>'/ mysqlsslcertificate1 / client-key.pem',                                             PDO :: MYSQL_ATTR_SSL_CERT => '/ mysqlsslcertificate1 /客户cert.pem',                                             PDO :: MYSQL_ATTR_SSL_CA =>'/ mysqlsslcertificate1 / ca-cert.pem'                                     )                                 );

答案 1 :(得分:0)

实际问题是服务器证书CN验证(不匹配),但报告的错误是PDOException: SQLSTATE[HY000] [2002]

在针对该问题记录的PHP中存在大量错误,例如:71845 71003Github PR

解决方案是这些PHP版本之后可用的未记录属性 5.6.22(不确定),7.0.18(已验证)和7.1.15(不确定)

PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT

可能的值:true,false 默认值:true

所以你的代码应该是

$pdo = new PDO('mysql:host=XXXXXX;dbname=XXXXXX', 'XXXXXX', 'XXXXXX', array(
    PDO::MYSQL_ATTR_SSL_KEY    =>'/path/to/client-key.pem',
    PDO::MYSQL_ATTR_SSL_CERT   =>'/path/to/client-cert.pem',
    PDO::MYSQL_ATTR_SSL_CA     =>'/path/to/server-ca.pem',
    PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false
)

);