MySQL SSL加密需同时满足have_ssl=YES、require_secure_transport=ON、客户端显式指定--ssl-mode=REQUIRED三条件,缺一则静默降级明文;首要验证have_ssl=YES,再确保证书路径绝对、权限600、含subjectAltName,最后强制全局加密。

MySQL SSL 不是配完证书就自动加密的——漏掉任一硬性条件,连接都会静默降级为明文。
确认 have_ssl = YES 是第一道生死线
很多配置看似完整,但连接仍是明文,根本卡在这一步:MySQL 启动时压根没加载 SSL 模块。执行 SHOW VARIABLES LIKE 'have_ssl',返回值必须是 YES;若为 DISABLED 或空,后续所有操作都无效。
- 常见原因包括:
server-key.pem权限不是 600、私钥被加密过、my.cnf里证书路径写错、OpenSSL 库缺失(尤其 Alpine 镜像)、或 MySQL 编译时未启用 SSL 支持(如 MariaDB 精简版) - 顺带检查
SHOW VARIABLES LIKE 'tls_version',确认支持的协议(如TLSv1.2),旧客户端连不上时可能需临时放宽,但不建议长期开启TLSv1.0 - 若为
DISABLED,重装官方二进制包比自行编译修复更稳妥
证书路径、权限、格式三者必须同时满足
MySQL 对证书极其挑剔:只认绝对路径、只读 PEM 格式、且严格校验文件权限。相对路径、~/、权限 >600 的私钥都会导致启动失败或连接被拒。
- 优先用内置工具生成(MySQL 8.0+):
mysql_ssl_rsa_setup --datadir=/var/lib/mysql --uid=mysql,它自动处理CN、subjectAltName、权限等细节 - 证书必须放在 MySQL 进程有读权限的目录,例如
/var/lib/mysql/ca.pem,不能放/root/或用户家目录下 - 检查权限:
sudo -u mysql ls -l /var/lib/mysql/server-key.pem,必须是-rw-------(即 600) - 若服务需通过
127.0.0.1和db.example.com访问,server-cert.pem的subjectAltName必须显式包含这两项
require_secure_transport = ON 是强制开关,不是可选项
仅在 [mysqld] 段配置 ssl_ca、ssl_cert、ssl_key 不等于启用加密——客户端仍可走明文连接。必须加 require_secure_transport = ON 才真正拒绝非 SSL 连接。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 配置示例(只能写在
[mysqld]段):ssl_ca = /var/lib/mysql/ca.pem<br>ssl_cert = /var/lib/mysql/server-cert.pem<br>ssl_key = /var/lib/mysql/server-key.pem<br>require_secure_transport = ON
- 改完必须执行
systemctl restart mysqld(不是reload),因为 SSL 参数只在启动时加载 - 重启失败?优先检查
server-key.pem权限是否为 600,再查 MySQL 错误日志:journalctl -u mysqld -n 50 -f - 如果启用了
require_secure_transport = ON,所有未走 SSL 的连接会直接拒绝,测试前务必确认客户端已准备就绪
验证当前连接是否真加密,而不是只看配置
SHOW VARIABLES LIKE '%ssl%' 只告诉你“配了啥”,不是“连上了啥”。关键要看当前连接是否加密:
- 登录后执行:
mysql -u root -p -e "SELECT Ssl_cipher FROM performance_schema.status_by_thread WHERE THREAD_ID = CONNECTION_ID();",返回非空值才表示当前连接已加密 - 更直接的方式:
mysql -u root -p -e "STATUS" | grep "SSL:",输出应为SSL: Cipher in use is ... - 注意:
localhost连接默认走 Unix socket,绕过所有 SSL 限制;测试务必用127.0.0.1或远程 IP - 客户端连接必须显式声明
--ssl-mode=REQUIRED,否则即使服务端强制,也会因握手未发起而失败
最容易被忽略的是:服务端配置、用户权限(REQUIRE SSL)、客户端参数三者缺一不可,且顺序不能颠倒——先确保 have_ssl = YES,再配证书路径和 require_secure_transport,最后才设用户策略和客户端连接方式。任何环节跳步,都会让加密形同虚设。










