require_secure_transport=ON后连不上MySQL,是因为服务端SSL未真正就绪:have_ssl为DISABLED、证书路径为空或不可读、SELinux/AppArmor拦截、TLS版本不匹配等导致握手失败。

必须先确认服务端 SSL 已真正就绪,否则 require_secure_transport = ON 会直接拒绝所有连接,包括本地 root。
为什么 require_secure_transport = ON 后连不上 MySQL?
这不是配置错了,而是服务端压根没准备好 SSL 握手能力。常见原因有:
-
SHOW VARIABLES LIKE 'have_ssl';返回DISABLED→ OpenSSL 库未加载或证书路径无效 -
ssl_ca、ssl_cert、ssl_key三个变量中任一为空 → MySQL 启动时跳过 SSL 初始化 - Linux 下 mysqld 进程用户(如
mysql)对证书文件无读权限 → 日志里出现SSL error: Unable to get private key - SELinux 或 AppArmor 拦截访问 → 临时执行
setenforce 0测试可快速验证
如何安全启用 require_secure_transport
这个开关是全局强制 TLS 的最后一道闸门,但它不替代证书配置。启用前需确保:
- 证书路径是绝对路径,且文件在
mysqld进程用户视角下可读(chown mysql:mysql *.pem && chmod 600 server-key.pem) - 配置写在
[mysqld]段下,例如:ssl-ca = /etc/mysql/ssl/ca.pem<br>ssl-cert = /etc/mysql/ssl/server-cert.pem<br>ssl-key = /etc/mysql/ssl/server-key.pem<br>require_secure_transport = ON
- 不要只用
SET GLOBAL require_secure_transport = ON临时设置 → 它不持久,MySQL 重启后失效,且若此时证书未加载,会导致服务无法启动
require_secure_transport = ON 和 REQUIRE SSL 用户的区别
二者作用层级不同,不能互相替代:
-
require_secure_transport = ON是全局策略:所有 TCP 连接(含127.0.0.1)都必须走 TLS,否则直接拒绝;Unix socket 连接不受影响(除非显式禁用) -
REQUIRE SSL是账户级限制:只对该用户生效,但前提是服务端已支持 SSL;它不阻止非加密连接尝试,而是握手阶段校验是否用了 TLS - 典型组合是:全局开
require_secure_transport = ON+ 关键账号加REQUIRE SSL,形成双重保障
客户端连不上?重点检查 TLS 协议兼容性
错误信息里带 protocol version mismatch 或 SSL connection error,大概率是 TLS 版本对不上:
- MySQL 8.0.28+ 默认
tls_version = TLSv1.2,TLSv1.3,老 JDBC 驱动或 MySQL 5.7 客户端可能只支持 TLSv1.0 - 服务端可临时放宽:执行
SET PERSIST tls_version = 'TLSv1,TLSv1.1,TLSv1.2';(不推荐长期使用) - 客户端显式指定协议更稳妥:
mysql -u user -p --ssl-mode=REQUIRED --tls-version=TLSv1.2,JDBC URL 加&enabledTLSProtocols=TLSv1.2 - 避免用
--ssl-mode=VERIFY_IDENTITY配自签名证书 → 客户端会校验 CN,而自签证书 CN 往往是localhost,与实际连接地址不一致
真正容易被忽略的是:证书文件权限和 SELinux/AppArmor 的静默拦截。很多问题表面是配置失败,实际是 mysqld 根本没读到私钥,日志里那句 Unable to get private key 就是唯一线索。


















