MySQL强制启用TLS需客户端显式声明ssl-mode=REQUIRED等参数,服务端设require_secure_transport=ON并配置tls_version,验证须查STATUS或SHOW STATUS中SSL字段。

MySQL 连接加密协议怎么强制启用 TLS
不配 TLS,mysql 客户端连上去默认走明文——哪怕服务端支持 TLS,客户端不声明,照样不加密。必须显式要求,不能靠“服务端开了就自动用”。
-
mysql --ssl-mode=REQUIRED -u user -p是最简验证方式;不加这个参数,即使服务端配置了证书,连接也走非加密通道 - 应用层(如 Python 的
pymysql、Go 的mysql驱动)必须显式设置ssl_disabled=False或传入ssl={'ca': '/path/to/ca.pem'},否则 TLS 不生效 - 服务端
require_secure_transport=ON可全局拦截非加密连接,但要注意:旧客户端(如 MySQL 5.7 默认编译选项)可能因缺少 SSL 库直接报错SSL connection error: protocol version mismatch
MySQL 支持哪些 TLS 版本?怎么限制最低版本
MySQL 8.0.16+ 才真正支持通过配置项控制 TLS 协议版本;早于这个版本只能靠 OpenSSL 底层限制,不可控且易出错。
- 服务端配置文件中加
tls_version=TLSv1.2,TLSv1.3(注意逗号无空格),MySQL 会拒绝低于 TLSv1.2 的握手请求 - 若设为
tls_version=TLSv1.3,MySQL 8.0.28+ 才完全稳定;低版本在某些 OpenSSL 组合下会 fallback 失败,导致连接中断 - 客户端不匹配时典型报错是:
SSL connection error: Unsupported protocol或SSL handshake failed,不是证书问题,而是协议协商失败 - 别依赖
openssl version判断——MySQL 编译时链接的 OpenSSL 版本才决定支持范围,可用SELECT VERSION(), @@version_compile_ssl;查看实际绑定情况
为什么开了 TLS 还被提示 “Insecure connection”
不是没启 TLS,而是证书链或验证方式没对上。MySQL 默认只校验证书签名,不校验域名、有效期或 CA 信任链,除非你主动要求。
- 客户端加
--ssl-mode=VERIFY_IDENTITY才会校验服务端证书中的Common Name或SAN是否匹配连接地址;否则即使证书过期、自签、域名不符,连接也成功 - Java 应用常见坑:
useSSL=true&requireSSL=true不等于加密生效,必须加上verifyServerCertificate=true并提供trustCertificateKeyStoreUrl - 用
mysql_config_editor存密码时,它不保存 SSL 设置,login-path里没有ssl-mode字段,得单独传参
配置后如何验证 TLS 真正生效
别信日志里那句 “SSL enabled”,要看实际协商结果和流量特征。
- 连接后执行
STATUS;,关注输出里的SSL:行,显示Cipher in use is TLS_AES_256_GCM_SHA384类似内容才算真走 TLSv1.3 - 服务端查
SHOW STATUS LIKE 'Ssl_cipher%';,Ssl_cipher非空且Ssl_version显示具体协议版本(如TLSv1.3)才可信 - 抓包验证最硬核:用
tshark -i lo port 3306 -Y ssl.handshake.type==1看 Client Hello 里的supported_versions扩展,确认客户端发的是 TLSv1.3 - 容易忽略的一点:MySQL Router、ProxySQL 等中间件若未配置 TLS 终止或透传,会把加密连接降级成明文转发,得单独检查它们的 TLS 设置










