MySQL 8.0 默认不启用双向SSL,必须同时满足服务端启用SSL(have_ssl=YES)、用户设REQUIRE X509、客户端显式提供ca.pem/client-cert.pem/client-key.pem三者,缺一则降级为单向加密或拒绝连接。

MySQL 8.0 默认不启用双向 SSL(即客户端证书验证),必须显式配置服务端校验 + 客户端提供有效证书,缺一不可;否则连接仍为单向加密或直接拒绝。
确认服务端已启用 SSL 且支持 client certificate 验证
只靠 require_secure_transport = ON 不够——它只强制 TLS 加密,不验证客户端身份。真正启用双向认证需满足两个前提:
-
have_ssl必须为YES(不是DISABLED),否则所有 SSL 相关参数都被忽略 -
tls_version至少含TLSv1.2,且服务端未禁用verify_ca或verify_identity类逻辑(MySQL 本身不内置 CA 链校验开关,但依赖 OpenSSL 行为) - 检查
SHOW VARIABLES LIKE 'ssl_mode';—— 若为PREFERRED或REQUIRED,说明服务端未要求客户端证书;双向认证实际由客户端证书是否被服务端接受决定,MySQL 本身不暴露“client cert required”开关,而是靠REQUIRE X509用户权限触发
生成 client-cert.pem 和 client-key.pem 的正确方式
MySQL 自带的 mysql_ssl_rsa_setup 默认不生成客户端证书。必须手动用 OpenSSL 补全,且关键点在于:CA 必须与服务端一致、subjectAltName 无需填客户端 IP(但 CN 可任意)、私钥绝不能加密。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 复用已有的
ca.pem和ca-key.pem(若用mysql_ssl_rsa_setup生成,它们默认不在数据目录,需先提取或重生成) - 生成客户端私钥(无密码):
openssl genrsa -out client-key.pem 2048 - 生成 CSR 并签名(注意用同一 CA):
openssl req -new -key client-key.pem -out client-req.pem -subj "/CN=client"→openssl x509 -req -in client-req.pem -days 3650 -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem - 验证客户端证书可用:
openssl verify -CAfile ca.pem client-cert.pem应返回OK - 客户端私钥权限必须是
-rw-------(600),且属主为运行客户端的用户(如部署应用的app用户)
创建 REQUIRE X509 用户并绑定证书信息
MySQL 的双向认证本质是“服务端验证客户端证书是否由指定 CA 签发”,不校验具体 CN 或 subjectAltName,因此只需用户权限设为 REQUIRE X509,无需指定 ISSUER 或 SUBJECT(除非你有强身份绑定需求)。
- 新建用户:
CREATE USER 'bi_user'@'%' IDENTIFIED BY 'pwd' REQUIRE X509; - 已有用户(MySQL ≥ 8.0.22):
ALTER USER 'bi_user'@'%' REQUIRE X509; - 验证生效:
SELECT user, host, ssl_type FROM mysql.user WHERE user = 'bi_user';→ssl_type应为X509 - 注意:
REQUIRE SSL和REQUIRE X509不等价——前者只要求加密通道,后者才强制客户端提供并验证证书
客户端连接时必须同时传入 ca.pem + client-cert.pem + client-key.pem
命令行或 JDBC 连接若漏掉任一文件,会报错 SSL connection error: SSL is required and the server doesn't support it 或静默降级为单向加密(取决于服务端配置)。
- mysql 命令行示例:
mysql -u bi_user -p --ssl-mode=VERIFY_IDENTITY --ssl-ca=ca.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem -h 192.168.1.100 - JDBC URL 示例:
jdbc:mysql://192.168.1.100:3306/test?useSSL=true&requireSSL=true&verifyServerCertificate=true&clientCertificateKeyStoreUrl=file:/path/to/keystore.jks&trustCertificateKeyStoreUrl=file:/path/to/truststore.jks(Java 推荐转成 JKS,但原生 PEM 也可用sslCert/sslKey参数) - 常见错误:
SSL error: Unable to get private key→ 检查client-key.pem是否被密码保护(MySQL 不接受)或权限 >600 - 测试是否真为双向:
STATUS命令后看Current pager下的Ssl_cipher非空,再查SELECT * FROM performance_schema.status_by_thread WHERE variable_name = 'Ssl_client_certificate';—— 若为空,说明客户端证书未提交或服务端未校验
双向 SSL 的核心复杂点不在服务端配置,而在于 CA 信任链一致性与客户端证书分发管理;一旦服务端 REQUIRE X509 生效,任何没配对证书的客户端连接都会被拒绝,且错误提示模糊(常表现为连接超时或权限拒绝),务必用 mysql --ssl-mode=DISABLED 先排除网络和基础认证问题。

















