mysql用户密码传输是否被截获取决于是否启用并正确配置ssl:服务端需have_ssl=yes、require_secure_transport=on,用户须require ssl,客户端必须显式指定--ssl-mode=required等参数,否则静默降级为明文,抓包可直接还原密码。

MySQL用户密码在传输过程中是否被截获,本质不是“能不能被截”,而是“有没有加密保护”——明文传输就等于裸奔,SSL未启用或配置错误时,mysql -u user -p 输入的密码、甚至整个登录握手过程都可能被网络抓包工具(如 tshark 或 tcpdump)直接还原。
确认连接是否真走SSL加密通道
很多人以为“服务器配了SSL证书”就安全了,其实客户端连上来默认仍走明文。必须验证当前会话是否真实启用了TLS:
- 登录后执行
STATUS,看输出中SSL:行是否显示具体 cipher(如SSL: Cipher in use is TLS_AES_256_GCM_SHA384),若显示Not in use,说明本次连接未加密 - 或者查
SELECT * FROM performance_schema.status_by_thread WHERE VARIABLE_NAME = 'Ssl_cipher';,结果为空或为NULL就是没走SSL - 注意:即使服务端有证书,若用户没设
REQUIRE SSL,或客户端没加--ssl-mode=REQUIRED,MySQL会静默降级为明文连接,不会报错
检查用户权限是否强制要求SSL
服务端开了SSL ≠ 所有用户必须用SSL。密码是否暴露,取决于该用户是否被强制走加密通道:
- 执行
SHOW CREATE USER 'username'@'host';,检查输出中是否含REQUIRE SSL(或REQUIRE X509等更强策略) - 如果只是
CREATE USER 'u'@'%' IDENTIFIED BY 'pwd';,那这个用户永远可以明文登录,哪怕服务端SSL开着 - 补救方式:
ALTER USER 'u'@'%' REQUIRE SSL;,然后FLUSH PRIVILEGES;
验证客户端是否真正完成TLS握手
客户端命令行或应用连接参数不正确,会导致“以为连了SSL,实际还是明文”:
- 命令行连接必须显式指定
--ssl-mode=REQUIRED(MySQL 8.0+)或--ssl(旧版),仅加--ssl-ca不够,缺了模式参数照样降级 - Java JDBC 连接串里要带
?useSSL=true&requireSSL=true&verifyServerCertificate=true,少任意一个都可能绕过校验 - Python MySQL Connector 需传
ssl_disabled=False且ssl_ca/ssl_cert路径有效;若证书路径错、私钥权限不对(如ssl-key文件不是600),连接会 fallback 到明文,且不报错
抓包验证密码是否可见(实操底线手段)
当以上都看似正常但仍有疑虑,最直接的办法是本地抓包看协议层:
- 在客户端机器运行:
sudo tcpdump -i any -w mysql.pcap port 3306,然后执行一次mysql -u test -p --ssl-mode=REQUIRED - 用 Wireshark 打开
mysql.pcap,过滤mysql,展开 TCP 流。若看到Handshake Protocol: Certificate和Change Cipher Spec,说明 TLS 握手成功;若只有明文COM_LOGIN包且 payload 含用户名,就是没加密 - 特别注意:MySQL 8.0+ 默认用
caching_sha2_password插件,其认证交换本身不依赖SSL也能防明文密码,但仅限认证阶段;后续查询内容仍是明文——所以仍需全程SSL
最容易被忽略的一点:MySQL服务端的 require_secure_transport = ON 必须开启,否则任何用户都能绕过SSL连进来,无论你给谁加了 REQUIRE SSL。这个开关才是全局兜底防线。











