【问题标题】:MySQLi SSL connection stops working after php 7 upgradephp 7 升级后 MySQLi SSL 连接停止工作
【发布时间】:2017-03-06 08:59:23
【问题描述】:

在将我的项目从 PHP 5.6 迁移到 PHP 7 时,我遇到了一个奇怪的问题,我有一个数据库类,它允许您在调用 mysqli_init(); 和调用 mysqli_real_connect() 之前设置与数据库的 SSL 连接。

我一直在 PHP 5.6 上开发此功能,并成功创建了与远程服务器的 SSL 连接,一切正常,远程数据库服务器不使用自签名证书。

在我的 db 类的 setSSL 方法中,我有这个:

        if($verify) { $this->mysqli->options(MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, true); }
        $this->mysqli->ssl_set($key, $cert, $ca, $capath, $ciphers);

该方法将$verify 设置为默认设置true 并保持原样,证书包通过变量$ca 传递。

这在 PHP 5.6 上运行良好,并且完全按照应有的方式运行,并确认该连接确实使用了 SSL 连接。

在同一台服务器上,我创建了一个子域并将其设置为使用 PHP 7(我听说性能要好得多,而且我的代码对 PHP 7 友好)。

我在新子域上完成了我的代码的完整副本,一切正常,除了远程 SSL mysqli 连接。

我已经检查了 PHP 7 中删除的功能和许多其他内容,但无法找出发生这种情况的原因。

从日志中提取:

[Msg: mysqli::real_connect(): SSL 操作失败,代码为 1。 OpenSSL 错误消息:错误:14090086:SSL 例程:SSL3_GET_SERVER_CERTIFICATE:证书验证失败]

[Msg: mysqli::real_connect(): 无法使用 SSL 连接到 MySQL]

[Msg: mysqli::real_connect(): [2002] (尝试通过 tcp://******.co.uk:3306)]

另一方面,如果我没有通过 ca 证书包,这与我第一次在 PHP 5.6 上开发此功能时产生的错误相同。

【问题讨论】:

  • 错误日志中有什么内容?
  • 感谢@neuhaus 的回复我已经用日志的摘录更新了这个问题。如上所述,这在 5.6 中运行良好,但在 PHP 7 中中断。我已经确认 ca 文件的正确位置正在传递给 ssl_set 方法。

标签: php ssl mysqli upgrade php-7


【解决方案1】:

我 99% 确定这是因为您使用的是链式证书(这很常见)和 MySQL 目前does not support chained certificates(这很烦人)。

您通常不要将中间证书加载到客户端证书池中,因为这会降低安全性,并且是许多网络服务器所有者常犯的错误。 但由于没有其他关于 MySQL 的解决方案,您可能只想做 那个。

因此,作为一种解决方法,请尝试将 CA 所有中间证书加载到您的 PHP 证书池中 - 请记住,这是一种不好的做法。

更新:

我认为这个错误很久以前就已经解决了,但是 MySQL 团队没有更新他们的票,...取决于哪个 ssl 库被烘焙到你的 MySQL(通常是 openssl)中,它应该已经可以工作了。

在此处阅读如何连接和构建适当的证书链:How to chain a SSL certificate

【讨论】:

  • 感谢@DanFromGermany 的回复,我明白你在说什么,我会尝试你的建议,但仍然不确定为什么会这样。我在应用程序中拥有的 ca 包和完整文件位置被传递给 ssl_set 选项。问题是,我正在连接到一个没有任何更改的远程数据库服务器,该连接在运行 PHP 5.6 的开发服务器上工作正常,但在连接到同一远程服务器的 PHP 7 上停止工作。 ca 包来自 Mozilla 的存储库,并由 cron 作业自动更新。
  • 我已经尝试了你的建议,没有任何影响,仍然得到完全相同的错误。
  • 链/包必须由服务器发送。它不应永久存储在客户端上。如果它适用于旧客户端但不适用于新客户端,则听起来与服务器发送错误的中间证书完全相同。 您能否使用 openssl verify <your_cert.pem> 命令验证您的证书链。
  • 非常感谢您的帮助@DanFromGermany,非常感谢。我已经验证了 ca 捆绑包,并从命令行得到了一个简单的“OK”。 PHP 5.6 和 PHP 7 开发区位于同一台服务器上,使用相同的 ca 包和相同的完整路径。在新的子域上,如果我将域降级为使用 PHP 5.6,则相同的代码可以工作,回到 PHP 7 它会停止工作。我有 plesk 并且可以在控制面板中更改 PHP 版本。
  • 也许证书的路径消失了。将其输出与两个 PHP 版本进行比较:print_r(openssl_get_cert_locations());
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-14
  • 2019-08-11
  • 2021-07-05
  • 1970-01-01
相关资源
最近更新 更多