PHP 7.4无客户端证书建立TLS加密MySQL/MariaDB连接问题求助
核心问题排查
你遇到的连接失败主要是两个配置错误导致的:
- 服务端配置段错误:你当前的SSL、强制安全传输等配置写在了
[mysql]段,该段是MySQL客户端的配置段,服务端配置需要放在[mysqld]段下才能生效。 - PHP连接未显式开启SSL标识:仅调用
ssl_set不会主动触发TLS握手,需要在real_connect时传入MYSQLI_CLIENT_SSL参数,才会发起加密连接请求。
解决方案
步骤1:修正服务端配置
将/etc/mysql/mariadb.conf.d/50-server.cnf中的配置移动到[mysqld]段下,修改后示例:
[mysqld] general_log_file = /var/log/mysql/mysql.log general_log = 1 log_error = /var/log/mysql/error.log ssl_cert = /etc/mysql/certs/ca-cert.pem ssl_key = /etc/mysql/certs/ca-key.pem tls_version = TLSv1.2,TLSv1.3 require-secure-transport = on bind-address = 0.0.0.0
修改完成后重启数据库服务生效:
systemctl restart mariadb # 若使用MySQL则执行 systemctl restart mysql
重启后可登录数据库执行SHOW VARIABLES LIKE 'have_ssl';确认返回值为YES,代表SSL配置生效。
步骤2:修正PHP端连接代码
根据你的场景需求,不用客户端证书的情况下可选择以下两种方案:
方案A:不验证服务端证书(适合内网、测试场景)
不需要额外传输证书到Web服务器,直接关闭证书校验即可:
$servername = "foo.bar"; $username = "user"; $password = "secret"; $dbname = "myDb"; $port = 3306; // 按实际端口修改 $mysqli = mysqli_init(); $mysqli->ssl_set(NULL, NULL, NULL, NULL, NULL); // 传入SSL连接标识,同时关闭服务端证书校验 $mysqli->real_connect($servername, $username, $password, $dbname, $port, NULL, MYSQLI_CLIENT_SSL | MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT); // 调试用:验证连接是否加密 if ($mysqli->connect_error) { die("连接失败: " . $mysqli->connect_error); } echo "加密连接状态:" . ($mysqli->get_connection_stats()['ssl'] ? '正常' : '未启用加密');
方案B:验证服务端证书(生产环境推荐)
将服务端生成的/etc/mysql/certs/ca-cert.pem上传到Web服务器的非公开目录(比如/var/www/certs/,确保该目录不能被HTTP直接访问),然后修改代码:
$servername = "foo.bar"; $username = "user"; $password = "secret"; $dbname = "myDb"; $port = 3306; $ca_cert_path = "/var/www/certs/ca-cert.pem"; // 替换为你上传的CA证书实际路径 $mysqli = mysqli_init(); // 传入CA证书路径用于校验服务端身份 $mysqli->ssl_set(NULL, NULL, $ca_cert_path, NULL, NULL); // 仅传入SSL连接标识即可,会自动校验服务端证书合法性 $mysqli->real_connect($servername, $username, $password, $dbname, $port, NULL, MYSQLI_CLIENT_SSL);
注意要给PHP进程授予CA证书文件的读取权限,避免权限不足导致校验失败。
内容的提问来源于stack exchange,提问作者Gill-Bates
相关产品推荐
相关产品推荐

