首先,给予一些背景:
我们有一个隐藏在 TLS 代理后面的服务器应用程序。代理服务器要求提供客户端证书,根据我们的 CA 对其进行测试,然后将请求以客户端证书作为标头通过 HTTP 转发到服务器。然后,应用程序中使用该标头来识别客户端。
现在,问题:几天前,我们将代理的实现从 Apache 切换到了 Nginx,我们发现一些以前可以通行的请求(来自不同的客户端)现在不再通过。Nginx 声明客户端证书丢失,请求被阻止。
我们知道什么:
- 我们比较了 Apache 代理在接收到通过的客户端请求和未通过的客户端请求时生成的日志。
经过的请求会产生一个包含客户端证书的大转储:
ssl_engine_io.c(2070): [client 192.168.1.117:65017] OpenSSL: read 5143/5143 bytes from BIO#557fd20fa810 [mem: 557fd23781c8] (BIO dump follows)
ssl_engine_io.c(1998): +-------------------------------------------------------------------------+
ssl_engine_io.c(2037): | 0000: 0b 00 13 cd 00 13 ca 00-06 d9 30 82 06 d5 30 82 ..........0...0. |
ssl_engine_io.c(2037): | 0010: 04 bd a0 03 02 01 02 02-12 11 21 1f 9d 56 1c 0f ..........!..V.. |
ssl_engine_io.c(2037): | 0020: 7d 5f 63 7c 90 39 0d 57-60 b2 75 30 0d 06 09 2a }_c|.9.W`.u0...* |
... continues for a few hundred lines
而客户端没有通过的请求则不会产生任何结果。
但是,客户端证书实际上不会在原始请求中丢失,因为它曾经通过并且我们的应用程序能够识别它。
我们用相同的证书测试了两种类型的客户端(工作和不工作),所以这不是问题。
我们使用 ssllabs.com 分析了我们的服务器。我们发现,我们的新实现不支持 TLS 1.0 和 1.1,但从我们进行一些测试时看到的情况来看,使用旧 TLS 实现向新服务器发出的请求会产生非常具体的错误消息,而不是有关缺少证书的信息。
ssllabs 还显示,我们的旧服务器接受的密码套件比当前服务器多得多。不过我认为这与我们的问题无关。
新服务器不具备 SSL2 兼容性,而旧服务器具备。
我们有点不知所措,因为这里没有人专门研究这种主题。如果您发现我的问题中有些内容没有意义或需要澄清,请随时提问。(我可能确实对某些事情感到困惑,因为我说过这不是我的领域)
如果我们发现更多信息,我会更新。
答案1
这是一个老话题,我也不是 100% 确定,但我认为问题确实是出在 TLS 版本上。有些客户端使用的版本非常旧,无法再与我们通信。
我将结束这个问题。