MySQL启用SSL需服务端生成证书、配置my.cnf并设require_secure_transport=ON;客户端须用VERIFY_CA模式验证CA证书;连接后需通过STATUS或查询Ssl_cipher确认加密生效。

MySQL 服务端 SSL 证书生成与启用
MySQL 要支持 SSL 加密连接,必须先在服务端生成或配置有效的证书文件,并在 my.cnf 中显式启用。不启用就等于没配,客户端即使强制要求 SSL 也会被拒绝。
- 证书路径必须由 MySQL 进程可读(常见坑:SELinux 或文件权限阻止 mysqld 读取
ca.pem/server-cert.pem/server-key.pem) - 推荐用 OpenSSL 一次性生成三件套:
openssl req -x509 -newkey rsa:4096 -days 3650 -nodes -keyout server-key.pem -out server-cert.pem -subj "/CN=localhost",再用openssl x509 -in server-cert.pem -out ca.pem -signkey server-key.pem补全 CA 文件 - 配置段加在
[mysqld]下:ssl_ca = /var/lib/mysql/ca.pem
,其中
ssl_cert = /var/lib/mysql/server-cert.pem
ssl_key = /var/lib/mysql/server-key.pem
require_secure_transport = ONrequire_secure_transport = ON是强制所有连接走加密通道的关键开关
客户端连接时如何验证服务器证书
只服务端配了 SSL 不够,客户端默认不校验证书,容易被中间人劫持。真正安全的连接必须让客户端主动验证 CA 签发链。
- 命令行连接加
--ssl-mode=VERIFY_CA并指定 CA 文件:mysql -u user -p --ssl-ca=/path/to/ca.pem --ssl-mode=VERIFY_CA - 若用 Python 的
pymysql,需传入ssl={'ca': '/path/to/ca.pem'};用mysql-connector-python则设ssl_disabled=False, ssl_ca='/path/to/ca.pem' -
ssl-mode=REQUIRED仅加密不验证,等同于明文风险;VERIFY_IDENTITY更进一步校验主机名,但要求证书CN或subjectAltName匹配实际连接地址
检查当前连接是否真的走 SSL
很多用户以为连上了就安全了,其实可能 fallback 到非加密连接。必须实时确认会话级加密状态。
- 登录后执行
STATUS;,看输出里SSL:行是否显示Cipher in use is ... - 更可靠的是查会话变量:
SHOW VARIABLES LIKE 'have_ssl';(服务端是否支持)和SELECT * FROM performance_schema.status_by_thread WHERE variable_name = 'Ssl_cipher'; - 如果
Ssl_cipher为空字符串,说明当前连接未启用 SSL,哪怕全局配置都开着——常见于客户端没传证书参数或服务端require_secure_transport未开启
常见报错与绕过陷阱
SSL 配置出问题时错误信息往往模糊,重点盯住几个典型提示。
-
SSL connection error: protocol version mismatch:客户端和服务端 TLS 版本不兼容,MySQL 8.0.16+ 默认禁用 TLSv1.0/TLSv1.1,需确保客户端支持 TLSv1.2+ -
ERROR 9002 (HY000): SSL connection is required:服务端开了require_secure_transport,但客户端没带 SSL 参数,不能靠加--skip-ssl绕过,那是自废武功 - 使用 Docker 或云数据库时,
localhost连接常走 socket 而非 TCP,SSL 不生效;应改用127.0.0.1强制走网络栈
证书不是配完就一劳永逸的,CA 过期、密钥泄露、TLS 协议升级都会让加密形同虚设。每次变更后务必用真实客户端复测,别只信配置文件里那几行。










