mysql ssl加密连接需同时满足三项:have_ssl= yes、用户权限含require ssl、客户端完成tls握手,缺一不可;否则静默降级明文传输。

MySQL SSL 加密连接不是“配了证书就自动生效”,必须同时满足 have_ssl = YES、用户权限含 REQUIRE SSL、客户端真实完成 TLS 握手这三项,缺一不可。漏掉任意一项,连接都会静默降级为明文——你查 SHOW VARIABLES 看着全绿,但 Ssl_cipher 为空,数据已在裸奔。
确认 have_ssl 是否真正启用(不是编译支持,是运行时加载)
很多问题卡在这一步:配置写了、证书放了、服务也重启了,SHOW VARIABLES LIKE 'have_ssl' 却返回 DISABLED 或空值。这说明 mysqld 启动时压根没加载 OpenSSL 模块。
-
SHOW VARIABLES LIKE 'have_ssl'必须返回YES;若为DISABLED,常见于 MariaDB 精简版、MySQL 编译时未加-DWITH_SSL=system,或进程以错误用户启动(如 root 启动但证书属主是 mysql) - 顺带查
SHOW VARIABLES LIKE 'ssl_ca'、ssl_cert、ssl_key——三者必须返回非空的绝对路径,且对应文件真实存在 - 如果
have_ssl是DISABLED,重装官方二进制包比自行编译修复更稳妥
生成并验证证书路径、权限、格式(三者必须同时满足)
MySQL 对证书极其挑剔:只认绝对路径、只读 PEM 格式、私钥权限必须为 600。相对路径、~/、权限 >600 的私钥都会导致启动失败或连接被拒。
- 优先用内置工具生成(MySQL 5.7.6+):
mysql_ssl_rsa_setup --datadir=/var/lib/mysql --uid=mysql,它自动处理subjectAltName,避免X509_V_ERR_IP_ADDRESS_MISMATCH - 证书必须放在 MySQL 进程有读权限的目录,例如
/var/lib/mysql/ca.pem,不能放/root/或/home/deploy/ - 立刻修正权限:
chown mysql:mysql /var/lib/mysql/*.pem && chmod 600 /var/lib/mysql/server-key.pem—— MySQL 拒绝读取组/其他可读的私钥 - 检查方式:
sudo -u mysql ls -l /var/lib/mysql/server-key.pem,输出必须是-rw-------
正确配置 my.cnf 并强制 require_secure_transport = ON
仅在 [mysqld] 段配置 ssl_ca、ssl_cert、ssl_key 不等于启用加密——客户端仍可走明文连接。require_secure_transport = ON 是强制开关,不是可选项。
- 编辑
/etc/my.cnf或/etc/mysql/mysql.conf.d/mysqld.cnf,只在[mysqld]段添加: ssl_ca = /var/lib/mysql/ca.pemssl_cert = /var/lib/mysql/server-cert.pemssl_key = /var/lib/mysql/server-key.pemrequire_secure_transport = ON- 路径必须是绝对路径,不能用
~/或相对路径;不要写在[client]段——那是客户端配置,对服务端无效 - 改完必须
systemctl restart mysqld(不是reload),SSL 配置不支持热加载
验证连接是否真走 SSL(STATUS 比 VARIABLES 更可信)
SHOW VARIABLES 只告诉你“配了什么”,SHOW STATUS LIKE 'Ssl_cipher' 才反映当前会话真实状态。返回非空值(如 ECDHE-ECDSA-AES256-SHA)才表示加密已生效。
- 新建用户:
CREATE USER 'app'@'%' IDENTIFIED BY 'pwd' REQUIRE SSL;已有用户(MySQL ≥ 8.0.22):ALTER USER 'app'@'%' REQUIRE SSL - 客户端连接时必须显式启用:
mysql -u app -p --ssl-mode=REQUIRED;若要校验证书,用--ssl-mode=VERIFY_CA --ssl-ca=/path/to/ca.pem - 务必用
127.0.0.1或远程 IP 测试——localhost默认走 Unix socket,完全绕过 SSL - 重启后立刻查错误日志:
tail -n 50 /var/log/mysqld.log | grep -i ssl,出现Failed to set up SSL就说明证书或权限有问题
最常被忽略的是:即使 require_secure_transport = ON 已开,localhost 连接仍走 socket;而 REQUIRE SSL 对已有用户在旧版本中无法追加;还有就是客户端不指定 --ssl-mode,服务端再严也没用——这些点不逐个核验,SSL 就只是个摆设。











