我正在寻找一种可能性mysql 客户端只测试--ssl-mode=REQUIRED
给定的指令是否--host
100% 确保,不会泄露用户名、密码和数据库名称通过互联网以明文形式传输。使用如下参数运行该模式:--ssl--check-handshake-only-then-disconnect-and-report
。
这是针对某人的网络主机的情况:
- 没有关于服务器上 SSL 可用性的适当/可用/可靠的文档,
- 和/或没有或只有对 mysql 服务器及其配置信息的复杂访问。
经过我目前的研究,我认为不可能进行 100% 无风险的 SSL/TLS 握手测试即显然没有风险,因为它不需要提供用户名、密码、数据库名称。
文档–ssl 模式 = 必需非常简单而简短地解决了这个问题:
必需:如果服务器支持加密连接,则建立加密连接。如果无法建立加密连接,则连接尝试失败。
我们只需相信 mysql 客户端(又名“shell”)确实按照该顺序运行:
- 确保
--ssl-mode=REQUIRED
在给定情况下有效,否则过早退出并显示明确的错误消息。 - 只有当握手和加密协商顺利时,客户端才会提交提供的用户名、密码和数据库名称。
- 并且没有新的开发人员会在这种条件检查中引入错误......
对于熟悉并信任其 mysql 客户端和设置的熟练/日常用户来说,这可能就足够了。
但对于新用户或需要怀疑的人来说,这并不是最理想的,因为他们真正需要的是 100% 无风险检查的可能性。
真正的“无风险连接/握手测试模式”显然是无风险的,因为它无需提交任何具体凭证就可以工作,这将非常令人放心。
- 在我注册之前https://bugs.mysql.com并在那里提交功能请求
- 我在这里问一下,是否存在我不知道的可能性。
答案1
如果您只是想测试当无法建立 SSL 时客户端是否会抛出错误,那么一种快速而肮脏的方法是将这两者结合起来:
- 只需使用虚假的用户名和密码即可连接
- 强制客户端使用错误的密码失败 SSL 握手,例如
--ssl-cipher SEED-SHA
您应该始终看到“SSL 失败”的错误,而不是“密码错误”。尝试--ssl-mode=REQUIRED
开启和关闭以验证它是否会抛出错误或恢复为明文。
如果您想检查服务器是否支持 SSL(以及支持到何种程度),那么 nmap 之类的工具会更好。确保您拥有更新版本的 nmap,然后使用类似下面的工具检查 SSL 状态,例如:
nmap --script ssl-enum-ciphers MyServerName -p 3306
而且,如果没有其他事情,您可以随时使用数据包捕获/ wireshark 来验证连接在 SSL 之前不会发送凭据,尽管它有一个学习曲线。
正如您提到的,如果您可以与控制服务器的任何人合作,这很简单,可以使用以下选项:
- 使用基于证书的身份验证,因此不会泄露任何秘密
- 要求服务器端使用 SSL(如果面向互联网则应要求使用)
- 在连接到 MySql 之前使用 VPN 或 SSH 控制连接
但这并不总是可能的
结果nmap
——这感觉像是适合这项工作的工具!
nmap --script ssl-enum-ciphers customerid-mysql.services.mywebhost.com -p 3306
Starting Nmap 7.93 ( https://nmap.org ) at 2022-12-16 01:39 CET
Nmap scan report for customerid-mysql.services.mywebhost.com (XXX.XX.X.XX)
Host is up (0.016s latency).
rDNS record for XXX.XX.X.XX: web20.mywebhost.com
PORT STATE SERVICE
3306/tcp open mysql
| ssl-enum-ciphers:
| TLSv1.2:
| ciphers:
| TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 2048) - A
| TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (dh 2048) - A
| TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (dh 2048) - A
| TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 2048) - A
| TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (dh 2048) - A
| TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (dh 2048) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (secp256r1) - A
| TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (secp256r1) - A
| TLS_RSA_WITH_AES_128_CBC_SHA (rsa 4096) - A
| TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 4096) - A
| TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 4096) - A
| TLS_RSA_WITH_AES_256_CBC_SHA (rsa 4096) - A
| TLS_RSA_WITH_AES_256_CBC_SHA256 (rsa 4096) - A
| TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 4096) - A
| compressors:
| NULL
| cipher preference: client
| warnings:
| Key exchange (dh 2048) of lower strength than certificate key
| Key exchange (secp256r1) of lower strength than certificate key
|_ least strength: A
Nmap done: 1 IP address (1 host up) scanned in 3.23 seconds
mysql
结合和--ssl-cipher
的结果--ssl-mode
$ mysql --ssl-cipher SEED-SHA -h customerID-mysql.services.mywebhost.com -u fakeUser -p --ssl-mode=DISABLED
Enter password:
ERROR 1045 (28000): Access denied for user 'fakeUser'@'XX.XXX.XX.XX' (using password: YES)
- ❌ 服务器接受纯文本。
- ✅ 但我们只破坏了虚假数据。
- ✅ 没有造成伤害。 最大风险已确定。
$ mysql --ssl-cipher SEED-SHA -h customerID-mysql.services.mywebhost.com -u fakeUser -p --ssl-mode=REQUIRED
Enter password:
ERROR 2026 (HY000): SSL connection error: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
- ✅ 服务器因密码错误而中止。
- ℹ️从理论上来说,我们知道这会在凭证发送之前启动。
- ✅ 因此,对于那些拥有相关知识的人来说,这是一个足够好的预测试。
$ mysql --ssl-cipher SEED-SHA -h customerID-mysql.services.mywebhost.com -u fakeUser -p --ssl-mode=PREFERRED
Enter password:
ERROR 2026 (HY000): SSL connection error: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
- ✅ 此外,当我们使用 PREFERRED 来诱惑服务器但提供错误的密码时,服务器会做出安全的选择并终止。
- ✅ 感觉很恐怖。另外,我不明白为什么 --ssl-cipher SEED-SHA 是一个坏密码,以及在什么条件下测试它。
$ mysql -h customerID-mysql.services.mywebhost.com -u fakeUser -p --ssl-mode=REQUIRED
Enter password:
ERROR 1045 (28000): Access denied for user 'fakeUser'@'77.119.77.94' (using password: YES)
- ❓ 不确定如何解释这一点:
- ❌ 尽管我要求协议继续(至少提交用户名,幸运的是用户名只是“fakeUser”。
- ❓但是这个请求中也发送了密码吗?