【问题标题】:PHP Mysql connection with SSL is not working PDO与 SSL 的 PHP Mysql 连接不起作用 PDO
【发布时间】:2017-12-18 20:13:43
【问题描述】:

Mysql 服务器正在运行 php5.3。新的网络服务器正在运行 php7.1(从 php5.3 迁移而来)。当我尝试使用 ssl 连接 Mysql 服务器时,它不起作用。

try {
$dbh = new PDO($dsn, $user, $password, array(PDO::MYSQL_ATTR_SSL_KEY  => '/etc/mysql/client-key.pem',
                                             PDO::MYSQL_ATTR_SSL_CERT => '/etc/mysql/client-cert.pem',
                                             PDO::MYSQL_ATTR_SSL_CA   => '/etc/mysql/ca-cert.pem')
              );
    echo "Connestion established";
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
}

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

PDO::__construct(): SSL 操作失败,代码为 1。OpenSSL 错误消息: 错误:1416F086:SSL 例程:tls_process_server_certificate:证书验证失败

但是,当我从连接中删除 SSL 块时,它工作正常。我不知道发生了什么事。可能是服务器和客户端的版本不匹配。因为我使用的是旧的公钥和私钥。

是不是因为mysql客户端和服务器版本不匹配?

PS:我只升级了webserver中的php7。

【问题讨论】:

  • php 的错误报告中的任何内容?并且在配置中安装和启用 SSL 后证书仍然有效吗?
  • @Fred-ii- php 没有任何内容,因为我正在使用 try-catch。我从未更改过证书。只需从旧网络服务器复制粘贴到新网络服务器即可。
  • @Fred-ii- :旧的网络服务器正在运行 apache2 和新的 nginx。 nginx在哪里开启mysql-ssl?
  • 对nginx不熟悉
  • @Fred-ii-:谢谢。你能再看看吗?我已经更准确地更新了错误消息。

标签: php mysql ssl php-7


【解决方案1】:

所以,经过搜索和阅读后,我认为问题是由于 SSL 处理已从 PHP 5.6 开始获得批准,并且默认情况下现在已启用对等验证。

虽然以下不是关于 mysql 而是关于 fsock,但我认为这篇文章回答了您的问题: https://stackoverflow.com/a/32366242/2459026

您可以禁用对等验证(这往往不是一个好主意)或修复您的根证书。 我认为最好通过禁用对等验证来进行测试,以确保这确实是您的问题。

(请注意,我在之前的答案旁边添加了第二个答案。这不是您问题的答案,但可能与其他人相关)

【讨论】:

  • 在连接数据库服务器之前添加了这个块。 stream_context_set_default([ 'ssl' => [ 'verify_peer_name' => false, 'verify_peer' => false ] ]); 仍然出现同样的错误。我错过了什么吗?
  • 你发给我的是这个错误的解决方案:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed 但在我的情况下错误是tls_process_server_certificate:certificate verify failed
  • 让我重新创建证书并在两台服务器中尝试。我会及时通知你的。
  • @vrijdenker 您不应该在同一个问题上创建多个答案。下次请写,编辑和修改一个答案。
【解决方案2】:

您说您“将 SSL 密钥从一台服务器复制到另一台服务器”。所以有新的服务器吗?新服务器有一个新的身份,所以远程服务器会因为 ID 不匹配而拒绝证书。

我认为您应该首先从“known_hosts”文件中删除远程服务器上的行。 然后在您的 Nginx 服务器上,您应该使用这些 SSH 密钥手动连接到远程服务器并建立一次连接,以便将新身份添加到 known_hosts。

之后我认为它应该可以工作。

即使上述方法不起作用,我认为最好通过手动连接到远程主机来调试此问题。当它工作时,您可以尝试设置 mysql 连接。

【讨论】:

  • 密钥对从MySQL 服务器生成。我只是在改变部分的客户端。其次,如果我用 php5.3 创建新的客户端-服务器,一切都会像以前一样工作。可能是它的 php 版本问题或 apache2 或 nginx 配置。您对此有何看法?
  • 嗯,不,无赖。对不起。
【解决方案3】:

您可以生成新的 SSL 证书并确保使用正确的“通用名称”:

CA: hostname 
Server: FQDN, e.g. hostname.example.com 
Client: somename

重要的部分是服务器证书,其中公用名必须与您要连接的主机相同,例如主机名.example.com。

【讨论】:

  • 如果有 2 个客户端连接到同一个服务器怎么办。服务器和 2 个客户端的通用名称应该是什么?
  • 当您生成证书时,系统会要求您提供几个参数,例如州 (S)、地区 (L)、通用名称 (CN)。所以 CN 应该是完全相同的地址,你从客户端连接。如果您的 MySQL 在 db.myhost.com 上运行,您应该使用 db.myhost.com 作为 CN 并从客户端 info.ssl.com/article.aspx?id=10048 连接到 db.myhost.com
【解决方案4】:

您需要生成新的 SSL 证书并在服务器上测试端点以确保其正常工作。之后你应该没有问题。我推荐使用Let's Encrypt:它是免费的、开放的并且受到高度支持。确保您遵循说明here 后记。

【讨论】:

    【解决方案5】:

    通过一些试验和错误,我能够在不禁用对等验证的情况下解决此问题,部分归功于 MySQL 文档:

    重要

    无论您使用什么方法来生成证书和密钥 文件,用于服务器和客户端的 Common Name 值 证书/密钥必须分别不同于用于 CA 证书。否则,证书和密钥文件将不会 适用于使用 OpenSSL 编译的服务器。这种情况下的典型错误 是:

    ERROR 2026 (HY000): SSL connection error:
    error:00000001:lib(0):func(0):reason(1)
    

    MySQL documentation

    但是,这只是让我成功了一部分。默认情况下,PHP 启用了VERIFY_IDENTITY,这需要与公用名匹配的主机名。

    这满足了一切:

    CA: 分配一个唯一的名称。可以是任何东西。我只是在我的 FQDN 前面加上 root.

    客户端和服务器:分配 MySQL 服务器的 FQDN。 这两个值必须匹配。

    如果客户端和服务器之间的 FQDN 不匹配,则VERIFY_IDENTITY 将失败。

    如果 FQDN 在 ca、客户端和服务器之间匹配,那么 PHP 中的 OpenSSL 将按照 MySQL 文档中的承诺失败。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-13
      • 2017-06-12
      • 2018-08-11
      • 1970-01-01
      • 2018-11-05
      • 1970-01-01
      • 2013-01-29
      相关资源
      最近更新 更多