MySQL真正启用SSL需同时满足have_ssl=YES且ssl_mode=REQUIRED(或更严值),并配置ssl_ca、ssl_cert、ssl_key三项路径,私钥权限600且属主为mysql用户,再加require_secure_transport=ON强制加密连接。

确认 MySQL 是否真正支持并启用 SSL
光看 have_ssl=YES 不代表 SSL 已生效——它只说明编译时启用了 SSL 支持。必须同时满足两个条件:have_ssl=YES 且 ssl_mode=REQUIRED(或更严格值如 VERIFY_CA)才算服务端强制启用。
执行这两条命令缺一不可:
SHOW VARIABLES LIKE 'have_ssl';
SHOW VARIABLES LIKE 'ssl_mode';
如果 have_ssl 是 DISABLED,检查启动参数或配置文件里有没有 skip_ssl 或 --skip-ssl;如果 ssl_mode 是 DISABLED 或空,说明服务端没强制要求加密,客户端仍可降级为明文连接。
配置 ssl_ca、ssl_cert、ssl_key 的硬性要求
这三个路径必须全部显式写在 my.cnf 的 [mysqld] 段落中,少一个,MySQL 启动时就会静默跳过 SSL 初始化,have_ssl 变成 DISABLED。
-
ssl_ca = /var/lib/mysql/ca.pem:CA 根证书,用于验证服务端(和客户端,若双向)证书签名链 -
ssl_cert = /var/lib/mysql/server-cert.pem:服务端公钥证书,必须由ssl_ca签发 -
ssl_key = /var/lib/mysql/server-key.pem:服务端私钥,权限必须是600,属主必须是mysql用户,否则 mysqld 启动失败并报SSL error: Unable to get private key
路径不能是相对路径,不能放在 /root/ 或其他 MySQL 进程无读权限的位置;证书必须是 PEM 格式,且 server-cert.pem 中不能包含私钥内容。
为什么加了 require_secure_transport = ON 才算真安全
只配证书不加这行,等于“门开着但没锁”——客户端仍可用 --ssl-mode=DISABLED 或旧驱动绕过加密。加上后,所有新连接都会被拒绝,除非明确走 SSL/TLS。
这个参数从 MySQL 5.7.17 起可用,8.0+ 默认不开启,必须手动添加:
[mysqld] ssl_ca = /var/lib/mysql/ca.pem ssl_cert = /var/lib/mysql/server-cert.pem ssl_key = /var/lib/mysql/server-key.pem require_secure_transport = ON
改完必须 systemctl restart mysqld(不是 reload),因为 SSL 配置不支持热加载。
客户端连不上?先盯住这几个点
服务端配得再对,客户端不配合也白搭。常见断连原因集中在证书加载和校验逻辑上:
- 命令行连接漏了
--ssl-ca:只加--ssl-mode=REQUIRED仅加密,不验证服务端身份,中间人攻击仍可能成功 - JDBC URL 缺参数:
?useSSL=true&requireSSL=true&verifyServerCertificate=true&trustCertificateKeyStoreUrl=file:/path/to/truststore,新版驱动中useSSL=true单独存在会被忽略 - PHP 的
mysqli必须显式调用mysqli_ssl_set(),否则全局配置无效 - 证书域名/IP 不匹配:客户端访问用的是
192.168.1.100,但server-cert.pem的subjectAltName没包含该 IP,会报X509_V_ERR_IP_ADDRESS_MISMATCH
最易被忽略的是:证书文件权限、SELinux/AppArmor 拦截、以及 server-key.pem 被误加了密码(MySQL 不接受加密私钥)——这些不会报明显错误,只会让 SSL 初始化失败,然后安静地退回非加密模式。


















