与服务器建立连接后,HTTP/2 协议允许客户端发起并发流进行数据交换。 与协议的先前迭代不同,如果最终用户决定离开页面或出于任何其他原因停止数据交换,HTTP/2 提供了一种取消流的方法。 它通过向服务器发出 RST_STREAM 帧来实现此目的,从而使其免于执行不必要的工作。
该漏洞是通过在已建立的连接上启动并快速取消大量 HTTP/2 流来利用的,从而绕过服务器的并发流最大值。 发生这种情况是因为传入流的重置速度比后续流到达的速度快,从而允许客户端在不达到其配置阈值的情况下使服务器过载。
出于性能和资源消耗的原因,NGINX 将并发流的数量限制为默认值 128(请参阅 http2_max_concurrent_streams )。 此外,为了最佳地平衡网络和服务器性能,NGINX 允许客户端默认使用 HTTP keepalive 保持最多 1000 个请求的 HTTP 连接(请参阅 keepalive_requests )。
通过依赖默认的 keepalive 限制,NGINX 可以防止此类攻击。 创建额外的连接来规避此限制会通过标准第 4 层监控和警报工具暴露不良行为者。
但是,如果 NGINX 配置的 keepalive 远高于默认和推荐的设置,则攻击可能会耗尽系统资源。 当发生流重置时,HTTP/2 协议要求该流上没有后续数据返回到客户端。 通常,重置会导致以优雅地处理取消的任务形式出现的服务器开销可以忽略不计。 然而,绕过 NGINX 的流阈值使客户端能够利用这种开销,并通过快速启动数千个流来放大它。 这会迫使服务器 CPU 达到峰值,从而拒绝向合法客户端提供服务。
通过建立 HTTP/2 流来拒绝服务,然后在异常高的保持活动限制下取消流。
作为功能齐全的服务器和代理,NGINX 为管理员提供了减轻拒绝服务攻击的强大工具。 要利用这些功能,必须对 NGINX 配置文件进行以下更新,从而最大限度地减少服务器的攻击面:
我们还建议添加这些安全措施作为最佳实践:
我们尝试了多种缓解策略,帮助我们了解这种攻击如何影响我们广泛的客户和用户。 虽然这项研究证实 NGINX 已经配备了避免攻击的所有必要工具,但我们希望采取额外的措施来确保确实需要配置超出推荐规格的 NGINX 的用户能够这样做。
我们的调查得出了一种提高服务器在各种形式的洪水攻击下的弹性的方法,这些攻击理论上可以通过 HTTP/2 协议实现。 因此,我们发布了一个补丁来提高这些条件下的系统稳定性。 为了防范此类威胁,我们建议 NGINX 开源用户从最新的代码库重建二进制文件,并且 NGINX Plus 客户立即更新到最新的软件包(R29p1 或 R30p1)。
为了确保尽早检测到 NGINX 上的洪水攻击,该补丁对一个事件循环中可以引入的新流的数量进行了限制。 此限制设置为使用 http2_max_concurrent_streams 指令配置的值的两倍。 即使从未达到最大阈值,也会应用该限制,例如发送请求后立即重置流(如本次攻击的情况)。
此漏洞影响 NGINX HTTP/2 模块 ( ngx_http_v2_module )。 有关可能受影响的特定 NGINX 或 F5 产品的信息,请访问: https: //my.f5.com/manage/s/article/K000137106 。
有关 CVE-2023-44487 – HTTP/2 快速重置攻击的更多信息,请参阅: https://www.cve.org/CVERecord ?id=CVE-2023-44487
我们要感谢 Cloudflare、Amazon 和 Google 在发现和协作识别和缓解此漏洞方面所做出的贡献。