PHP PDO连接MySQL指定TLS1.2版本失败问题求助
解决PHP 5.6.40 PDO连接MySQL 8.0的TLS 1.2版本指定问题
问题核心
PHP 5.6.40的PDO没有直接指定TLS版本的内置选项(该特性在PHP 7.1+才通过PDO::MYSQL_ATTR_TLS_VERSION引入),但OpenSSL 3.0与PHP 5.6的mysqlnd驱动组合时,默认协议版本或安全等级不匹配MySQL 8.0要求的TLS 1.2,导致连接失败。
解决方案
1. 修改PDO加密套件为TLS 1.2兼容组
将PDO配置中的MYSQL_ATTR_SSL_CIPHER替换为仅支持TLS 1.2的加密套件集合,强制握手时使用TLS 1.2:
$options_ssl_arr = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_PERSISTENT => true, PDO::MYSQL_ATTR_FOUND_ROWS => true, PDO::MYSQL_ATTR_SSL_KEY => '/path/to/cert/abc.pem.key', PDO::MYSQL_ATTR_SSL_CERT => '/path/to/cert/abc.pem.crt', PDO::MYSQL_ATTR_SSL_CA => '/path/to/cert/abc.ca.pem.crt', // 指定TLS 1.2专属加密套件 PDO::MYSQL_ATTR_SSL_CIPHER => 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256', ];
2. 通过PHP-FPM环境变量强制TLS 1.2
由于修改系统全局openssl.cnf可能未被PHP-FPM读取,需单独配置PHP-FPM的环境变量和自定义OpenSSL配置:
- 编辑PHP-FPM池配置(如
/etc/php/5.6/fpm/pool.d/www.conf),添加:env[MYSQL_TLS_VERSION] = TLSv1.2 env[OPENSSL_CONF] = /etc/ssl/openssl-custom.cnf - 创建
/etc/ssl/openssl-custom.cnf,设置最小协议版本和兼容安全等级:[openssl_init] ssl_conf = ssl_sect [ssl_sect] system_default = system_default_sect [system_default_sect] MinProtocol = TLSv1.2 CipherString = DEFAULT@SECLEVEL=1 - 重启PHP-FPM生效:
sudo service php5.6-fpm restart
3. 验证MySQL端配置(可选)
确认MySQL 8.0的my.cnf或my.ini中已启用TLS 1.2:
[mysqld] tls_version=TLSv1.2
(注:你已通过Python 3连接验证,此步骤可跳过)
原理说明
OpenSSL 3.0默认安全等级为2,部分旧款TLS 1.2套件会被过滤;同时PHP 5.6的mysqlnd驱动未自动适配OpenSSL 3.0的默认规则。通过指定加密套件、强制TLS版本和降低安全等级,让PHP与MySQL的SSL握手协议版本对齐。
内容的提问来源于stack exchange,提问作者Xiaopei
相关产品推荐
相关产品推荐

