mysql如何配置SSL双向证书校验_mysql高安全级别连接

4次阅读

mysql如何配置SSL双向证书校验_mysql高安全级别连接

如何在 mysql 客户端和服务端启用双向 ssl(mTLS)

MySQL 原生支持双向 SSL,但默认不开启,且服务端必须先配置好 CA、服务端证书和私钥,客户端也必须提供有效证书——缺一不可。否则会报错 SSL connection Error: protocol version mismatch 或更常见的 access denied for user 'xxx'@'xxx' (using password: YES)(注意:这个错误可能根本不是密码问题,而是 SSL 握手失败被静默降级或拒绝)。

实操关键点:

  • 服务端必须设置 require_secure_transport = ON 强制所有连接走加密通道,否则即使配了证书,非 SSL 连接仍能成功
  • 客户端连接时必须显式指定 --ssl-mode=VERIFY_IDENTITY(或更低的 REQUIRED),不能只靠 --ssl-ca
  • CA 证书(ca.pem)在服务端和客户端必须完全一致;服务端证书(server-cert.pem)和私钥(server-key.pem)不能用自签名工具随意生成——需确保 subjectAltName 匹配服务端实际域名/IP,否则客户端校验失败

生成兼容 MySQL 的双向证书链(OpenSSL 实操要点)

MySQL 对证书格式敏感:不接受 PKCS#12,只认 PEM;私钥不能加密(即不能有 passphrase),否则启动 mysqld 时会卡住;服务端证书的 extendedKeyUsage 必须包含 serverAuth,客户端证书必须含 clientAuth

常见翻车点:

  • openssl req -x509 直接生成自签名证书 → 缺少 subjectAltName,导致客户端连接时报 ERROR 2026 (HY000): SSL connection error: Certificate verification failed
  • 私钥用 openssl genrsa -aes256 生成 → mysqld 启动失败,日志里只有模糊的 Failed to set up SSL
  • 客户端证书没加 clientAuth 扩展 → 即使证书存在,服务端日志显示 SSL error: SSL is required and the client does not support it

推荐最小可行命令流(以服务端 IP 192.168.1.10 为例):

openssl req -x509 -newkey rsa:2048 -days 3650 -nodes    -keyout ca-key.pem -out ca.pem -subj "/CN=MySQL-CA" <p>openssl req -newkey rsa:2048 -nodes -keyout server-key.pem -out server-req.pem  -subj "/CN=localhost" openssl x509 -req -in server-req.pem -days 3650 -CA ca.pem -CAkey ca-key.pem  -set_serial 01 -out server-cert.pem -extfile <(printf "subjectAltName=IP:192.168.1.10nextendedKeyUsage=serverAuth")</p><p>openssl req -newkey rsa:2048 -nodes -keyout client-key.pem -out client-req.pem  -subj "/CN=mysql-client" openssl x509 -req -in client-req.pem -days 3650 -CA ca.pem -CAkey ca-key.pem  -set_serial 02 -out client-cert.pem -extfile <(printf "extendedKeyUsage=clientAuth")

MySQL 服务端配置文件关键项(my.cnf)

只写真正影响双向校验的几项,多余参数反而引发冲突。尤其注意路径权限:MySQL 进程用户(如 mysql)必须对证书文件有读权限,且不能是 root-only 可读(chmod 600 是安全的,但 chmod 400 可能因 SELinux 拒绝)。

必须配置:

  • ssl_ca = /etc/mysql/ssl/ca.pem —— CA 证书路径,服务端和客户端共用同一份
  • ssl_cert = /etc/mysql/ssl/server-cert.pem —— 服务端证书
  • ssl_key = /etc/mysql/ssl/server-key.pem —— 服务端私钥(无密码)
  • require_secure_transport = ON —— 强制加密,这是双向校验的前提

可选但建议加:

  • tls_version = TLSv1.2,TLSv1.3 —— 禁用老旧协议,避免降级攻击

验证双向 SSL 是否真生效(不只是“连得上”)

连得上 ≠ 双向校验开启。MySQL 提供两个关键状态变量来确认:

  • 执行 SHOW STATUS LIKE 'Ssl_cipher'; —— 返回非空值(如 TLS_AES_256_GCM_SHA384)说明 SSL 已启用
  • 执行 select * FROM performance_schema.status_by_thread WHERE VARIABLE_NAME = 'Ssl_client_verify'; —— 若值为 FAILED 或空,说明客户端证书未通过校验;若为 SUCCESS,才代表双向认证完成
  • 检查服务端错误日志:成功双向握手时会有类似 SSL connection established with cipher TLS_AES_256_GCM_SHA384, peer certificate CN: mysql-client 的记录

最容易被忽略的是:客户端证书的 CNsubjectAltName 必须与 MySQL 用户的 REQUIRE X509REQUIRE SUBJECT 约束严格匹配。例如创建用户时用了 REQUIRE SUBJECT '/CN=mysql-client',那客户端证书的 subject 就必须一字不差,包括斜杠和顺序。

text=ZqhQzanResources