Laravel/Lumen通过SSL连接MySQL报错:PDO::__construct()不支持SSL流
this stream does not support SSL/crypto错误 我来帮你排查这个头疼的SSL连接问题!你遇到的PDO::__construct(): this stream does not support SSL/crypto错误,结合你已经确认openssl和mysqlnd安装的情况,大概率是几个细节配置没到位,咱们一步步来解决:
先梳理下你当前的情况:
- 错误日志:
[2018-05-16 10:42:45] lumen.ERROR: exception 'ErrorException' with message 'PDO::__construct(): this stream does not support SSL/crypto' in /var/www/project/vendor/illuminate/database/Connectors/Connector.php:56
- 已确认信息:
- 通过
php -m验证openssl模块已安装 php-mysqlnd已安装- MySQL服务器已启用SSL(附状态截图:
)
- 通过
- 当前数据库配置片段:
'mysql' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', 'localhost'), 'port' => env('DB_PORT', 3306), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => env('DB_PREFIX', ''), 'timezone' => env('DB_TIMEZONE', '+00:00'), 'strict' => false, 'options' => array( PDO::MYSQL_ATTR_SSL_KEY => '/etc/ssl/certs/mysqlssl/key.pem', PDO::MYSQL_ATTR_SSL_CERT => '/etc/ssl/certs/mysqlssl/cert.pem', PDO::MYSQL_ATTR_SSL_CA => '/etc/ssl/certs/mysqlssl/ca-cert.pem', ), ]
具体解决步骤:
1. 确认PDO MySQL是否基于mysqlnd编译
虽然你装了mysqlnd,但有可能PHP的PDO MySQL扩展还是用的旧的libmysqlclient(这个库对SSL支持有限)。你可以用命令行检查:
php -i | grep "PDO MySQL"
看输出里的Client API version,如果显示mysqlnd x.x.x就没问题;如果是libmysqlclient x.x.x,那你需要重新安装/编译基于mysqlnd的PDO MySQL扩展。
2. 修复证书文件的权限问题
PHP运行的用户(比如www-data、nginx)必须能读取这三个SSL证书文件,否则会出现无法加载证书的隐性错误,最终触发SSL不支持的提示:
# 把证书文件的所有者改成PHP运行用户 chown www-data:www-data /etc/ssl/certs/mysqlssl/*.pem # 设置证书文件权限为600(仅所有者可读) chmod 600 /etc/ssl/certs/mysqlssl/*.pem # 确保证书目录权限正确 chmod 700 /etc/ssl/certs/mysqlssl/
3. 调整数据库配置的SSL选项
在你的options数组里补充两个关键配置,适配MySQL的SSL要求:
'options' => array( PDO::MYSQL_ATTR_SSL_KEY => '/etc/ssl/certs/mysqlssl/key.pem', PDO::MYSQL_ATTR_SSL_CERT => '/etc/ssl/certs/mysqlssl/cert.pem', PDO::MYSQL_ATTR_SSL_CA => '/etc/ssl/certs/mysqlssl/ca-cert.pem', // 如果是自签名证书,关闭服务器证书验证(权威CA签发的话可以设为true) PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false, // 指定和MySQL服务器匹配的加密套件 PDO::MYSQL_ATTR_SSL_CIPHER => 'DHE-RSA-AES256-SHA', ),
4. 先测试命令行的SSL连接
先排除MySQL服务器端的问题,用mysql客户端直接测试:
mysql -h 你的数据库主机 -u 你的数据库用户名 -p --ssl-ca=/etc/ssl/certs/mysqlssl/ca-cert.pem --ssl-cert=/etc/ssl/certs/mysqlssl/cert.pem --ssl-key=/etc/ssl/certs/mysqlssl/key.pem
如果能成功连接,说明服务器和证书没问题,问题在PHP端;如果连接失败,先排查MySQL的SSL配置(比如证书路径是否正确、是否允许远程SSL连接)。
5. 重启服务生效
修改配置和权限后,一定要重启PHP-FPM和web服务器:
service php-fpm restart service nginx restart
总结
最常见的两个原因是PDO用了libmysqlclient而非mysqlnd,或者证书权限不足,优先排查这两点,基本就能解决问题。
内容的提问来源于stack exchange,提问作者Pat

