
给 MySQL 加把“安全锁”从零配置 SSL 加密连接的完整实操记录如果你负责的数据库还在一路裸奔那这篇文章值得你花十分钟看完。不管是内网部署还是云端托管MySQL 默认的明文传输协议就像把银行卡密码写在明信片上寄出去任何一个能抓包的人都能把你的 SQL 语句、账号密码、业务数据看得清清楚楚。我最早意识到这个问题是因为一次安全审计。当时开发环境里 MySQL 和业务服务之间走的是内网交换机大家觉得内网很安全结果测试组用 Wireshark 在出口交换机上一挂业务系统所有的增删改查、甚至数据库账号密码全都直接暴露出来了。审计报告出来之后领导拍板MySQL 必须开启 SSL 加密连接。我花了整整两天把服务端、客户端、证书体系全部捋了一遍踩了证书签名、密码套件、兼容性等一堆坑。这篇文章把我当时的完整操作过程整理出来包括 SSL 证书如何生成、MySQL 服务端怎么配置、客户端如何在命令行/Workbench/代码里连上来、以及最常见的几个 SSL 报错怎么排查。不管你是刚接触 MySQL 的新手还是已经在生产环境摸爬滚打多年的老手这套流程都能直接用。1. 先搞清楚MySQL 的 SSL 到底在保护什么1.1 明文传输的风险比你想象的要大MySQL 默认情况下客户端和服务器之间的通信是明文传输的。这意味着三点风险首先SQL 语句本身会暴露业务逻辑其次连接时发送的账号密码虽然经过哈希处理但攻击者可以抓包后离线爆破最后客户端和服务器之间传输的敏感数据比如用户手机号、身份证号、订单金额只要有人在你和数据库之间任何一个网络节点上做抓包分析所有数据都能被还原出来。很多人觉得“我在内网没事”。但现实中内网并不等于安全公司内部可能有员工机器中毒成为跳板云服务器的同物理机邻居可能做流量嗅探甚至路由器、交换机、DNS 服务本身也可能被劫持。所以不管是等保合规要求还是纯粹从安全角度出发高强度加密数据库连接都应该成为标配。1.2 MySQL SSL 加密的实现机制MySQL 的 SSL 加密是基于 TLS/SSL 协议的内部依赖 OpenSSL 库。它的工作原理可以这样理解客户端连接服务器时服务器先把数字证书发给客户端客户端验证证书的合法性然后双方协商出一个会话密钥之后所有的数据都用这个会话密钥加密传输。在这个过程中有几个核心概念证书Certificate相当于服务器的“身份证”里面包含服务器公钥、组织信息、域名等。私钥Private Key服务器自己保管的密钥用来解密客户端发来的加密数据。CACertificate Authority颁发证书的机构客户端用它来验证服务器证书是否可信。自签名证书Self-signed Certificate自己充当 CA 签发的证书测试环境常用生产环境如果预算有限也可以采用客户端需要显式信任这个 CA。MySQL 支持单向 SSL只验证服务器身份和双向 SSL客户端也要提供证书验证身份。默认配置通常只要求验证服务器证书但如果你需要做高安全等级的客户端接入认证可以要求客户端也出示证书这就是 REQUIRE X509 的场景。1.3 哪些场景建议必须开启 SSL根据我这几年的实践经验以下场景属于强烈建议开启 SSL 的数据库部署在云服务器上业务服务跨公网或跨地域访问。业务系统包含用户隐私数据如支付信息、健康信息、身份信息。公司有等保、GDPR 等合规要求。多机房、混合云环境下流量会经过第三方链路。即便是纯内网只要安全审计有要求也应该开。对于纯本地开发环境比如本机跑一个 MySQL 实例做测试开启 SSL 的优先级可以低一些但对生产环境或者任何涉及真实数据的场景别犹豫开就完了。2. 准备工作证书体系怎么搭5 分钟生成一套可用证书2.1 证书规划一套还是两套在真正敲命令之前先把证书体系想清楚。MySQL 的 SSL 配置最少需要三个文件CA 证书用于客户端校验服务器证书的真伪。服务器证书包含服务器公钥和信息发给客户端。服务器私钥服务端用来解密的私有文件。如果要做双向认证还需要额外的客户端私钥和客户端证书。生产环境建议用公司已有的企业 CA 签发或者买商业证书这样客户端系统默认信任不需要手工维护 CA。但自建 CA 更灵活可以按需求签发任意数量的服务器证书和客户端证书而且完全免费。我生产环境里用自建 CA 已经跑了三年多只要把 CA 证书分发到需要连接数据库的机器上一切都非常可控。下面这套流程全部使用 OpenSSL 工具Linux/macOS 自带Windows 上可以用 Git Bash 或者安装 OpenSSL 发行版。以 MySQL 8.0 和 Ubuntu 20.04 环境为例。2.2 生成 CA 私钥和自签名 CA 证书先从 CA 开始。CA 是整个证书体系的信任根它的私钥一定要妥善保管最好设置强密码保护。# 生成 CA 私钥2048 位带 AES256 加密 openssl genrsa -aes256 -out ca-key.pem 2048执行后会提示设置密码这个密码每次用 CA 签发证书时都要输入务必记住。接下来根据私钥生成 CA 证书openssl req -new -x509 -nodes -days 3650 \ -key ca-key.pem \ -out ca-cert.pem \ -subj /CCN/STBeijing/LBeijing/OMyCompany/CNMySQL-CA参数说明-x509表示直接生成自签名证书而不是证书请求。-days 3650表示有效期 10 年可以根据企业策略调整。-nodes表示私钥不加密CA 证书本身不需要每次用都输密码。-subj一次性设置证书主体信息避免交互式填写。2.3 生成服务器私钥和证书签名请求服务器证书关键点在于CNCommon Name和SANSubject Alternative Name必须填对这直接决定客户端连接时是否能通过主机名校验。先创建服务器私钥并生成证书签名请求CSR# 生成服务器 RSA 私钥2048 位 openssl genrsa -out server-key.pem 2048 # 生成证书签名请求 openssl req -new -key server-key.pem -out server-csr.pem \ -subj /CCN/STBeijing/LBeijing/OMyCompany/CNdb1.example.com这里的CNdb1.example.com特别注意它应该是客户端连接 MySQL 时使用的主机名。如果你通常用 IP 地址连接那建议在 SAN 里加上 IP 地址否则即使证书链是可信的客户端也可能会因为主机名不匹配而拒绝连接。现代 OpenSSL 默认以 SAN 为主要校验依据CN 只是兜底。所以创建一个扩展文件把服务器所有可能的访问方式都列入 SANcat server-ext.cnf EOF [ v3_ca ] subjectAltName DNS:db1.example.com, DNS:mysql.internal, IP:192.168.1.100 EOF2.4 用 CA 签署服务器证书接下来用 CA 私钥对证书请求进行签名openssl x509 -req -in server-csr.pem \ -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial \ -out server-cert.pem -days 825 \ -extensions v3_ca -extfile server-ext.cnf这里会要求输入 CA 私钥的密码。执行完成后会得到server-cert.pem和ca-cert.srl文件。CAcreateserial参数会生成一个序列号文件后续再用 CA 签发其他证书时要用。2.5 生成客户端证书用于双向认证如果你打算让 MySQL 用户使用REQUIRE X509方式登录那还需要客户端证书。生成过程和服务器证书几乎一样只需要把 CN 改成客户端标识即可openssl genrsa -out client-key.pem 2048 openssl req -new -key client-key.pem -out client-csr.pem \ -subj /CCN/STBeijing/LBeijing/OMyCompany/CNmysql-client-1 openssl x509 -req -in client-csr.pem \ -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial \ -out client-cert.pem -days 825生成完之后记得把文件权限收紧chmod 600 ca-key.pem server-key.pem client-key.pem chmod 644 ca-cert.pem server-cert.pem client-cert.pem chown mysql:mysql server-key.pem server-cert.pem ca-cert.pem3. 服务端配置修改 my.cnf 只需要 4 行配置3.1 配置文件怎么改拿到证书之后把三个关键文件放到 MySQL 服务器上。我习惯放在/etc/mysql/ssl/目录下这样权限管理比较清晰。然后编辑 MySQL 配置文件以 Ubuntu 系统为例文件路径通常是/etc/mysql/mysql.conf.d/mysqld.cnfCentOS/RHEL 系统则在/etc/my.cnf。在[mysqld]段下增加[mysqld] ssl-ca/etc/mysql/ssl/ca-cert.pem ssl-cert/etc/mysql/ssl/server-cert.pem ssl-key/etc/mysql/ssl/server-key.pem require_secure_transportON前面三行是必须的它们告诉 MySQL 使用哪些证书文件。最后一行require_secure_transportON是强制执行选项开启之后所有客户端连接都必须走 SSL/TLS 加密或者本地 socket任何不带加密的 TCP 连接都会被直接拒绝。注意建议先把前面三行配好确认 SSL 能正常开启之后再加最后一行强制选项。如果证书配置有误就直接开强制模式会把所有业务连接全部切断到时候数据库直接连不上生产事故就是这么来的。配置完成之后重启 MySQLsystemctl restart mysql3.2 确认 MySQL 的 SSL 是否成功启用重启之后登录 MySQL 进行检查SHOW VARIABLES LIKE have_ssl;如果显示YES说明 MySQL 已经支持 SSL。接着查看当前连接是否用了加密SHOW STATUS LIKE Ssl%;重点关注Ssl_cipher字段如果它不是空的说明当前会话的连接已经使用了加密套件。空值则说明虽然 SSL 可用但当前连接没有使用加密。也可以直接执行\s在输出信息里找到SSL:一行能看到当前连接是否使用加密以及加密套件名称。正常的输出类似SSL: Cipher in use is TLS_AES_256_GCM_SHA384看到这一行就说明 SSL 已经成功生效了。3.3 创建必须使用 SSL 的用户MySQL 的权限系统非常灵活可以精细控制哪些用户必须使用 SSL 连接。这样你可以让普通账号保持默认只让高权限的管理账号强制加密。-- 创建用户并要求 SSL CREATE USER app_user% IDENTIFIED BY StrongPass123! REQUIRE SSL; -- 如果要求客户端必须提供合法证书使用 REQUIRE X509 CREATE USER secure_client% IDENTIFIED BY StrongPass456! REQUIRE X509;REQUIRE SSL和REQUIRE X509的区别在于前者只要求连接是加密的不验证客户端证书后者要求客户端必须出示一个由受信任 CA 签发的证书能做到更严格的双向认证。这里用%做 host 通配符在生产环境要谨慎建议换成具体 IP 或者网段减少暴露面。4. 客户端连接加密不是服务端单方面的事4.1 命令行 mysql 客户端连接服务端配置好之后客户端需要显式或自动启用 SSL。MySQL 命令行客户端在 5.7.11 之后默认就会尝试使用 SSL但不强制验证服务器证书。最严谨的连接方式是显式指定 CA 证书并验证mysql -h db1.example.com -u app_user -p \ --ssl-modeVERIFY_CA \ --ssl-ca/path/to/ca-cert.pem常用--ssl-mode参数DISABLED不使用 SSL。PREFERRED首先尝试 SSL失败则降级为明文这是旧版本默认行为。REQUIRED必须使用 SSL但不验证 CA 证书。VERIFY_CA必须使用 SSL并验证服务器证书是否由受信任的 CA 签发。VERIFY_IDENTITY在VERIFY_CA的基础上还校验证书中的主机名是否与连接的主机名匹配。生产环境我强烈推荐使用VERIFY_IDENTITY但因为证书里 SAN 的配置问题新手经常在这里卡住。先用VERIFY_CA保证加密可用跑通之后再升级为VERIFY_IDENTITY。连接成功后同样执行\s查看 SSL 状态确认 cipher 存在。4.2 MySQL Workbench 连接配置GUI 工具里配置也不复杂。在 MySQL Workbench 的“管理服务器连接”页面切换到“SSL”标签页选择“不使用 SSL”之外的选项如果只是测试选Require SSL即可。如果要验证证书选Verify CA并在“CA 证书”栏中选择ca-cert.pem文件。如果要最严格的校验把 SSL 模式设为Verify Identity。Workbench 的验证方式比较直观如果证书有问题它会直接弹出错误提示不会出现命令行那种“假死”或者模糊报错的情况。不过我建议 CLI 先跑通再配置 GUI因为 CLI 的报错信息更直接。4.3 Java JDBC 连接配置Java 环境下JDBC URL 需要明确指定 SSL 参数。MySQL Connector/J 8.x 版本的写法如下String url jdbc:mysql://db1.example.com:3306/mydb ?useSSLtrue requireSSLtrue verifyServerCertificatetrue trustCertificateKeyStoreUrlfile:/path/to/truststore.jks trustCertificateKeyStorePasswordchangeit;大多数生产系统用的是密钥库方式。需要把 CA 证书导入 JKS 信任库keytool -importcert -alias mysql-ca \ -file ca-cert.pem \ -keystore truststore.jks \ -storepass changeit -noprompt另外有些老系统还在用sslMode属性的新写法注意 Connector/J 8.0.27 之后verifyServerCertificate已经改名推荐用sslModeVERIFY_CA或VERIFY_IDENTITY避免使用废弃参数出现告警。新版 Connector/J 的推荐写法String url jdbc:mysql://db1.example.com:3306/mydb ?sslModeVERIFY_CA trustCertificateKeyStoreUrlfile:/path/to/truststore.jks trustCertificateKeyStorePasswordchangeit;4.4 Python/Node.js 等其他客户端Python 的 PyMySQL 或者 mysql-connector-pythonimport pymysql conn pymysql.connect( hostdb1.example.com, userapp_user, passwordStrongPass123!, databasemydb, ssl_ca/path/to/ca-cert.pem, ssl_verify_certTrue, ssl_verify_identityTrue, ssl_disabledFalse )Node.js 的 mysql2const mysql require(mysql2/promise); const conn await mysql.createConnection({ host: db1.example.com, user: app_user, password: StrongPass123!, database: mydb, ssl: { ca: fs.readFileSync(/path/to/ca-cert.pem), rejectUnauthorized: true } });可以看到不管什么语言核心思路都是一样的指定 CA 证书路径开启校验加密连接就建立起来了。5. 验证加密是否真的生效别被“看上去加密”骗了5.1 服务端状态变量检查最直接的验证方式就是在 MySQL 内部看状态。执行SHOW GLOBAL STATUS LIKE Ssl%;关注几个指标Ssl_version当前使用的 TLS 版本比如 TLSv1.3 或 TLSv1.2如果显示 TLSv1 或 TLSv1.1说明密码套件太旧建议升级 MySQL 或调整 OpenSSL 配置。Ssl_cipher当前使用的加密套件。Ssl_accepts成功建立 SSL 连接的总次数。Ssl_client_connects客户端发起的 SSL 连接次数。如果Ssl_cipher为空但have_sslYES说明有客户端用明文连接了。结合require_secure_transportON可以完全堵住这种情况。5.2 用 tcpdump 抓包验证数据确实被加密这是最直观的验证方式眼见为实。在客户端发起连接之前在服务器上开启抓包tcpdump -i any -s 0 -w mysql-ssl.pcap port 3306 然后从客户端执行一段 SQL比如SELECT * FROM users WHERE email testexample.com;抓包完成后用 Wireshark 打开看数据包内容。如果配置正确SQL 语句的明文内容不会出现在包里只能看到 TLS 加密后的乱码。如果能在包里直接看到SELECT * FROM users...说明还是明文连接赶紧排查配置。在没有 Wireshark 的命令行环境也可以用strings直接过滤抓包文件strings mysql-ssl.pcap | grep SELECT什么都搜不到就是对的。搜到了明文 SQL就不用我多说了。5.3 从 performance_schema 检查连接加密情况MySQL 的 performance_schema 提供了更细粒度的视图可以查看每个连接是否用了加密SELECT PROCESSLIST_ID, PROCESSLIST_USER, PROCESSLIST_HOST, SSL_CIPHER, SSL_VERSION, SSL_VERIFY_MODE FROM performance_schema.threads WHERE PROCESSLIST_ID IS NOT NULL;SSL_CIPHER为空的连接就是明文连接。生产环境上跑一遍这个查询哪些客户端在用明文连接哪些在用加密连接一目了然。如果开了require_secure_transportON还有明文连接那基本可以断定这些连接走的是本地 socket 而不是 TCP。5.4 模拟一个“恶意抓包”场景为了说服团队和领导我曾做过一个演示在客户端用 TCP 明文协议直接连数据库然后在服务端 show processlist发现连接存在但 SSL cipher 为空。然后又用加密方式连接再次查看cipher 正常显示。把这个对比截图放到审计报告里比说一百句话都管用。6. 常见报错与排查实录6.1 报错[08001] SSL connection required, but not provided by server这个报错说明客户端启用了 SSL但服务器没有提供 SSL 支持。可能的原因有服务器配置文件里的 ssl-cert / ssl-key 路径不对证书加载失败。MySQL 是通过某些包管理脚本自动安装的配置目录和实际加载的配置文件路径不一致。证书文件权限不对MySQL 进程没有读取权限。排查方式# 查看 MySQL 是否支持 SSL SHOW VARIABLES LIKE have_ssl; # 查看错误日志通常在 /var/log/mysql/error.log tail -100 /var/log/mysql/error.log | grep -i ssl还有一个很隐蔽的问题Ubuntu 上 MySQL 8.0 默认会扫描/etc/mysql/conf.d/下所有.cnf文件如果你把配置写在/etc/mysql/mysql.conf.d/mysqld.cnf里但另一个配置文件也设置了ssl-cert可能会产生冲突。检查一下所有配置片段确认没有两个互相矛盾的ssl-项。6.2 报错SSL: certificate_verify_failed证书验证失败这是客户端在验证服务器证书时无法建立信任链路。原因基本是以下三种之一客户端没有指定正确的 CA 证书。指定的 CA 证书和签发服务器证书的 CA 不相符。服务器证书已经过期。排查方式# 客户端检查服务器证书的签发者信息 openssl s_client -connect db1.example.com:3306 -showcerts /dev/null 2/dev/null | grep issuer再看看本地 CA 证书信息openssl x509 -in /path/to/ca-cert.pem -noout -subject对比一下如果 issuer 对不上说明用错了 CA。6.3 报错Hostname mismatch / certificate verify failed (identity check)VERIFY_IDENTITY模式下客户端不仅验证证书链还会验证主机名。如果证书里的 CN/SAN 和你连接时使用的主机名不一致就会报这个错。解决方案有两个在证书的 SAN 里加入你连接时使用的域名或 IP。连接时使用证书里写的主机名。我遇到过最坑的情况是在云环境下MySQL 的域名解析出来是内网 IP但证书里写的是公网域名导致内网客户端反而验证失败。后来统一了证书 SAN把内网域名、内网 IP、公网域名全部列进去问题才彻底解决。6.4 报错no required SSL certificate was sent这个报错出现在使用REQUIRE X509的用户上。客户端没有提供证书或者提供的证书不被服务器信任。客户端需要在连接时指定客户端证书和私钥mysql -h db1.example.com -u secure_client -p \ --ssl-modeREQUIRED \ --ssl-ca/path/to/ca-cert.pem \ --ssl-cert/path/to/client-cert.pem \ --ssl-key/path/to/client-key.pem如果证书链没问题但还是报错检查客户端证书是否过期以及签发客户端证书的 CA 是否和 MySQL 配置的ssl-ca是同一个。6.5 报错ssl recv / 服务器不支持 SSL / SSL connection error客户端可观察到握手异常这种情况多数是协议版本不匹配或密码套件不支持。比如 MySQL 开启了 TLS 1.3但客户端的 OpenSSL 版本太老或者 JDK 版本太老不支持 TLS 1.3。Python 2 和一些老版本的 JDBC 驱动经常出现这类问题。排查方式# 查看 MySQL 支持的 TLS 版本 SHOW GLOBAL VARIABLES LIKE tls_version;如果输出TLSv1.2,TLSv1.3说明支持到 TLS 1.3。可以用openssl s_client直接测试openssl s_client -connect db1.example.com:3306 -tls1_2 /dev/null还能试探-tls1_3。如果某个版本报no protocols available说明客户端不支持。解决方案升级客户端的 OpenSSL / JDK / 驱动版本。在服务器上降低tls_version比如tls_versionTLSv1.2,TLSv1.3不建议在生产环境使用低于 TLS 1.2 的版本。检查是不是密码套件被系统的 OpenSSL 策略限制住了比如 CentOS 8 的 crypto-policy。6.6 Performance 下降加密到底吃多少性能这是我们团队当时争论最多的问题。加了 SSL 之后数据库性能几乎可以忽略不计的原因有两方面第一现代 CPU 都有 AES-NI 指令集加密是在硬件层面完成的第二相比网络 I/O 和磁盘 I/O加解密的计算开销占比很小。实测在同样的 100 万行查询下开启 SSL 前后只差约 3%-5%而且这个差异在多数场景下都感知不到。但有两个注意点在 CPU 非常古老、没有 AES-NI 指令集的机器上加密性能损耗会明显放大可能达到 10%-20%。如果连接数特别多每个连接都会进行握手握手短连接场景下 SSL 握手耗时相比普通连接会增加一些。解决方案是启用连接池减少握手次数。6.7 常见问题速查表问题现象可能原因解决思路have_sslNO证书路径配置错误或权限不对检查路径、证书格式、文件权限连接报 SSL connection required服务器没启用 SSL检查 my.cnf 配置是否被正确加载certificate_verify_failedCA 证书不匹配用 openssl 核对证书颁发链Hostname mismatchCN/SAN 与实际主机名不一致重新签发证书并加入正确 SANno required SSL certificate未提供客户端证书客户端配置 ssl-cert 和 ssl-keySSL connection errorTLS 版本或密码套件不兼容升级客户端或调整 tls_version7. 另一个容易被忽略的细节连接池和中间件怎么办如果业务系统通过连接池HikariCP、Druid、C3P0或者中间件ProxySQL、MyCat访问 MySQLSSL 配置的位置会发生变化。连接池的配置项通常和 JDBC URL 一致但有些连接池会在初始化时额外做连接校验比如connectionTestQuery这时候要确保测试查询也走同一个 SSL 环境。ProxySQL 作为代理层需要在 ProxySQL 和后端 MySQL 之间也配置 SSL。在 ProxySQL 的mysql_servers表里设置use_ssl1并指定ssl_ca、ssl_cert、ssl_key文件路径。这条链路如果不配代理到后端数据库之间仍然是明文传输等于只加密了一半前面所有努力白费。关于连接池还有一个经验不要把sslModeDISABLED和useSSLfalse随意混用Java 环境下如果驱动版本和连接池版本之间有兼容性问题可能会出现“配置没生效”的假象。连接池配置好之后务必用查询状态变量的方式验证一下不要只看配置文件。8. 证书过期与自动续期的运维方案这是我后来踩过最大的坑特别提醒大家SSL 证书是有有效期的。CA 证书 10 年有效期看起来很长服务器证书如果只签了一年到期那天业务突然连不上数据库你会非常被动。我当时把服务器证书签了 825 天约两年到期当天所有新建立的连接全部失败而连接池里老连接还在跑看起来像“间歇性故障”排查了很久才发现是证书过期。为了避免这种情况建议把证书续期纳入日常运维在证书到期前 30 天设置提醒监控系统或者 cron 脚本。准备一个续期脚本自动重新生成服务器证书并重载 MySQL。如果在云环境可以考虑用云厂商的证书生命周期管理服务自动完成签发、部署、刷新。一个简单的续期脚本思路是先备份旧证书然后再跑一遍第三节里的 openssl 签名命令覆盖新的 server-cert.pem 和 server-key.pem最后ALTER INSTANCE RELOAD TLSMySQL 8.0.21 支持在线重载 TLS 配置无需重启 MySQL。ALTER INSTANCE RELOAD TLS这个命令很实用它能在不重启 MySQL 的情况下重新加载证书文件大大减少了证书轮换对业务的影响。执行后新的连接会使用新证书存量连接不受影响。9. 从 MySQL 版本差异看配置演进不同版本的 MySQLSSL 配置行为有差异如果你管理的是多版本混合环境这点要特别留意。MySQL 5.6 及以前SSL 证书配置语法是独立的而且在编译时就要决定是否启用WITH_SSL有些发行版默认是编译了 SSL 的但有些老版本还要手动编译。MySQL 5.7 开始默认编译开启 SSL而且--ssl参数从命令行移到了配置文件中require_secure_transport也开始支持。MySQL 8.0 变化更大默认开启 SSL而且默认启用了sha256_password和caching_sha2_password认证插件。如果你从 5.7 升级到 8.0旧客户端可能不支持新的认证插件报错信息往往也和 SSL 相关容易混淆排查方向。8.0.21 之后可以用ALTER INSTANCE RELOAD TLS在线重载证书这个功能强烈推荐。还有一点MySQL 8.0 中mysql_native_password被标记为废弃如果你还在使用老客户端可以临时指定default_authentication_pluginmysql_native_password但这只是过渡方案长期还是应该升级客户端。10. 最后的几点个人经验从我实际维护的经验来看MySQL 开启 SSL 加密连接这件事技术难度本身不高真正的难点在于证书体系的规划、不同客户端的适配、以及后续证书生命周期管理。下面这几条是我踩过的坑汇总出来的经验第一次配置不要上来就开require_secure_transportON。先把证书配好确认 SSL 能启用然后用一个测试账号手动验证加密连接成功之后再开启强制模式。否则证书路径写错一个字母MySQL 直接拒绝所有 TCP 连接只能在服务器上通过本地 socket 登录修复非常被动。证书文件的权限管理一定要做好。MySQL 服务进程对私钥文件必须有可读权限但私钥文件本身不能被其他系统用户读到。通常设置所属用户为 mysql权限设为 600 的私钥和 644 的证书文件可以避免很多安全和故障问题。对于生产环境不建议使用一个统仓的 CA 证书给所有环境签发建议测试环境、预发环境、生产环境各建一套独立的 CA。这样如果测试环境的私钥泄露不会影响生产环境的信任链。最后再分享一个小技巧排查 SSL 问题时先用openssl s_client -connect 127.0.0.1:3306在服务器本地查看证书输出可以快速区分是服务器证书问题还是客户端网络链路问题。这几年我排查过的 SSL 连接故障中一半以上都是客户端流程配置错误真正服务器证书出问题的反而是少数。希望这篇记录能帮你少走一些弯路。