MySQL用户启用SSL必须显式执行CREATE USER或ALTER USER语句添加REQUIRE SSL,图形界面勾选无效;服务端需配置ssl_ca/cert/key并确保have_ssl=YES;客户端须主动指定--ssl-mode=REQUIRED等参数,否则仍走明文。
MySQL用户创建时必须显式指定 REQUIRE SSL
勾选“require ssl”只是图形化工具(如phpmyadmin、mysql workbench)的界面操作,它不会自动生效——底层必须在 create user 或 alter user 语句里写明 require ssl,否则权限不成立。
常见错误现象:SHOW GRANTS FOR 'user'@'host'; 返回结果里没有 REQUIRE SSL,即使界面上勾了也白搭。
- 正确做法:用命令行执行
CREATE USER 'api_user'@'%' IDENTIFIED BY 'pwd123' REQUIRE SSL; - 已有用户补救:用
ALTER USER 'api_user'@'%' REQUIRE SSL;,不是GRANT语句 - 注意:MySQL 8.0+ 默认认证插件是
caching_sha2_password,它和REQUIRE SSL兼容;但老版本用mysql_native_password也能用,别被插件名误导
服务端没开SSL,客户端强制SSL会直接连不上
REQUIRE SSL 是个单向约束:它只管客户端是否走加密通道,不管服务端有没有配好证书。如果 MySQL 服务本身没启用 SSL(即 have_ssl 变量为 DISABLED),那任何带 REQUIRE SSL 的用户都连不进,报错通常是:SSL connection error: protocol version mismatch 或直接拒绝连接。
- 检查服务端状态:连上 MySQL 后运行
SHOW VARIABLES LIKE 'have_ssl';,必须是YES - 关键配置项:
ssl_ca、ssl_cert、ssl_key必须在my.cnf的[mysqld]段落里指向有效文件路径,且 MySQL 进程有读取权限 - 重启 mysqld 后,再查
STATUS或SHOW STATUS LIKE 'Ssl%';看握手是否成功
客户端连接时得主动启用TLS,不能靠服务端“推”
即使用户设了 REQUIRE SSL、服务端也开了 SSL,客户端如果不声明要用加密连接,MySQL 默认仍走明文。很多 ORM 或脚本默认不启用 TLS,导致看似连得上,实则绕过了 SSL 要求。
- 命令行测试:用
mysql -u api_user -p --ssl-mode=REQUIRED,漏掉--ssl-mode就可能降级为非加密 - Python pymysql 示例:连接参数里加
ssl={'ssl': {}}或更明确的ssl={'ca': '/path/to/ca.pem'} - Node.js mysql2:设
ssl: { rejectUnauthorized: true },不设等于没开 - 注意:
--ssl-mode=DISABLED会强制跳过,哪怕用户要求 SSL,也会被服务端拒绝并报错Access denied for user ... (using password: YES)
权限变更后要重载,但不需要 FLUSH PRIVILEGES
用 ALTER USER ... REQUIRE SSL 修改后,权限立即生效,不需要 FLUSH PRIVILEGES——那是针对直接改 mysql.user 表才需要的操作。误执行反而可能干扰缓存状态。
- 验证是否生效:用另一个未授权 SSL 的客户端尝试连接,应报错
Access denied for user ... (using password: YES),而不是密码错的提示 - 容易被忽略的点:某些云数据库(如阿里云 RDS、AWS RDS)控制台修改 SSL 设置,实际是改服务端参数,不是用户权限;用户级
REQUIRE SSL还得自己跑 SQL - 调试时别只看连接是否成功,务必用
STATUS命令或查information_schema.PROCESSLIST的SSL_TYPE字段确认当前连接是否真用了 SSL











