MySQL服务端SSL需用mysql_ssl_rsa_setup生成证书并配置ssl_ca、ssl_cert、ssl_key三项路径及require_secure_transport=ON,否则仍为明文连接;验证须查Ssl_cipher或Ssl_version非空。

MySQL 服务端 SSL 不会自动启用,哪怕你生成了证书文件,只要 require_secure_transport = ON 没加、路径写错、权限不对,或者 have_ssl 是 DISABLED,连接就还是明文。
怎么快速生成可用的证书文件(推荐 MySQL 8.0+ 内置工具)
MySQL 8.0 自带 mysql_ssl_rsa_setup,比手敲 OpenSSL 命令更可靠,不会漏掉 subjectAltName 或搞错格式。
- 停掉 MySQL:先确保
mysqld未运行,或确认数据目录可写(如/var/lib/mysql) - 切换到 MySQL 用户执行:
sudo -u mysql mysql_ssl_rsa_setup --datadir=/var/lib/mysql - 检查生成结果:
ls -l /var/lib/mysql/*.pem,必须看到ca.pem、server-cert.pem、server-key.pem三个文件 -
server-key.pem权限必须是600,且属主为mysql:mysql;否则 mysqld 启动时静默跳过 SSL 初始化
my.cnf 中哪些配置项不能少、不能写错
只写 ssl_ca 或只写两个参数,SSL 就算“半启用”——SHOW VARIABLES LIKE 'have_ssl' 仍返回 DISABLED。
- 必须在
[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(MySQL 5.7.17+ 支持),否则客户端用--ssl-mode=DISABLED仍能连上明文连接 - MySQL 8.0 可额外加
tls_version = TLSv1.2,TLSv1.3,5.7 不识别该参数,加了会启动失败 - 改完配置必须重启
mysqld,MySQL 启动时只读一次配置
验证 SSL 是否真生效,别只看 have_ssl=YES
have_ssl = YES 只说明 MySQL 编译支持 SSL 且证书加载没报错,不代表连接已加密。
- 连接后立即执行:
mysql -u root -p -e "STATUS;" | grep "SSL",确认输出含Ssl_cipher且非空 - 或查状态变量:
mysql -e "SHOW STATUS LIKE 'Ssl_version';",有值(如TLSv1.3)才算真正启用了加密通道 - 如果
Ssl_cipher为空,常见原因是客户端没强制走 SSL(比如用 Navicat 连接时没勾选“使用 SSL”),不是服务端配错了 - 错误日志(
/var/log/mysql/error.log)里出现SSL error: Unable to get certificate from file,基本是路径错、权限不足或 OpenSSL 库不可用
客户端连接时最容易忽略的三个点
服务端开了 SSL,不代表客户端自动加密。不显式要求,就等于白配。
- 命令行连接必须加参数:
mysql -u user -p --ssl-mode=VERIFY_CA --ssl-ca=/path/to/ca.pem;VERIFY_CA是最常用安全模式,REQUIRED不校验证书,风险高 - 连接字符串中若含
?ssl-mode=DISABLED(比如某些 ORM 默认行为),会直接绕过加密 - 如果服务端证书的
CN或subjectAltName不匹配客户端访问的 host(比如用192.168.1.100连,但证书 CN 是localhost),客户端会报certificate verify failed
真正卡住人的从来不是生成证书那几步,而是证书路径被 SELinux 拦截、server-key.pem 权限是 644 被 mysqld 拒绝读取、或者客户端连的时候根本没传 --ssl-ca ——这些地方一错,have_ssl 看着像 YES,实际流量全是明文。


















