You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP通过私有CA证书远程SSL连接MySQL失败问题求助

问题描述

两台服务器均使用Ubuntu Server 22.04、MySQL 8.0、PHP 8.1。Server1上的PHP文件通过PDO尝试连接Server2的MySQL,配置了私有CA证书相关参数:

$pdo = new PDO('mysql:host=<server2_ip>;dbname=<dbname>', '<user>', '<password>',
      array(
       PDO::MYSQL_ATTR_SSL_KEY    =>'<path>/client-key.pem',
       PDO::MYSQL_ATTR_SSL_CERT=>'<path>/client-cert.pem',
       PDO::MYSQL_ATTR_SSL_CA    =>'<path>/ca.pem'
       )
    );  
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->exec('SET NAMES "utf8"');

私有SSL证书在Server2生成并同步到Server1。通过Server1命令行执行mysql -u <user> -h <server2_ip> -p可正常连接,但PHP文件执行时抛出PDOException:failed loading cafile stream。

尝试将ca.pem添加到/etc/ssl/certs目录并修改PDO的SSL_CA路径后,出现新错误:

SSL operation failed with code 1. OpenSSL Error messages: error:0200008A:rsa routines::invalid padding error:02000072:rsa routines::padding check failed error:1C880004:Provider routines::RSA lib error:06880006:asn1 encoding routines::EVP lib error:0A000086:SSL routines::certificate verify failed

不想通过添加PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false禁用证书验证(存在中间人攻击风险),寻求安全解决方法。

安全解决方法

1. 检查证书文件的路径与权限

  • 确保证书文件使用绝对路径,避免PHP因工作目录问题找不到文件;
  • 设置正确的权限:
    • ca.pem和client-cert.pem权限设为644,所属用户/组包含PHP运行用户(通常是www-data);
    • client-key.pem权限设为600,仅允许所有者读取,避免密钥泄露;
  • 执行命令调整权限:
    chmod 644 /path/to/ca.pem /path/to/client-cert.pem
    chmod 600 /path/to/client-key.pem
    chown www-data:www-data /path/to/*.pem
    

2. 验证MySQL服务器证书的有效性与匹配性

  • 在Server1上用OpenSSL命令验证Server2的证书链:
    openssl s_client -connect <server2_ip>:3306 -CAfile /path/to/ca.pem
    
    检查输出是否包含Verify return code: 0 (ok),若否则说明证书链存在问题;
  • 确认Server2的MySQL证书的**Common Name(CN)或Subject Alternative Name(SAN)**包含你连接时使用的<server2_ip>(或主机名)——PHP的PDO会严格验证这一点,而命令行mysql默认验证较宽松,这是常见的差异点。

3. 检查PHP的OpenSSL配置

  • 确认PHP已启用openssl扩展:查看php.ini中extension=openssl未被注释;
  • 可以在PHP中执行以下代码查看OpenSSL的证书搜索路径,确保你的CA证书位置符合要求:
    var_dump(openssl_get_cert_locations());
    

4. 确认MySQL用户权限配置

  • 在Server2的MySQL中,确保目标用户被配置为强制SSL连接,且允许从Server1的IP访问:
    GRANT ALL ON <dbname>.* TO '<user>'@'<server1_ip>' REQUIRE SSL;
    FLUSH PRIVILEGES;
    

5. 重新同步证书文件

若上述步骤无效,可能是证书在同步过程中损坏,重新用scp从Server2同步证书:

scp user@server2:/path/to/{ca.pem,client-cert.pem,client-key.pem} /local/path/

内容的提问来源于stack exchange,提问作者multivax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 02:25:36