MySQL 8.0+ 启用SSL需三步:编译支持(have_ssl= YES)、服务端配置ssl_ca/cert/key绝对路径并重启、客户端显式设置ssl_mode;证书须PEM无密钥,CN匹配连接地址。

MySQL 8.0+ 启用 SSL 的最低可行配置路径
MySQL 默认不启用 SSL,即使你生成了证书,ssl_mode 仍为 DISABLED。必须显式开启服务端 SSL 支持,并验证实际生效状态,否则客户端强制加密会直接失败。
- 先确认 MySQL 编译时已启用 SSL:
SHOW VARIABLES LIKE 'have_ssl';返回YES才能继续 - 服务端启动时需加载三类文件:
ssl_ca(CA 证书)、ssl_cert(服务器证书)、ssl_key(服务器私钥),路径必须绝对且 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
- 配置后必须重启 mysqld,仅 reload 不生效;检查是否启用:
SHOW VARIABLES LIKE 'ssl%';中ssl_cipher非空即表示成功
用 OpenSSL 生成兼容 MySQL 的 PEM 格式证书链
MySQL 要求 CA、服务器证书、私钥均为 PEM 格式,且私钥不能加密(即无密码)。常见错误是用 openssl req -newkey rsa:2048 -nodes 生成带密码的 key,或混淆 DER/PEM 编码。
- 生成 CA 私钥和自签名证书(只做一次):
openssl genrsa 2048 > ca-key.pem openssl req -new -x509 -nodes -days 3650 -key ca-key.pem -out ca.pem
- 生成服务器私钥(务必加
-nodes):openssl genrsa -nodes 2048 > server-key.pem
- 生成服务器证书请求并签发(注意 CN 不能为 localhost,建议填域名或 IP):
openssl req -new -key server-key.pem -out server-req.pem openssl x509 -req -in server-req.pem -days 3650 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem
- 验证证书匹配性:
openssl x509 -noout -text -in server-cert.pem | grep -A1 "Subject Public Key Info"和openssl rsa -noout -text -in server-key.pem | grep -A1 "modulus"输出前几行应一致
客户端连接时强制 SSL 加密的三种方式及区别
“强制加密”不是单靠服务端配置就能实现的,客户端必须明确声明 SSL 要求,否则仍走明文。MySQL 客户端行为由 ssl_mode 参数控制,不同值语义差异极大。
-
--ssl-mode=REQUIRED:最常用,只要服务端支持 SSL 就加密,但不校验证书(易受中间人攻击) -
--ssl-mode=VERIFY_CA:校验服务端证书是否由指定 CA 签发,需配合--ssl-ca=/path/to/ca.pem -
--ssl-mode=VERIFY_IDENTITY:除 VERIFY_CA 外,还校验证书中 CN 或 SAN 是否匹配连接目标地址(如mysql -h db.example.com要求证书含该域名) - 应用层连接字符串示例(Python PyMySQL):
ssl={'ca': '/path/to/ca.pem', 'check_hostname': True},此时ssl_mode隐含为VERIFY_IDENTITY - 注意:MySQL 8.0.22+ 默认
ssl_mode=REQUIRED,但老版本或 Docker 镜像可能仍为DISABLED,必须显式指定
常见连接失败原因与快速排查顺序
报错信息看似相似,但根因完全不同。优先看客户端错误提示,再查服务端日志,不要一上来就重生成证书。
-
SSL connection error: protocol version mismatch:客户端和服务端 TLS 版本不兼容,MySQL 8.0.16+ 默认禁用 TLSv1.0,检查客户端是否太旧(如旧版 mysql CLI 或 JDBC 驱动) -
SSL connection error: SSL_CTX_set_default_verify_paths failed:客户端找不到 CA 文件,路径错或权限不足(Linux 下 MySQL 用户无法读取用户 home 目录下的文件) -
Access denied for user ... (using password: YES)且启用了require_secure_transport=ON:说明服务端已强制加密,但客户端未启用 SSL,不是密码错误 - 用
mysql --ssl-mode=DISABLED -u root -p能连上,但--ssl-mode=REQUIRED失败 → 90% 是服务端ssl_cert/ssl_key路径配置错误或文件权限不对(MySQL 进程用户需可读)
ssl_mode 必须显式设置——这三个点漏掉任意一个,都会让整个 SSL 链路静默降级到明文。


















