MySQL不支持为单个用户指定TLS版本,因REQUIRE子句仅控制是否启用加密,不参与TLS协商;真正决定TLS版本的是服务端tls_version变量(需8.0.16+配置于my.cnf并重启)与客户端能力共同协商。

MySQL 本身不支持为单个用户指定 TLS 版本,只能通过服务端全局配置 tls_version 限制所有连接可用的协议范围。 想靠 CREATE USER ... REQUIRE SSL 或类似语法指定 TLSv1.2,会直接报错 ERROR 1064 (42000) —— 这个语法根本不存在。
为什么不能在用户级设 TLS 版本?
MySQL 的 REQUIRE 子句只控制“是否启用加密”,不参与 TLS 握手协商。它支持的值只有:SSL、X509、CIPHER、ISSUER、SUBJECT,但没有 TLSv1.2 或任何版本号关键词。TLS 协议选择完全由服务端 tls_version 和客户端能力共同决定,用户定义里写版本号是无效的。
真正起作用的配置:mysqld 的 tls_version
必须在 my.cnf 的 [mysqld] 段设置,且仅 MySQL 8.0.16+ 支持该参数可写;低于此版本该变量只读,改了也无效。
-
tls_version = TLSv1.2,TLSv1.3—— 逗号分隔、绝对不能有空格,否则 mysqld 启动失败 - MySQL 8.0.28+ 已彻底移除 TLSv1/TLSv1.1 支持,即使写进配置也会被忽略
- 若只配
TLSv1.3,需确认客户端 OpenSSL ≥ 1.1.1、Java ≥ 11、Python ≥ 3.10,否则握手失败 - 修改后必须重启
mysqld,SET GLOBAL tls_version = ...不生效
验证是否真用了指定 TLS 版本
只查 SHOW GLOBAL VARIABLES LIKE 'tls_version' 不够——它只说明“允许哪些”,不代表当前连接用了哪个。
- 连接后执行
STATUS;,在输出中找SSL:行,例如SSL: Cipher in use is TLS_AES_256_GCM_SHA384→ 表示实际用了 TLSv1.3 - 或查性能表:
SELECT VARIABLE_VALUE FROM performance_schema.status_by_thread WHERE THREAD_ID = CONNECTION_ID() AND VARIABLE_NAME = 'Ssl_version'; - 客户端不匹配时典型报错:
SSL connection error: Unsupported protocol或protocol version mismatch,不是证书问题,而是协议协商失败
配套必须做的两件事
光设 tls_version 不足以强制 TLS 连接,还必须:
- 开启
require_secure_transport = ON(MySQL 5.7.19+),否则非加密连接仍能成功 - 确保已正确配置证书路径:
ssl_ca、ssl_cert、ssl_key,且文件权限为mysql用户可读;否则require_secure_transport会静默失效
最常被忽略的是:客户端必须主动声明加密需求,比如 mysql --ssl-mode=REQUIRED,否则哪怕服务端全配好了,连接依然走明文。











