MySQL启用SSL的必要条件是生成并加载ca.pem、server-cert.pem、server-key.pem三类证书文件,且私钥权限须为600;配置需在[mysqld]段,重启生效,通过SHOW VARIABLES和STATUS验证是否真正启用。

MySQL 服务端启用 SSL 的必要条件
MySQL 5.7.10+ 默认支持 SSL,但不默认启用;低于该版本需确认是否编译时启用了 openssl。关键不是“能不能”,而是“有没有生成并加载有效的证书文件”。常见错误现象是客户端报错 SSL connection error: protocol version mismatch 或 Access denied for user ... (using password: YES)(实际是 SSL 握手失败被降级拒绝)。
- 必须在 MySQL 启动前准备好三类文件:
ca.pem(CA 证书)、server-cert.pem(服务端公钥)、server-key.pem(服务端私钥)
- 私钥文件权限必须严格:MySQL 进程用户(如
mysql)需可读,且不能被组或其他用户访问(Linux 下建议 chmod 600 server-key.pem)
- 配置项写在
my.cnf 的 [mysqld] 段,不是 [client] 或 [mysql] 段
- 启用后必须重启 mysqld,
SET GLOBAL have_ssl = 'YES' 无效——这是只读状态变量,不能设
验证 SSL 是否真正生效的命令和指标
别信配置写了就完事。很多环境看似启用了,实则因证书链不完整或路径错误,导致 MySQL 启动时静默忽略 SSL 参数。
- 连上 MySQL 后执行:
SHOW VARIABLES LIKE 'have<em>ssl';</em> 和 SHOW VARIABLES LIKE 'ssl%';,重点看 ssl_ca、ssl_cert、ssl_key 是否指向真实存在的绝对路径
- 执行:
STATUS; 或 \s,观察输出中 “SSL: Cipher in use is” 是否非空;若显示 SSL: Not in use,说明当前连接未走 SSL(哪怕服务端支持)
- 检查错误日志(
mysqld.log),搜索 SSL 或 error,常有类似 Failed to set up SSL because of SSL library error 的提示,直接暴露证书格式或权限问题
客户端强制走 SSL 的三种典型方式及差异
服务端开了 SSL,不代表客户端会自动用。不显式要求,连接仍走明文——这是最常被忽略的安全盲区。
- 命令行连接加参数:
mysql -u user -p --ssl-mode=REQUIRED(MySQL 8.0+ 推荐)或旧版的 --ssl(5.7 中已弃用,行为不一致)
- JDBC URL 中添加参数:
?useSSL=true&requireSSL=true&verifyServerCertificate=false(开发测试可用,生产应设 verifyServerCertificate=true 并配 trustCertificateKeyStoreUrl)
- 用户级强制(推荐生产用):
ALTER USER 'user'@'%' REQUIRE SSL;,之后该用户任何连接都必须满足 SSL,否则直接拒绝,比应用层控制更可靠
自签名证书在生产环境的实际风险与替代方案
用 openssl req -x509 生成的自签名证书能跑通流程,但无法抵御中间人攻击——客户端若不校验 CA,等于没加密意义。
-
verifyServerCertificate=false 在 JDBC 或连接字符串里等同于“信任任意证书”,和没开 SSL 几乎一样危险
- 真正起作用的是客户端加载了正确的
ca.pem 并开启校验;若用自签,就得把同一份 ca.pem 分发到所有客户端并配置信任
- 更可行的路径:用内网私有 CA(如 HashiCorp Vault PKI、OpenSSL 自建 CA)签发服务器证书,或使用 Let’s Encrypt 的泛域名证书(需定期续期 + MySQL 支持 reload 证书,8.0.22+ 可用
ALTER INSTANCE RELOAD TLS;)
ca.pem(CA 证书)、server-cert.pem(服务端公钥)、server-key.pem(服务端私钥)mysql)需可读,且不能被组或其他用户访问(Linux 下建议 chmod 600 server-key.pem)my.cnf 的 [mysqld] 段,不是 [client] 或 [mysql] 段SET GLOBAL have_ssl = 'YES' 无效——这是只读状态变量,不能设- 连上 MySQL 后执行:
SHOW VARIABLES LIKE 'have<em>ssl';</em>和SHOW VARIABLES LIKE 'ssl%';,重点看ssl_ca、ssl_cert、ssl_key是否指向真实存在的绝对路径 - 执行:
STATUS;或\s,观察输出中 “SSL: Cipher in use is” 是否非空;若显示SSL: Not in use,说明当前连接未走 SSL(哪怕服务端支持) - 检查错误日志(
mysqld.log),搜索SSL或error,常有类似Failed to set up SSL because of SSL library error的提示,直接暴露证书格式或权限问题
客户端强制走 SSL 的三种典型方式及差异
服务端开了 SSL,不代表客户端会自动用。不显式要求,连接仍走明文——这是最常被忽略的安全盲区。
- 命令行连接加参数:
mysql -u user -p --ssl-mode=REQUIRED(MySQL 8.0+ 推荐)或旧版的 --ssl(5.7 中已弃用,行为不一致)
- JDBC URL 中添加参数:
?useSSL=true&requireSSL=true&verifyServerCertificate=false(开发测试可用,生产应设 verifyServerCertificate=true 并配 trustCertificateKeyStoreUrl)
- 用户级强制(推荐生产用):
ALTER USER 'user'@'%' REQUIRE SSL;,之后该用户任何连接都必须满足 SSL,否则直接拒绝,比应用层控制更可靠
自签名证书在生产环境的实际风险与替代方案
用 openssl req -x509 生成的自签名证书能跑通流程,但无法抵御中间人攻击——客户端若不校验 CA,等于没加密意义。
-
verifyServerCertificate=false 在 JDBC 或连接字符串里等同于“信任任意证书”,和没开 SSL 几乎一样危险
- 真正起作用的是客户端加载了正确的
ca.pem 并开启校验;若用自签,就得把同一份 ca.pem 分发到所有客户端并配置信任
- 更可行的路径:用内网私有 CA(如 HashiCorp Vault PKI、OpenSSL 自建 CA)签发服务器证书,或使用 Let’s Encrypt 的泛域名证书(需定期续期 + MySQL 支持 reload 证书,8.0.22+ 可用
ALTER INSTANCE RELOAD TLS;)
mysql -u user -p --ssl-mode=REQUIRED(MySQL 8.0+ 推荐)或旧版的 --ssl(5.7 中已弃用,行为不一致)?useSSL=true&requireSSL=true&verifyServerCertificate=false(开发测试可用,生产应设 verifyServerCertificate=true 并配 trustCertificateKeyStoreUrl)ALTER USER 'user'@'%' REQUIRE SSL;,之后该用户任何连接都必须满足 SSL,否则直接拒绝,比应用层控制更可靠openssl req -x509 生成的自签名证书能跑通流程,但无法抵御中间人攻击——客户端若不校验 CA,等于没加密意义。
-
verifyServerCertificate=false在 JDBC 或连接字符串里等同于“信任任意证书”,和没开 SSL 几乎一样危险 - 真正起作用的是客户端加载了正确的
ca.pem并开启校验;若用自签,就得把同一份ca.pem分发到所有客户端并配置信任 - 更可行的路径:用内网私有 CA(如 HashiCorp Vault PKI、OpenSSL 自建 CA)签发服务器证书,或使用 Let’s Encrypt 的泛域名证书(需定期续期 + MySQL 支持 reload 证书,8.0.22+ 可用
ALTER INSTANCE RELOAD TLS;)
证书路径写错、私钥权限松、客户端不校验 CA、用户没设 REQUIRE SSL——这四点,只要漏一个,传输层加密就形同虚设。


















