必须先启用服务端SSL(have_ssl=YES且证书路径有效、权限正确),再创建/修改用户时加REQUIRE SSL,客户端还需显式指定--ssl-mode=REQUIRED等参数才能完成TLS握手并验证加密生效。

直接给用户加 REQUIRE SSL 不会强制加密连接——服务端 SSL 没真正启用时,这条语句只是存进表里,连 TLS 握手都触发不了,客户端连不上,报错看着像权限拒绝,实际是协议层被拦在门外。
确认 MySQL 服务端 SSL 已真正启用
这是所有操作的前提。跳过这步,后续全白忙。
-
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 拦截读取、路径写在[client]段而非[mysqld]段 - 查错误日志:
grep -i "ssl\|error" /var/log/mysql/error.log,常有Failed to set up SSL because of SSL library error类提示
给用户添加 REQUIRE SSL 权限的正确方式
服务端 SSL 启用后,REQUIRE SSL 才真正起作用。它只控制该用户的连接是否必须加密,不提供双向认证。
- MySQL 5.7 支持对已有用户执行:
ALTER USER 'appuser'@'10.0.2.%' REQUIRE SSL; - 执行后必须运行:
FLUSH PRIVILEGES;,否则旧连接可能仍缓存旧权限状态 - 验证是否生效:
SELECT user, host, ssl_type FROM mysql.user WHERE user = 'appuser';,ssl_type应为ANY - 注意:
REQUIRE SSL对localhost或 Unix socket 连接无效——本地连接不走 TCP,不参与 TLS 握手
客户端必须显式启用 SSL 模式才能完成握手
即使用户设了 REQUIRE SSL,客户端不主动发起 TLS 握手,连接仍会被拒绝——这不是认证失败,是协议层被拦在门外。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 命令行连接必须加参数:
mysql -u appuser -h 192.168.1.100 -p --ssl-mode=REQUIRED(MySQL 5.7 中--ssl已弃用,行为不一致) - JDBC URL 需完整声明:
?useSSL=true&requireSSL=true&enabledTLSProtocols=TLSv1.2(旧驱动用usessl=true无效) - PHP PDO 连接需在 DSN 中加入
;sslmode=require或指定证书路径 - 连接成功后执行
STATUS;,看 “SSL” 行是否显示 cipher 名(如TLS_AES_256_GCM_SHA384)
require_secure_transport=ON 才是真正的全局强制开关
仅靠 REQUIRE SSL 无法阻止其他用户明文连接——它只约束特定账号;要彻底禁用所有未加密 TCP 连接,必须开启此全局开关。
- 必须写在
my.cnf的[mysqld]段中,值只能是ON或OFF,重启生效 - 设为
ON后,mysql -u user -p(无 SSL 参数)会直接报错:ERROR 3159 (HY000): Connections using insecure transport are prohibited while --require_secure_transport=ON. - Unix socket 连接(如
mysql -u root -S /var/run/mysqld/mysqld.sock)不受此限制,这是设计行为 - 该参数依赖底层 SSL 能力:若
have_ssl不是YES,mysqld 启动时会报错退出或静默忽略配置
最容易被忽略的是:证书路径必须是绝对路径、私钥权限必须为 600、且 mysqld 进程必须能真实读取——任何一环权限或路径出错,都会导致 have_ssl 显示 YES 实际却无法握手。别只看变量值,要结合 STATUS; 和错误日志交叉验证。










