通过 VPN 使用 MySQL:验证服务器,而不只是加密
加密到错误的主机依然是错误。比较 ssl-mode 的各取值,然后执行一条连接,指明你想要的服务器并证明这一点。
你保存了一个指向 10.20.4.15 的连接,VPN 断开后,客户端却仍然连得上。这不是好消息。私有地址只是你所处路由上下文中的一个位置,而许多网络使用相同的网段。客户端确实到达了一台 MySQL 服务器,只是可能不是你的那台。
修复分为两半,而只有一半与网络有关。让连接保持在预期的路径上,并让客户端认证它所通信的服务器。前一半是 VPN 能帮忙的地方;后一半必须靠配置。
到底加密到了哪里?
TLS 保护对话不被中间人窃听,但除非客户端主动检查,它并不说明服务端自称是谁。对受信任机构验证通过的证书只证明该证书由该机构签发。它并不证明证书是为你想访问的主机名签发的,而这是两个不同的问题。
这不是理论上的缺口。强制门户、错误的 VRF 失误以及重叠的地址规划,都会产生一台完全愿意与你协商 TLS 的服务器。如果客户端只要求加密,会话是私密的,却指向了错误的数据库。
所以关键问题不是连接有没有加密,而是它是否加密到了你预期的那一方。在 MySQL 客户端里,这一区别完全体现在 ssl-mode 设置中。
实践中的五种 ssl-mode 取值
共有五种取值,而只有一种能回答本手册的问题。表中列出的是每种取值真正保证什么,而不是名字暗示什么。
| Mode | What it guarantees |
|---|---|
DISABLED | No TLS at all; everything on the wire is readable |
PREFERRED | Tries TLS and falls back to plaintext when the account and server allow it, so it is not a fail-closed requirement |
REQUIRED | Refuses to connect without TLS, and does not validate the certificate |
VERIFY_CA | Validates the server certificate against the configured CA and does not check the hostname |
VERIFY_IDENTITY | Validates the CA and checks that the certificate names the host the client used |
本文的问题只有最后一行能回答。 PREFERRED 值得单独指出,因为悄悄降级到明文的客户端比直接拒绝的更糟:你以为有加密,抓包结果却不同意。
今天就能执行的一条连接
下面的命令就是应当采用的形式,有两个占位符:已批准的数据库名,以及通过已批准渠道获得的 CA 文件。这两者都不应取自服务器在首次接触时提供的东西。
mysql --host=db.corp.example --user=app_reader \
--ssl-mode=VERIFY_IDENTITY \
--ssl-ca=/approved/path/ca.pem --password
--password 不带取值时会提示输入,可让密码不出现在进程列表和 shell 历史里。这是个很小的习惯,但在共享跳板机上收益很大,因为命令行对其他用户可见。
失败时,错误文本比直觉更能区分情况。CA 失败意味着证书链验证不通过,应查看服务器证书是由哪个 CA 签发的。主机名失败意味着证书链没问题,但名字不匹配,这通常说明你用错误的名称连到了正确的服务器,而不是连到了错误的服务器。
出现提示并不能证明密码已经发送,连接失败也不能证明客户端什么都没发出。如果你在重建过去的事件,要确定客户端、它的配置、认证插件以及失败的阶段。仅凭最后的错误信息估计暴露程度只是猜测。
当名字来自隧道时
本地端口转发会以出人意料的方式破坏身份检查。如果你把本地端口转发到数据库并连接到 localhost,客户端会用 localhost 来验证证书,而并没有为该名字签发过证书。连接可能完全安全,验证却仍然失败,这正是检查在按设计工作。
有两个诚实的答案。给转发的端点一个能解析到回环地址、并且出现在服务器证书里的名字;或者端到端使用主机名,让客户端验证真实身份。前者对开发者方便,但需要证书方面的工作;后者更容易推理,通常也是自动化的正确默认值。为了让转发能用而关闭验证,等于丢掉了你本想增加的那项属性。
验收是三个条件
把验收测试写成三条彼此独立的陈述:连接走了预期路径,加密是被要求的而不是被偏好的,服务器身份是依据可信材料验证过的。 绿色的 VPN 图标并不确立其中任何一条。
对于图形界面客户端和 MariaDB,请查阅厂商自己的文档,而不是假定标志的拼写可以照搬。MySQL 加密连接文档 涵盖了各模式的差别以及 CA 分发的要求,在改动生产连接字符串之前,应当查阅的正是这份资料。