确认 MySQL 是否支持 SSL
安装完 MySQL 后,不能直接假设 SSL 已启用。先连上 MySQL,执行
SHOW VARIABLES LIKE 'have_ssl';或
SHOW VARIABLES LIKE 'ssl_mode';。如果返回值是
DISABLED或
NO,说明 OpenSSL 库未加载或配置缺失——这和是否安装了 OpenSSL 无关,而是 MySQL 启动时没找到证书路径或权限不对。
常见错误现象:
mysql -u root -p --ssl-mode=REQUIRED连接失败,报错
SSL connection error: protocol version mismatch或直接退回非加密连接,基本都是这个原因。 检查
mysqld进程是否带
--ssl参数启动(
ps aux | grep mysqld) 确认 OpenSSL 版本兼容:MySQL 8.0.28+ 推荐 OpenSSL 1.1.1+;低于该版本可能不支持 TLSv1.3 Linux 上若用包管理器安装(如 apt/yum),默认通常不生成证书,需手动创建或指定路径
生成 PEM 格式证书和私钥文件
MySQL 要求证书为 PEM 格式,且私钥不能加密(即无密码)。用 OpenSSL 生成时必须避开交互式密码输入,否则 MySQL 启动会卡住。
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \ -keyout /var/lib/mysql/server-key.pem \ -out /var/lib/mysql/server-cert.pem \ -subj "/CN=localhost"
关键点:
-nodes必须存在,否则私钥带密码,MySQL 无法自动读取 路径建议放在
/var/lib/mysql/(数据目录内),避免 SELinux 或 AppArmor 拒绝访问 文件权限必须是
mysql:mysql且私钥权限设为
600:
chown mysql:mysql /var/lib/mysql/server-*.pem && chmod 600 /var/lib/mysql/server-key.pem不要用
ca.pem做客户端验证时,除非你真需要双向认证;单向加密只需
server-cert.pem+
server-key.pem
修改 my.cnf 并重启 mysqld
在
[mysqld]段落中添加证书路径,不是
[client]或
[mysql]—— 那些只影响客户端行为,服务端 SSL 由
mysqld进程控制。
[mysqld] ssl_ca=/var/lib/mysql/server-cert.pem ssl_cert=/var/lib/mysql/server-cert.pem ssl_key=/var/lib/mysql/server-key.pem
注意:
ssl_ca在单向加密中可指向和
ssl_cert相同的文件(自签名场景),但语义上它应是 CA 证书;MySQL 8.4 开始更倾向使用
ssl_mode=REQUIRED替代旧参数 改完后运行
mysqld --validate-config检查语法,再
systemctl restart mysqld重启失败?大概率是路径错、权限错、或私钥被加密。查日志:
journalctl -u mysqld -n 50 --no-pager,重点看
SSL error行
验证连接是否走 SSL 及强制客户端加密
登录后执行
STATUS;或
SELECT * FROM performance_schema.status_by_thread WHERE VARIABLE_NAME = 'Ssl_cipher';。如果
Ssl_cipher非空,说明当前连接已加密。
要强制所有用户走 SSL,需修改用户账户:
ALTER USER 'app_user'@'%' REQUIRE SSL; FLUSH PRIVILEGES;
此时该用户用
mysql -u app_user -p会失败,必须显式加
--ssl-mode=REQUIRED。容易忽略的一点是:
localhost连接默认走 socket,不走 TCP,因此即使设了
REQUIRE SSL,本地连接仍可能绕过——测试务必用
-h 127.0.0.1或远程 IP。
另外,MySQL 8.0+ 默认
ssl_mode=DISABLED,客户端不声明就绝不加密;别指望“配完服务端就自动全量加密”。
