要完成@raz'的回答,有几点:
OpenSSL以及因此基于 OpenSSL(客户端和服务器)的实现往往不再发送close_notify
消息;他们只是断开连接。主要原因是在现有的 Web 服务器和客户端中,连接是在一个池中管理的,该池会在一些不活动延迟后关闭它们;该池管理低级套接字,并且不知道 SSL 可能是什么;因此,SSL 层无法发送(或等待)显式close_notify
.
这种设计的一个根本原因是避免过度保留资源。从服务器的角度来看,不活动的客户端可能是死客户端——可能是客户端计算机崩溃或或多或少干净地关闭,或者它的网络访问刚刚中断。因此,可能没有人接收close_notify
. 通常情况下,TCP 连接是缓冲的,因此服务器代码可以close_notify
立即发送并关闭连接,而无需等待来自客户端的 ACK(ACK 永远不会到来,客户端已经死亡)。但是,客户端死亡可能在任何时候发生,包括在从服务器发送上一个应答的过程中,因此此时 TCP 缓冲区可能已满。因此,发送close_notify
可能会停顿很长时间,直到 TCP 层确定连接真的死了(这可能需要几个小时)。
通过简单地直接关闭套接字,在一些固定的不活动延迟之后,无论当时的连接逻辑状态如何(SSL 与否;发送答案或等待下一个请求),服务器确保它们避免阻塞资源以受益于死客户端.
HTTPS 级别的主要“截断攻击”与 HTTP 0.9 有关。在 HTTP 0.9 中,每个请求都使用一个新连接,并且服务器会在没有显式数据终止的情况下发回答案;当服务器完成发送数据时,它会关闭底层套接字。客户端因此知道它在套接字关闭时获得了所有数据。
对于 HTTP 0.9,缺少 aclose_notify
意味着攻击者可以截断答案(通过强制 TCP 级别关闭)并且客户端不会知道它。这被认为是 SSL 2.0 的主要弱点之一。
但是,为每个请求打开一个新连接的效率非常低,因此从 HTTP 1.0 开始,客户端和服务器会为多个请求和响应重用连接。这反过来又要求 HTTP 协议自终止:仅检查交换的字节就足以决定是否到达请求或应答的结尾,而不依赖于来自传输介质的“关闭”事件。基本上,客户端和服务器使用显式Content-Length
标头,或者(对于数据流)使用“分块传输编码”。当进入 SSL/TLS 隧道的应用程序协议自行终止时,close_notify
是多余的,可以省略。这正是现代 HTTPS 中发生的情况。现代服务器不再使用 HTTP 0.9;他们所有的回应都是自我终止的;所以他们有能力(从安全的角度)不发送close_notify
.
@raz 谈到的截断攻击更高一级:客户端发送一个 HTTP 请求以执行某些“注销”操作,但不等待相应的答案(一个HTTP答案,而不是 a close_notify
)。存在或缺少 aclose_notify
在这里不会改变任何东西;弱点是不耐烦的用户。
SSL/TLS 会话重用实际上比单纯的恢复更大。最初,SSL 的设计理念是客户端打开一个与服务器的连接,如果前一个连接关闭,则只需打开一个新连接。
Web 浏览器不再那样做。相反,他们打开了几个到服务器的连接,主要是为了他们可以并行发送请求,以获得更好的用户体验。HTTP-1.0 参考说:
Clients that use persistent connections SHOULD limit the number of
simultaneous connections that they maintain to a given server. A
single-user client SHOULD NOT maintain more than 2 connections with
any server or proxy.
然而,实践和往常一样,有点不同(不过,一些浏览器对同时连接的数量应用不同的限制,具体取决于连接是否使用 SSL)。
对于所有这些连接,典型的浏览器将与一个连接进行完整的握手,然后为其他连接“恢复”该会话,即使“会话”仍处于活动状态并启动第一个连接。因此,会话可以在停止之前恢复。@raz 引用的 TLS 1.0 中的规定只是扩展了这个想法,因为它定义了会话可以恢复,而不管其他连接上的同一会话发生了什么或仍然发生什么。实际上,会话恢复不再是恢复,而是重用会话参数(即协商的共享密钥)。
总结: SSL/TLS 正式提供了加密保护的闭包:当一个连接被关闭时,客户端和服务器都可以保证这个闭包是真实的,并且不会被插入的攻击者注入。现有实践偏离了该理论,并且实现不再提供该保证。
这对于 HTTPS Web 服务器来说不是问题,因为此类服务器强制使用不需要闭包加密保护的自终止应用程序协议(具有显式块或内容长度的 HTTP 1.0+)。
总的来说,不发送 aclose_notify
是协议的弱化,如果(且仅当)底层协议没有自行终止时,可能会利用它。幸运的是,非自终止协议极为罕见,可以说是“设计不佳”(如果只是因为它们不允许连接重用),因此这种弱化在实践中并不是一个大问题(暂时。 ..)。