MySQL SSL需显式强制启用,仅配置证书不生效;用mysql_ssl_rsa_setup生成合规证书并设require_secure_transport=ON,再通过SHOW VARIABLES和Ssl_cipher验证连接加密状态。

MySQL SSL 不是配完证书就自动加密的——必须显式强制,否则客户端连上来还是明文。
用 mysql_ssl_rsa_setup 一键生成证书(MySQL 8.0+ 推荐)
这是最省事、最不容易出错的方式,MySQL 自带工具会生成合规 PEM 文件,并自动处理私钥无密码、权限 600、subjectAltName 包含 localhost 等细节。
- 先确认 MySQL 数据目录位置:
mysqld --verbose --help | grep "datadir",常见为/var/lib/mysql或/www/server/data(宝塔) - 切换到该目录并确保 MySQL 用户有写权限:
cd /var/lib/mysql && chown mysql:mysql . - 执行生成命令:
mysql_ssl_rsa_setup --datadir=/var/lib/mysql --uid=mysql - 检查生成结果:
ls -l /var/lib/mysql/*.pem,应看到ca.pem、server-cert.pem、server-key.pem三个文件,且server-key.pem权限为-rw-------(600)
手动配置 my.cnf 启用 SSL 并强制加密
只写证书路径不等于启用 SSL;不加 require_secure_transport = ON 就等于没开——客户端仍可走明文连接。
- 编辑
my.cnf(路径常见为/etc/my.cnf、/etc/mysql/my.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
mysql 用户)能读取——不能放在 /root/ 或用户家目录下systemctl restart mysqld 或宝塔面板点“重启”验证 SSL 是否真正生效,而不是只看配置
SHOW VARIABLES LIKE '%ssl%' 只告诉你“配了啥”,不是“连上了啥”。关键要看当前连接是否加密。
- 连上去执行:
mysql -u root -p -e "SHOW VARIABLES LIKE 'have_ssl'; SHOW STATUS LIKE 'Ssl_version'; SELECT * FROM performance_schema.status_by_thread WHERE VARIABLE_NAME = 'Ssl_cipher';" - 理想输出:
have_ssl = YES、Ssl_version非空(如TLSv1.3)、当前连接的Ssl_cipher字段非空(如ECDHE-ECDSA-AES128-GCM-SHA256) - 如果
have_ssl = DISABLED,常见原因是:server-key.pem权限不是 600、私钥被加密过、证书路径拼错、OpenSSL 库缺失或版本太低(尤其 Alpine 镜像可能用 WolfSSL) - 如果
Ssl_cipher为空,说明你连的是明文连接——试试加参数重连:mysql -u root -p --ssl-mode=REQUIRED
客户端连接时必须显式声明 SSL 模式
服务端开了强制加密(require_secure_transport = ON),不代表所有客户端自动走 SSL。有些旧驱动或 CLI 默认降级,必须明确指定。
- 命令行连接必须加:
mysql -u user -p --ssl-mode=REQUIRED --ssl-ca=/path/to/ca.pem - PHP PDO 示例:
$pdo = new PDO("mysql:host=localhost;port=3306;dbname=test", $user, $pass, [PDO::MYSQL_ATTR_SSL_CA => '/path/to/ca.pem', PDO::MYSQL_ATTR_SSL_MODE => MYSQLI_SSL_REQUIRED]); - Java JDBC 示例:在 URL 后加
?useSSL=true&requireSSL=true&trustCertificateKeyStoreUrl=file:/path/to/truststore - 注意:
--ssl-mode=DISABLED在服务端开启require_secure_transport = ON后会直接拒绝连接,报错类似Access denied for user ... (using password: YES)——这不是密码错,是 SSL 被拒
最容易被忽略的一点:subjectAltName 必须包含客户端实际访问的 IP 或域名,否则即使证书存在、服务端启动成功,客户端也会报 X509_V_ERR_IP_ADDRESS_MISMATCH。自签名证书用 mysql_ssl_rsa_setup 默认只覆盖 localhost,若用 127.0.0.1 或内网 IP 连,就得手动补 extfile 重新签;云环境更得提前规划好访问入口。


















