MySQL 8.0+ 启用 SSL 的最低必要配置是:在 my.cnf 的 [mysqld] 段设置 ssl_ca、ssl_cert、ssl_key 路径,并启用 require_secure_transport = ON;证书需满足无密码私钥、PEM 格式、同 CA 签发且 subjectAltName 包含访问域名或 IP;重启 mysqld 后验证 Ssl_cipher 非空。

MySQL 8.0+ 启用 SSL 的最低必要配置
MySQL 默认不启用 SSL,即使你生成了证书,ssl_mode 仍为 DISABLED。必须显式开启服务端强制加密,否则客户端连上来还是走明文。
- 编辑
my.cnf(通常在/etc/mysql/my.cnf或/etc/my.cnf),在[mysqld]段落下加:
[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=ON更可靠 - 证书路径必须是 MySQL 进程有读权限的路径(不能放在
/root/下) - 改完重启
mysqld,别只 reload —— SSL 配置不支持热加载
用 openssl 生成兼容 MySQL 的证书链
MySQL 对证书格式敏感:要求私钥无密码、PEM 格式、CA 和 server 证书需用相同 CA 签发,且 subjectAltName 必须包含服务端实际访问域名或 IP(否则客户端会报 X509_V_ERR_IP_ADDRESS_MISMATCH)。
- 生成 CA 私钥和自签名证书(只需一次):
openssl genrsa 2048 > ca-key.pem openssl req -new -x509 -nodes -days 3650 -key ca-key.pem -out ca.pem
- 生成服务端私钥和 CSR(注意:-subj 中的 CN 要写对,但真正起作用的是下一步的
subjectAltName):
openssl req -newkey rsa:2048 -days 3650 -nodes -keyout server-key.pem -out server-req.pem -subj "/CN=localhost"
- 用配置文件补全
subjectAltName(例如服务通过127.0.0.1和mysql.example.com访问):
echo "subjectAltName=IP:127.0.0.1,DNS:mysql.example.com" > ext.cnf openssl x509 -req -in server-req.pem -days 3650 -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile ext.cnf
- 最后把
server-key.pem去掉密码(MySQL 不接受加密私钥):openssl rsa -in server-key.pem -out server-key.pem
验证 SSL 是否真生效:别只信 status
执行 SHOW VARIABLES LIKE '%ssl%'; 只能看服务端配了啥,不代表连接已加密。真正要看的是当前连接的加密状态。
- 连接后立刻查:
SELECT * FROM performance_schema.status_by_thread WHERE variable_name = 'Ssl_cipher'; - 或者更直接:
STATUS;(即 \s),看输出里有没有SSL: Cipher in use is ... - 常见假阳性:客户端用
--ssl-mode=REQUIRED连上了,但服务端没开require_secure_transport,此时其他未加 SSL 参数的客户端仍可明文连入 - 如果看到
Ssl_cipher为空或NULL,说明该连接没走 SSL —— 即使have_ssl = YES
Java / Python 客户端连 SSL MySQL 的典型坑
很多客户端库默认不校验服务端证书,或默认不启用加密,光靠服务端强制还不够,得两边对齐。
- Python(PyMySQL):必须显式传
ssl={'ca': '/path/to/ca.pem'},否则即使服务端强制,PyMySQL 也会静默降级到非 SSL(除非加ssl_disabled=False) - Java(MySQL Connector/J 8.0+):URL 加
?useSSL=true&requireSSL=true&verifyServerCertificate=true,且trustCertificateKeyStoreUrl必须指向含 CA 的 JKS 或 PKCS12;用 PEM 要转成 JKS,别直接丢ca.pem - MySQL 命令行客户端:
mysql --ssl-mode=VERIFY_IDENTITY --ssl-ca=ca.pem -h mysql.example.com,漏掉--ssl-mode就可能跳过验证 - 特别注意:MySQL 8.0.28+ 默认禁用 sha256_password 插件,若用户用的是老式认证方式,SSL 连接会失败,需先
ALTER USER ... IDENTIFIED WITH caching_sha2_password
证书路径权限、subjectAltName 缺失、客户端未主动声明 SSL 模式——这三处出问题的概率加起来超过八成。其他都是细节微调。


















