【问题标题】:PHP PDO SSL MySQL connection failsPHP PDO SSL MySQL 连接失败
【发布时间】:2012-03-13 16:25:59
【问题描述】:

我正在尝试开发一个使用 SSL 连接到 MySQL 服务器的 PHP 应用程序。 我尝试使用 mysql_connect 并且工作正常,但使用 PDO 却不行。当我尝试连接时,出现以下错误:

PDO::__construct(): 这个流不支持 SSL/crypto

看起来很奇怪的是,如果我调整证书路径(指向不存在的文件),我会得到同样的错误!

我在 Debian Squeeze 上使用 php 5.3.10,安装了以下软件包:

php5-cgi 
php5-cli
php5-common
php5-fpm
php5-gd
php5-mcrypt
php5-mysql
php5-suhosin

有什么想法吗?谢谢

【问题讨论】:

  • 看看this bug report,虽然对我来说似乎很模棱两可。一个引用说“注意,在 PHP 5.3.8 上,当我尝试使用 PDO 时,mysql 和 SSL 对我来说失败了。”,另一个引用说“5.3.8 中的 PDO 和 SSL 问题已经在 SVN 中修复,这是由于#ifdef 中的错字。我希望它以某种方式有所帮助。我想您也可以将其应用于 5.3.10。
  • 我发现了那个错误报告,但我认为错字在源代码中,并且在以后的版本中已修复,所以我认为它不适用。

标签: php mysql ssl pdo


【解决方案1】:

您需要移除 php-mysql 并安装 php-mysqlnd。在 Centos 上:

sudo yum remove php-mysql
sudo yum install php-mysqlnd
sudo yum reboot

Ubuntu/Debian

sudo apt-get remove php5-mysql
sudo apt-get install php5-mysqlnd
sudo reboot

mysqli 程序:

$con=mysqli_init();
if (!$con)
  {
  die("mysqli_init failed");
  }

mysqli_ssl_set($con,'/ssl/client-key.pem','/ssl/client-cert.pem', '/ssl/ca.pem',NULL,NULL);

if (!mysqli_real_connect($con,'xx.xxx.xxx.xxx', 'user', 'pass' ,'dbname'))
  {
  die("Connect Error: " . mysqli_connect_error());
  }

mysqli_close($con);
?>

PDO

$ssl = array(
                PDO::MYSQL_ATTR_SSL_KEY    =>'/ssl/client-key.pem',
                PDO::MYSQL_ATTR_SSL_CERT=>'/ssl/client-cert.pem',
                PDO::MYSQL_ATTR_SSL_CA    =>'/ssl/ca.pem'
        );
        try {
                $dbl = new PDO("mysql:host=$host;dbname=$database", $user, $password, $ssl);
                $dbl->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch(PDOException $e) {
echo $e->getMessage();
die;
        }

您的证书路径必须正确。在您的 SSL 中尝试此操作以确保文件存在:

if(file_exists('/ssl/client-key.pem') && file_exists('/ssl/client-cert.pem') && file_exists('/ssl/ca.pem')) echo 'file exists';

远程主机(数据库服务器)也必须启用 SSL。运行查询

SHOW VARIABLES LIKE '%ssl%';

输出:

+---------------+----------------------+
| Variable_name | Value                |
+---------------+----------------------+
| have_openssl  | YES                  |
| have_ssl      | YES                  |
| ssl_ca        | /ssl/ca.pem          |
| ssl_capath    |                      |
| ssl_cert      | /ssl/server-cert.pem |
| ssl_cipher    | DHE-RSA-AES256-SHA   |
| ssl_key       | /ssl/server-key.pem  |
+---------------+----------------------+

如果它被禁用,它将无法工作。您的 /etc/my.cnf(或您的 my.cnf 所在的位置)必须包含:

ssl-ca=/ssl/ca.pem
ssl-cert=/ssl/server-cert.pem
ssl-key=/ssl/server-key.pem
ssl-cipher=DHE-RSA-AES256-SHA

生成密钥的 MySQL 资源:http://dev.mysql.com/doc/refman/5.0/en/creating-ssl-files-using-openssl.html

最后,DHE 密码不再被认为是安全的。密码不断被破解,因此您必须找出今天哪些被认为是安全的。

【讨论】:

  • 非常感谢,遗憾的是我没有设置要测试了。我希望它对其他人有用
  • 我注意到这是一个旧线程,但它出现在 Google 中用于我的所有搜索,所以我希望其他人不要像我一样花几个小时摆弄。
【解决方案2】:

您的模块列表不包括 openssl

您可以使用php -m 检查已编译的模块。你可以通过运行php -a然后执行var_dump(get_loaded_extensions());来检查运行时加载的所有模块

您需要将其编译或作为扩展加载才能使用 SSL 连接。

如果磁盘上存在扩展(检查您的 php 扩展目录 - 在 php.ini 中的位置),那么还要检查您的 php.ini 中的 extension=php_openssl.so 行,并确保它没有被注释掉。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-22
    • 2017-12-13
    • 2016-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-18
    • 1970-01-01
    相关资源
    最近更新 更多