
MySQL客户端连接报 SSL connection error: protocol version mismatch 怎么办
证书路径没更新,或者服务端/客户端 TLS 版本不一致,是最常见原因。MySQL 8.0+ 默认要求 TLSv1.2,旧证书或旧 OpenSSL 库可能只支持到 TLSv1.0。
实操建议:
- 先确认服务端支持的协议版本:
SHOW VARIABLES LIKE 'tls_version';(返回值类似TLSv1.2,TLSv1.3) - 检查客户端 OpenSSL 版本:
openssl version,低于1.1.1的很可能不支持 TLSv1.3,且对 TLSv1.2 兼容不稳定 - 若用
mysql命令行连接,必须显式指定证书路径,不能依赖系统默认位置:mysql --ssl-ca=/path/to/ca.pem --ssl-cert=/path/to/client-cert.pem --ssl-key=/path/to/client-key.pem -h host -u user - 证书文件权限必须严格(尤其
.pem私钥):客户端会拒绝读取权限过宽的client-key.pem(如 group/others 可读),报错SSL connection error: SSL_CTX_set_default_verify_paths failed
my.cnf 里 ssl-ca/ssl-cert/ssl-key 路径迁移到新服务器后连不上
路径写死在配置里,迁移后没改,是最直接的失败点。MySQL 客户端(包括 mysqldump、mysqlpump)读 [client] 段,服务端读 [mysqld] 段,别混用。
实操建议:
- 检查实际生效的配置文件路径:
mysql --help | grep "Default options",常见有/etc/my.cnf、/etc/mysql/my.cnf、~/.my.cnf,优先级从高到低 -
[client]段下的ssl-ca必须是绝对路径;相对路径(如./certs/ca.pem)会被解析为当前执行命令的工作目录,极易出错 - 如果用 Docker 或 systemd 启动 MySQL 客户端工具,环境变量
HOME可能被重置,导致~/.my.cnf不生效,建议统一用/etc/my.cnf并设好权限 - 证书文件需由运行客户端的用户可读(例如用
sudo -u mysql mysql连接,则mysql用户必须能读取所有.pem文件)
Java 应用里 javax.net.ssl.SSLHandshakeException 和 MySQL SSL 握手失败的关系
不是 MySQL 配置错了,而是 JVM 自带的 truststore 没导入 CA 证书,或没启用对应 TLS 协议。JDBC URL 中的 &useSSL=true&requireSSL=true 已废弃,MySQL Connector/J 8.0+ 强制走 &sslMode=REQUIRED。
实操建议:
- JDBC URL 必须明确指定 sslMode:
jdbc:mysql://host:3306/db?sslMode=REQUIRED&serverSslCert=/path/to/ca.pem;serverSslCert是 CA 证书路径(非 client-cert),用于验证服务端身份 - 如果服务端证书是自签名或私有 CA 签发,需把 CA 证书导入 JVM truststore:
keytool -import -alias mysql_ca -file ca.pem -keystore $JAVA_HOME/jre/lib/security/cacerts(默认口令changeit) - 避免用
verifyServerCertificate=false绕过验证——它只是关校验,不解决证书路径问题,且线上禁用 - Spring Boot 应用注意:
spring.datasource.hikari.connection-init-sql等初始化语句会在 SSL 握手后执行,但若握手失败,根本不会走到那一步
证书文件迁移到新机器后,mysql_ssl_rsa_setup 生成的密钥为啥不能直接复用
它生成的是服务端证书(ca.pem、server-cert.pem、server-key.pem),而客户端连接需要的是「客户端证书对」或至少信任同一 CA。直接拷贝服务端私钥给客户端用,既不安全,也不符合 MySQL 的双向认证逻辑。
实操建议:
-
mysql_ssl_rsa_setup仅用于快速搭建测试环境,生产环境应使用独立 CA 签发客户端证书,或至少用openssl手动签发:openssl x509 -req -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -days 365 - 客户端无需
server-key.pem,也绝不能拿到它;拿到即意味着服务端私钥泄露 - 迁移时只需复制三样:
ca.pem(服务端 CA)、client-cert.pem、client-key.pem;并确保client-key.pem权限为600 - 如果原环境用的是自签名 CA,新环境必须复用同一个
ca.pem和ca-key.pem,否则客户端无法验证服务端证书链
证书路径本身不复杂,但每层都卡在权限、路径解析上下文、TLS 协议协商细节上。最容易被忽略的是:客户端读配置的用户身份、当前工作目录、JVM truststore 状态,这三者任何一个不匹配,都会让证书“明明放对了位置却连不上”。









