mysql 8.0启用ssl加密传输的核心是确保mysqld真正加载证书并使have_ssl= yes;若为disabled或no,后续所有客户端配置均无效。需先验证ssl编译支持,再用sudo -u mysql运行mysql_ssl_rsa_setup生成证书,配置my.cnf中ssl_ca/cert/key绝对路径及require_secure_transport=on,最后重启mysqld并检查ssl_cipher非空。

MySQL 8.0 启用 SSL 加密传输,核心不是“生成证书”这一步,而是让 mysqld 进程真正加载并使用它们——have_ssl 返回 YES 才算生效,否则客户端无论怎么配 --ssl-mode=REQUIRED 都会失败。
确认 MySQL 编译时已启用 SSL 支持
这是最容易被跳过的前置检查。很多编译安装或精简版包(如某些 Alpine 镜像)压根没链接 OpenSSL/yaSSL。
- 登录 MySQL 执行:
SHOW VARIABLES LIKE 'have_ssl';,结果必须是YES;若为DISABLED或NO,后续所有配置都无效 - 若返回非
YES,需重装带 SSL 支持的 MySQL 包(如 Ubuntu 的mysql-server默认包含,但mysql-client单独安装不保证服务端支持) -
SHOW VARIABLES LIKE 'version_ssl_library';可查看实际使用的加密库(OpenSSL 或 yaSSL),影响证书兼容性
用 mysql_ssl_rsa_setup 生成证书但必须切换用户运行
这个工具只生成文件,不改配置、不重启、不授权,且对运行身份极其敏感——用 root 跑,生成的 server-key.pem 属主是 root,mysqld 读不了,have_ssl 就仍是 DISABLED。
- 先确认数据目录归属:
ls -ld /var/lib/mysql/,输出中属主应为mysql - 切到
mysql用户执行:sudo -u mysql mysql_ssl_rsa_setup --datadir=/var/lib/mysql - 验证生成结果:
sudo -u mysql ls -l /var/lib/mysql/*.pem,确保server-key.pem权限是-rw-------(600)且属主为mysql - 若报
Permission denied或日志里有SSL_CTX_set_default_verify_paths failed,大概率是 SELinux 拦截,临时可sudo setenforce 0排查
在 my.cnf 中配置绝对路径并重启 mysqld
配置项写错路径、漏掉 [mysqld] 段、或只 reload 不重启,都会导致证书不加载。
- 编辑
/etc/my.cnf或/etc/mysql/mysql.conf.d/mysqld.cnf,在[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 = ON
require_secure_transport = ON 是强制所有连接走 SSL 的开关,不加它,用户仍可用 --ssl-mode=DISABLED 绕过sudo systemctl restart mysql(或 mysqld),reload 不生效mysql -e "SHOW VARIABLES LIKE 'have_ssl';" 和 SHOW STATUS LIKE 'Ssl_cipher';,后者非空才表示握手层已就绪客户端连接时必须显式声明 SSL 要求
服务端开了 require_secure_transport = ON,不代表客户端自动加密——旧驱动、ORM 默认可能禁用 SSL,或连错 host 导致 CN 不匹配。
- 命令行测试:
mysql --ssl-ca=/var/lib/mysql/ca.pem -u user -p -h 192.168.1.100(注意:不加--ssl-mode时,MySQL 客户端默认行为是尝试 SSL,但失败后会降级;加--ssl-mode=REQUIRED才强制) - 如果报
SSL connection error: certificate verify failed,大概率是客户端连接用的 host(如127.0.0.1)和证书里Subject CN或subjectAltName不一致——mysql_ssl_rsa_setup生成的证书默认含localhost和127.0.0.1,但不含0.0.0.0或具体 IP,连 IP 时需确认证书是否覆盖 - Python
mysql-connector-python等库需显式传参:ssl_disabled=False或ssl_mode='REQUIRED',不能依赖服务端配置自动生效
最关键的卡点永远在服务端:have_ssl=DISABLED 时,所有客户端操作都是徒劳。务必先用 sudo -u mysql 验证文件可读、路径绝对、重启到位,再调客户端。











