必须先确认 mysql 服务端启用 ssl(have_ssl=yes 且 ssl_ca/cert/key 为有效绝对路径),再配置 require ssl 用户策略并客户端显式启用 ssl 模式,三者缺一不可。

必须先确认 MySQL 服务端真正启用了 SSL,否则给用户加 REQUIRE SSL 只会让连接直接失败——错误看着像权限拒绝,实际是 TLS 握手根本没开始。
确认服务端 have_ssl = YES 且证书路径有效
这是所有后续操作的前提。很多“配了连不上”的问题都卡在这一步。
-
SHOW VARIABLES LIKE 'have_ssl';必须返回YES;若为DISABLED或空值,说明 OpenSSL 模块未加载或配置被忽略 -
SHOW VARIABLES LIKE 'ssl_%';中ssl_ca、ssl_cert、ssl_key三项必须是非空绝对路径(如/var/lib/mysql/ca.pem),不能是OFF、空字符串或相对路径 - 常见静默失败原因:
server-key.pem权限不是600、属主不是mysql用户、SELinux/AppArmor 拦截读取、ssl_*配置写在了[client]段而非[mysqld]段
在 my.cnf 的 [mysqld] 段配置证书并重启服务
配置位置和重启方式错了,等于没配。
- 只能写在
[mysqld]段,不能放在[client]或[mysql]—— 那些只影响本地命令行工具 - 路径必须是绝对路径,例如:
ssl_ca = /var/lib/mysql/ca.pem,不要加引号,不要用.或~ - 修改后必须执行
systemctl restart mysqld(不是reload),因为 SSL 参数只在启动时加载
给特定用户添加 REQUIRE SSL 策略
REQUIRE SSL 是用户级强制策略,它不开启 SSL,只在服务端已启用 SSL 的前提下起访问控制作用。
- 新建用户时直接指定:
CREATE USER 'appuser'@'10.0.2.%' IDENTIFIED BY 'p4ssw0rd' REQUIRE SSL; - 已有用户补加策略(MySQL 8.0.22+ 支持):
ALTER USER 'appuser'@'10.0.2.%' REQUIRE SSL; - 执行后需
FLUSH PRIVILEGES;,否则旧连接可能仍缓存旧权限状态 - 验证是否生效:
SELECT user, host, ssl_type FROM mysql.user WHERE user = 'appuser';,ssl_type应为ANY
客户端连接必须显式启用 SSL 模式
即使用户设了 REQUIRE SSL,客户端不主动发起 TLS 握手,连接仍会被拒绝——这不是认证失败,是协议层被拦在门外。
- 命令行:
mysql -u appuser -h 192.168.1.100 -p --ssl-mode=REQUIRED - JDBC URL:
?useSSL=true&requireSSL=true&enabledTLSProtocols=TLSv1.2(旧驱动用usessl=true无效) - PHP mysqli:连接时传入
MYSQLI_CLIENT_SSL标志 - PDO DSN:
sslmode=require或完整指定证书路径 - 注意:
--ssl-mode=VERIFY_IDENTITY要求证书 CN 匹配连接地址,自签名证书 CN 多为localhost,连 IP 就会失败
最容易被忽略的是:服务端 have_ssl = YES 和客户端 --ssl-mode=REQUIRED 必须同时满足,缺一不可;而 require_secure_transport = ON 是另一层全局开关,它会直接拒绝所有未加密的 TCP 连接,但不影响 Unix socket 连接。











