揭秘 MySQL TLS:通过抓包了解真实的加密通信

你的 mysql 客户端和服务端之间开启 tls 了吗?你的回答可能是 No,我没有申请证书,也没有开启 mysql 客户端,服务端的 tls 配置。
可是当你抓取了 3306 mysql 的端口之后,你会发现,抓出来的包里居然有 Client Hello、Server Hello 这样的典型 TLS 报文。

其实,Mysql 的通信是否加密,是由客户端和服务端共同协商是否开启的,客户端与服务端都处于默认配置下的话,有些类似于 StartTls。
服务端侧
在连接建立时,Mysql 服务端会返回一个 Server Greeting,其中包含了一些关于服务端的信息,比如协议版本、Mysql 版本等等。在其中有一个 flag 的集合字段,名为 Capabilities Flag,顾名思义,这就是用来做兼容性,或者说特性开关的 flag,大小为 2 个字节,其中的第 12 位,代表着 CLIENT_SSL,如果设置为 1,那代表着如果客户端具备能力,服务端可以在后面的会话中切换到 TLS。可以看到里面还有一些其他的 flag,事务、长密码等等相关的兼容性开关。

我们可以测试一下设置为 0 的行为,只需要在 my.cnf 中添加
重启 mysql。再度进行抓包,就发现没有 tls 的报文了,都是在使用明文进行通信了。

客户端侧
这个协商过程也可以在客户端进行控制,客户端对应的参数是 sslMode,可以设置为 DISABLED、PREFERRED、REQUIRED、VERIFY_CA、VERIFY_IDENTITY,分别代表不使用 ssl、优先使用 ssl、必须使用 ssl、验证 CA、验证身份。example:
比如配置 sslMode 为 DISABLED,那么客户端就不会使用 ssl 进行通信,而是使用明文。

总结
注:
VERIFY_CA:确保服务器证书由受信任的 CA 签发,但不验证证书的主机名或 IP 地址。
VERIFY_IDENTITY:不仅验证证书的 CA 签发,还额外验证证书的主机名或 IP 地址与服务器的实际地址是否一致。
版权声明: 本文为 InfoQ 作者【张俭】的原创文章。
原文链接:【http://xie.infoq.cn/article/c973040973f5d4da9be7251ff】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论