必须先执行SHOW VARIABLES LIKE 'have_ssl';确认返回YES,否则后续所有SSL配置无效;常见原因是mysqld未加载OpenSSL库,返回DISABLED时应重装官方MySQL包而非调试证书路径。

确认 MySQL 是否真正支持 SSL
执行 SHOW VARIABLES LIKE 'have_ssl';,返回值必须是 YES,否则后续所有配置都无效。常见原因是 mysqld 启动时没加载 OpenSSL 库(比如精简版 MariaDB、或编译时未加 -DWITH_SSL=system)。如果返回 DISABLED,别折腾证书路径——重装官方 MySQL 二进制包最省事。
顺带检查 SELECT @@GLOBAL.tls_version;,确保值包含 TLSv1.2 或 TLSv1.3;若为空或只含旧协议,说明服务端 TLS 栈未就绪。
证书路径、权限与 require_secure_transport=ON 缺一不可
在 my.cnf 的 [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
require_secure_transport = ON 是强制开关,它让所有非 SSL 连接直接被拒绝。仅设 ssl_mode = REQUIRED 没用——这个变量已被弃用且不生效。
关键细节:
- 证书文件必须由
mysql用户可读,server-key.pem权限必须是600(-rw-------) - 路径不能是
~/、相对路径或符号链接;/root/下的文件一定读不到 - 改完必须
systemctl restart mysqld,reload不触发 SSL 重载
用户级 REQUIRE SSL 才真正起作用
REQUIRE SSL 不是全局策略,而是绑定到每个用户的权限记录里。新建用户直接加:
CREATE USER 'app'@'%' IDENTIFIED BY 'pwd' REQUIRE SSL;
已有用户补加(仅 MySQL ≥ 8.0.22 支持):
ALTER USER 'app'@'%' REQUIRE SSL;
注意:MySQL 8.0.21 及更早版本不支持对已有用户追加该限制,只能删掉重建。漏掉这步,即使服务端开了 SSL,用户仍可用明文连上。
验证是否生效:用该用户连接后执行 SELECT Ssl_cipher FROM information_schema.PROCESSLIST WHERE ID = CONNECTION_ID();,返回空字符串即未加密。
客户端连接失败?先看错误类型再排查
常见报错及对应动作:
-
SSL connection error: protocol version mismatch→ 检查服务端tls_version和客户端支持的 TLS 版本是否重叠;JDBC 需显式加&enabledTLSProtocols=TLSv1.2 -
X509_V_ERR_IP_ADDRESS_MISMATCH→ 自签证书缺subjectAltName,必须用ext.cnf补全 IP 或 DNS(如IP:192.168.1.100) -
Failed to initialize TLS for channel→ SELinux/AppArmor 拦截了文件访问,临时setenforce 0测试是否为此问题 -
mysql -u app -p连不上 → 默认不启用 SSL,必须加--ssl-mode=REQUIRED
证书私钥一旦被加密(比如生成时用了 -passout),MySQL 就会静默失败,日志里只报“Unable to get private key”——务必用 openssl rsa -in server-key.pem -out server-key.pem 去密。


















