与数据库的PDO连接失败,无法进行证书转换

时间:2019-05-03 13:01:13

标签: php ubuntu ssl pdo

我一直在Ubuntu 18.04 LTS上运行mysql数据库。 除非我按照以下教程尝试实现SSL,否则一切正常。 https://www.digitalocean.com/community/tutorials/how-to-configure-ssl-tls-for-mysql-on-ubuntu-16-04 https://www.acunetix.com/blog/articles/securing-mysql-server-ubuntu-16-04-lts-configuring-mysql-securely-part-3/

连接失败。我尝试使用PDO和普通的MYSQLI连接来实现它,但是它在证书验证方面一直失败。

我正在使用mysqlnd transporter运行PHP 7.1.8。

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>SSL Connection test</title>
  </head>
  <body>
    <?php
    phpinfo();
    $servername = "****";
    $username = "****";
    $password = "****";
    $dbname = "****";

    $options = array(
      PDO::MYSQL_ATTR_SSL_KEY => 'client-key.pem',
      PDO::MYSQL_ATTR_SSL_CERT => 'client-cert.pem',
        PDO::MYSQL_ATTR_SSL_CA => 'ca.pem',
        PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => true,
    );

    try {
        $conn = new PDO("mysql:host=$servername;port=3306;dbname=$dbname;", $username, $password, $options);
        // set the PDO error mode to exception
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        echo "Connected successfully";
            var_dump($conn->query("SHOW STATUS LIKE 'Ssl_cipher';")->fetchAll());
    }
    catch(PDOException $e)
        {
        echo "Connection failed: " . $e->getMessage();
    }

    ?>
  </body>
</html>

这是我目前用于测试功能的代码。 每当我将PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT设置为假时,连接就会成功。如果PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT为真,则连接失败。

关于失败的错误消息:

  

连接失败:SQLSTATE [HY000] [2002]

关于连接的消息:

  

已成功连接array(1){[0] => array(4){[“”变量名“] =>字符串(10)” Ssl_cipher“ [0] =>字符串(10)” Ssl_cipher“ [”值“] =>字符串(18)“ DHE-RSA-AES256-SHA” [1] =>字符串(18)“ DHE-RSA-AES256-SHA”}}

已通过以下代码检查证书:

openssl verify -CAfile ca.pem server-cert.pem client-cert.pem

这两个文件都返回OK。

在过去的几个小时里,我一直在尝试解决此问题,但似乎无法找出问题所在。

请帮助我解决此问题。

编辑:所有文件(client-key.pemclient-cert.pemca.pem)均已通过is_readable进行了测试,并且可读。

1 个答案:

答案 0 :(得分:0)

您可能知道,在Windows Server IIS PHP配置中,您需要设置openssl.cafile指令,并提供证书颁发机构(CA)文件的路径。在使用系统默认值的Linux上,这不是必需的。 MYSQL_ATTR_SSL_CA在Windows上需要此路径,在Linux上可以省略。

要将此逻辑添加到PDO测试脚本中,请在OS信息中添加一个额外的变量,并更改MYSQL_ATTR_SSL_CA行:

$OS = ( strtoupper( substr( PHP_OS, 0, 3 ) ) === 'WIN' );
PDO::MYSQL_ATTR_SSL_CA => $OS ? 'c:/path/to/cacert.pem' : '',

您的$ options数组变为:

$OS = ( strtoupper( substr( PHP_OS, 0, 3 ) ) === 'WIN' );

$options = array(
    PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
    PDO::MYSQL_ATTR_SSL_CA => $OS ? 'c:/path/to/cacert.pem' : '',
    PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,
);

f $OS === true (e.g $OS === 'WIN')使用c:/path/to/cacert.pem作为PDO :: MYSQL_ATTR_SSL_CA文件路径,否则我们在Linux上并忽略该路径。这样,您可以确定可以在Windows Server和Linux上都使用此PHP代码跨平台!

通过WordPress保护MySQL连接

在WordPress中,您可以使用“安全数据库连接”插件来设置和配置与MySQL数据库的SSL连接。不要忘记在数据库权限中设置REQUIRE SSL。