不可能的任务:零配置 SSL

SSL(姑且这么称呼它,尽管 SSL 2.0 和 SSL 3.0 早已被 TLS 1.0–1.3 协议取代)支持于 2001 年在 MySQL 中实现,因此 MariaDB(诞生于 2009 年)一直拥有此功能。但在二十多年的 SSL 支持历程中,存在一个巨大问题。它需要繁琐的手动配置,因此大多数用户从未费心去设置,接受了他们的查询和数据在未受保护的情况下发送的事实。这在 2001 年可能略有风险,但在 2023 年绝对是鲁莽的。
传统方法
让我们看看。首先,安装 MariaDB 或 MySQL 的用户必须生成一个私钥和一个证书。诚然,这是最简单的一步,只需从手册中复制几条命令即可。MySQL 8.0 甚至可以自动为您完成。但这仅仅是个开始。你看,SSL 的唯一目的是保护连接免受位于客户端和服务器之间的攻击者(MitM,中间人)的侵害。如果中间不可能有攻击者,则无需 SSL。如果存在攻击者,他们可以替换服务器发送给客户端的证书,并获得拦截和窥探客户端和服务器都认为是安全加密的连接的能力。
为了防止这种情况发生,客户端必须验证证书确实属于与之通信的服务器。这可以通过 --ssl-verify-server-cert
选项启用(在 MySQL 中重命名为 --ssl-mode=VERIFY_IDENTITY
)。从根本上讲,验证证书意味着验证签名。它必须由受信任的证书颁发机构(CA)签名。这意味着用户必须从其 SSL 实现信任的机构购买合适的证书。或者从 Let’s Encrypt 免费获取一个,但这会让用户面临一套特殊的障碍。或者用户可以成为自己的 CA,生成证书,然后手动将其安装到受信任证书存储中的所有客户端上。
正因为如此,只有一小部分 MariaDB 用户实际启用了 SSL,而拥有正确签名证书以启用 --ssl-verify-server-cert
的用户数量更少。其他人要么选择完全不使用 SSL,要么选择不验证证书(这仅比第一种选择稍微好一点)。
零配置 SSL
这种情况将在 11.3 版本中改变。在这个新的 MariaDB 版本中,你可以鱼与熊掌兼得,呃,可以在启用 SSL 并验证证书的情况下,无需进行任何配置。但这如何实现呢?MariaDB 如何能够打破对受信任签名机构的基本 SSL 要求?解决方案在于 MariaDB 客户端连接到 MariaDB 服务器与一般情况不同,例如您的浏览器访问 https://mariadb.org.cn。
在绝大多数情况下,客户端和服务器有一个共享密钥——只有它们知道,但攻击者不知道。确实,客户端需要通过证明它知道账户密码来向服务器进行身份验证。现在在 11.3 版本中,MariaDB 服务器和客户端可以额外使用此密码来验证 SSL 证书确实来自于客户端想要通信的服务器。
协议
其工作原理如下。客户端连接到服务器并建立 SSL 连接。如果客户端可以使用 CA 签名或指纹(11.3 中的另一个新功能)验证证书,则验证在此结束,证书被验证。类似地,如果连接是通过安全的本地传输(Unix 套接字或命名管道)完成的。否则,证书存疑,但客户端不会像以前那样立即断开与服务器的连接。如果服务器请求安全认证(mysql_native_password 或 ed25519,它们即使没有 SSL 也具有 MitM 防护能力),客户端可以继续进行。但如果服务器想要切换到不安全的认证方式,客户端将断开连接——它将拒绝通过不安全的 SSL 连接发送明文密码。成功进行安全认证后,服务器将向客户端发送此签名
SHA256("password hash", scramble, "certificate fingerprint")
客户端知道这三个值,它可以计算出相同的签名,与服务器发送的进行比较,并验证服务器确实知道密码(客户端未被重定向到恶意服务器),并且证书未被攻击者替换(指纹未改变)。
现在,即使是自签名证书,MariaDB 客户端也可以验证服务器证书。这使得我们可以在服务器上默认启用 SSL,即使用户未提供证书,服务器也会自动生成它们。并在客户端默认启用 SSL,提供完整的 MitM 防护证书验证。用户无需做任何事情或进行任何配置。任务完成。
限制
有缺点吗?不幸的是,有。少数用户会受到以下情况的负面影响
- 如果您使用 PAM 或 gssapi 插件,这种自动证书验证将不起作用。您需要使用通过 CA 的旧方法或完全禁用证书验证。
- 在测试环境中,无密码账户很常见。在没有密码的情况下,自动证书验证将不起作用(而且,如果攻击者可以合法地无密码登录,他们确实无需破解 SSL)。在这种情况下,MariaDB 命令行客户端会发出警告并自动禁用证书验证。
- 通常,SSL 对连接速度的影响可以忽略不计。但如果您的应用程序使用了大量非常短暂的连接(例如,连接、一次主键查找、断开连接),那么 SSL 握手的开销可能会非常明显。此时请禁用 SSL 或使用连接池。
但大多数用户会发现自己身处一个更安全的世界,与数据库的连接会自动加密并受到 MitM 攻击的保护。
免责声明:此功能目前包含在11.3.0 预览版中。虽然可能性不大,但根据MariaDB 发布模型,它可能会从最终的 11.3.1 版本中移除。
更新:此功能未包含在 11.3.1 版本中。由于这是一个关键的安全相关功能,我们希望比平时更加确定其中没有缺陷,并且我们咨询了密码协议领域的各种专家。但未能及时获得反馈以赶上 11.3.1 版本发布。
更新 2:我们已收到所有等待的反馈,此功能已在 11.4.1 版本中发布。
听起来以后会更容易一些。感谢您的发文!