证书过期是90%“连不上”主因,需先查ca/server-cert.pem有效期,确认后更新带subjectaltname的新证书,并确保ssl-ca路径绝对、权限600、属主mysql,再重载mysql配置。

直接换证书,别修配置。90% 的“连不上”不是客户端写错了参数,而是服务端 CA 或 server-cert.pem 已过期,MySQL 升级或迁移后会严格校验——哪怕只超 1 天,TLS 握手就卡在 certificate verify failed。
怎么确认真是证书过期,而不是配错路径?
先别碰 my.cnf,上服务器直接查证书有效期:
- 运行
openssl x509 -in /var/lib/mysql/ca.pem -text -noout | grep -E "(Not Before|Not After)",如果Not After早于2026-06-14,就是它了 - 云数据库(RDS/AWS/腾讯云)去控制台「SSL 设置」页看
ValidTill字段,别 SSH 进去翻文件 - MySQL 8.0.29+ 可执行
SHOW VARIABLES LIKE 'ssl_cert_expire_date';,返回空或旧日期也说明证书失效
新证书必须带 subjectAltName,否则 MySQL 8.0+ 直接跳过加载
用 OpenSSL 自签时漏掉 subjectAltName,MySQL 启动不报错,但 have_ssl 是 DISABLED,SHOW STATUS LIKE 'Ssl_cipher'; 返回空——你根本意识不到证书被无视了。
-
subjectAltName必须覆盖所有连接方式:用localhost连?加DNS:localhost;用内网 IP10.0.1.5连?加IP:10.0.1.5;域名是db.example.com?加DNS:db.example.com - OpenSSL 3.0+ 可用
-addext "subjectAltName = DNS:localhost,IP:127.0.0.1";老版本必须写配置文件,在[req_ext]段明确声明 - 密钥用法至少含
digitalSignature, keyEncipherment,扩展密钥用法建议加serverAuth,别用sha1WithRSAEncryption
ssl-ca 路径和权限比证书内容还关键
MySQL 静默失败,日志里只写一句 Could not set ssl_mode,连错在哪都不说。它直接降级为非 SSL 连接(如果允许),或者握手失败。
-
ssl-ca必须写在[mysqld]段,不能放[client]或[mysql] - 路径必须是绝对路径,比如
/etc/mysql/ssl/ca.pem,./ca.pem或~/ssl/ca.pem都无效 - 文件属主必须是
mysql用户(Linux),权限必须是600;644都会导致加载失败 - 重启前手动测试:
sudo -u mysql cat /etc/mysql/ssl/ca.pem | head -1,能读才说明权限和路径都对
客户端连不上?先关验证再定位责任方
服务端证书更新后,客户端可能还在用旧 CA、缓存路径、或默认信任系统根证书。临时绕过验证能快速分清是服务端还是客户端的问题。
- 命令行测试:
mysql --ssl-mode=VERIFY_CA --ssl-ca=/path/to/new-ca.pem -u user -h host -p,报unable to get issuer certificate就说明客户端用的 CA 不是服务端发的那张 - 云数据库必须用控制台下载的专用 CA(如
aliyun-rds-ca-cert.pem),不能用本地mysql_ssl_rsa_setup生成的证书 - JDBC 连接要显式传
trustCertificateKeyStoreUrl和trustCertificateKeyStorePassword,光靠sslMode=REQUIRED不够 - PDO 必须设
PDO::MYSQL_ATTR_SSL_CA,且值是完整 CA bundle 路径;Alpine 容器里默认没有/etc/ssl/certs/ca-certificates.crt,得挂载或指定
最常被忽略的是:证书换了,但 MySQL 进程没重载配置;或者客户端代码里硬编码了旧 CA 路径,连 --ssl-ca 参数都没传——这种问题不会出现在错误日志里,只会表现为“明明证书更新了,还是连不上”。











