先查服务端证书是否过期,mysql不报“证书已过期”而只抛ssl connection error: certificate verify failed;运行openssl x509 -in /var/lib/mysql/ca.pem -text -noout | grep -e "(not before|not after)",若not after早于当前时间即为过期。

直接看服务端证书是否过期
MySQL不报“证书已过期”,只抛SSL connection error: certificate verify failed,所以别在客户端反复试配置,先登服务端查证书有效期。
运行:openssl x509 -in /var/lib/mysql/ca.pem -text -noout | grep -E "(Not Before|Not After)"
- 如果
Not After时间早于当前系统时间,就是它了 - 注意路径:
ssl_ca变量值(SHOW VARIABLES LIKE 'ssl_ca';)必须和实际文件路径一致 - 自签名场景下,
ca.pem和server-cert.pem通常同一批生成,过期时间一致;云数据库(如阿里云RDS)不提供文件访问,得去控制台查证书有效期
客户端连不上,先确认--ssl-ca和--ssl-mode是否配对
命令行连MySQL时,--ssl-mode=VERIFY_IDENTITY必须搭配--ssl-ca=/path/to/ca.pem,缺一不可。只写--ssl-mode=REQUIRED等于放弃身份校验,生产环境禁用。
-
--ssl-ca必须是绝对路径,~/certs/ca.pem或./ca.pem在多数shell里会解析失败 - 云数据库(如RDS)必须用控制台下载的专用CA证书,例如
aliyun-rds-ca-cert.pem,不能用mysql_ssl_rsa_setup本地生成的 - 若服务端启用了
require_secure_transport=ON,客户端不满足VERIFY_IDENTITY也会被拒绝,哪怕加密通道通了
JDBC或DBeaver报javax.net.ssl.SSLHandshakeException
这个错误基本锁定在JVM证书加载环节,不是驱动问题,是JVM没拿到或不认CA。
- DBeaver:连接编辑页 → Driver properties → 找
sslTrustCertificate,填绝对路径(如/home/user/certs/rds-ca.pem),同时确保useSSL=true且sslMode=REQUIRED - JDBC URL必须显式带
trustCertificateKeyStoreUrl=file:/tmp/rds-ca.pem&trustCertificateKeyStorePassword=changeit;若用PEM格式,部分驱动支持sslTrustCertificate参数,但需确认驱动版本 - JVM太老(如Java 8u151之前)默认不启用TLSv1.2,而MySQL 8.0+默认协商TLSv1.2,要么升级JDK,要么加JVM参数
-Djdk.tls.client.protocols=TLSv1.2
证书换了,但客户端还是连不上
证书文件更新后,MySQL服务进程未必自动重载,客户端也可能缓存旧CA或信任库。
- 服务端:MySQL 5.7.36+/8.0.16+执行
ALTER INSTANCE RELOAD TLS;;老版本只能service mysql restart - Java应用:JVM启动时已加载
truststore,必须重启应用;Alpine Linux容器里默认没有/etc/ssl/certs/ca-certificates.crt,得手动挂载或指定路径 - PHP PDO:
PDO::MYSQL_ATTR_SSL_CA必须指向完整CA bundle,且www-data用户要有读权限(chmod 644比600更稳妥)
certificate verify failed反复出现。











