HTTP2 ERR CONNECTION CLOSED(开销太大)

Posted

技术标签:

【中文标题】HTTP2 ERR CONNECTION CLOSED(开销太大)【英文标题】:HTTP2 ERR CONNECTION CLOSED (Too much overhead) 【发布时间】:2020-08-08 08:31:11 【问题描述】:

我们正在开发一个项目,前端使用 Angular,后端使用 Spring。没什么新鲜的。但是我们已经将后端设置为使用 HTTP2,并且不时会发现奇怪的问题。

今天我开始玩 chrome 的“网络日志导出”,我在日志的 HTTP2_SESSION 行中发现了这条有趣的信息。

t=43659 [st=41415]    HTTP2_SESSION_RECV_GOAWAY
                  --> active_streams = 4
                  --> debug_data = "Connection [263], Too much overhead so the connection will be closed"
                  --> error_code = "11 (ENHANCE_YOUR_CALM)"
                  --> last_accepted_stream_id = 77
                  --> unclaimed_streams = 0
t=43659 [st=41415]    HTTP2_SESSION_CLOSE
                  --> description = "Connection closed"
                  --> net_error = -100 (ERR_CONNECTION_CLOSED)
t=43661 [st=41417]    HTTP2_SESSION_POOL_REMOVE_SESSION
t=43661 [st=41417] -HTTP2_SESSION

看起来 ERR_CONNECTION_CLOSED 问题的根源在于服务器认为来自同一客户端的开销过多并关闭了连接。

问题是 ¿ 我们可以调整服务器以接受达到一定限制的开销吗?如何?我相信这是我们应该能够在 Spring 或 tomcat 或那里的某个地方进行调整的东西。

干杯 伊格纳西奥

【问题讨论】:

我认为 Tomcat http2 实现中存在错误,这就是问题的根源。看到这条评论:github.com/apache/tomcat/commit/… 你有没有设法解决这个/正确配置这个?我遇到了类似的问题。发表在 github 线程中。 【参考方案1】:

针对 2019 年年中针对 HTTP/2 的 collection of CVE's 报告设置了开销保护。虽然 Tomcat 没有受到直接影响(恶意输入没有触发过度负载),但我们确实采取了措施阻止与恶意配置文件匹配的输入。

在您的 GitHub comment 中,您会看到 POST 的问题。这强烈表明客户端正在以多个小数据包而不是较少数量的大数据包发送 POST 数据。一些客户端(例如Chrome)知道偶尔会这样做,因为它们缓冲数据的方式。

许多 HTTP/2 DoS 攻击可以概括为发送比数据更多的开销。虽然 Tomcat 没有直接受到影响,但我们决定监控以这种方式运行的客户端,如果发现任何连接,我们会以该客户端可能是恶意的为由断开连接。

通常,数据包会减少开销计数,非数据包会增加开销计数,并且(可能)恶意数据包会显着增加开销计数。这个想法是,一个已建立的、通常表现良好的连接应该能够在偶尔的“可疑”数据包中幸存下来,但除此之外,将很快触发连接关闭。

就小型 POST 数据包而言,键 configuration setting 是:

overheadCountFactor overheadDataThreshold

开销计数从 -10 开始。对于接收到的每个 DATA 帧,它会减少 1。对于每个 SETTINGS、PRIORITY 和 PING 帧,它都会增加 overheadCountFactor。如果开销计数超过 0,则连接关闭。

此外,如果接收到的非最终 DATA 帧和之前接收到的 DATA 帧(在同一流上)的平均大小小于overheadDataThreshold,则开销计数将增加overheadDataThreshold/(average size of current and previous DATA frames)。这样,DATA帧越小,开销的增加就越大。少量小的非最终 DATA 帧应该足以触发连接关闭。

存在平均值,因此 Chrome 显示的缓冲不会触发开销保护。

要诊断此问题,您需要查看日志以了解客户端发送的非最终 DATA 帧大小。我怀疑这会显示一系列大小小于 1024 的非最终 DATA 帧(overheadDataThreshold 的默认值)。

要解决此问题,我的建议是先查看客户端。为什么它会发送小的非最终 DATA 帧,可以做些什么来阻止它?

如果您需要立即缓解,则可以减少 overheadDataThreshold。您获得的有关客户端发送的 DATA 帧大小的信息应指导您将其设置为什么。它需要小于客户端发送的 DATA 帧。在极端情况下,您可以将overheadDataThreshold 设置为零以禁用保护。

【讨论】:

在我们的例子中,用户通过一个对话框设置不同的属性并提供信息以完成任务。收集到信息后,浏览器会发送一个 POST(小)以在服务器上创建一个对象(任务)。到目前为止,一切进展顺利。成功创建该对象后,前端可以执行从 3 到 15 的可变数量的操作,具体取决于表单上先前的答案。这些操作只有 2 种类型: 将文件上传到任务的 POST。用于设置任务属性的 PUT。问题是最多可以有 15 个 PUT 请求数量不是问题。如果任何非最终 DATA 帧的大小合适,许多小的 PUT/POST 不会触发保护。许多带有小的最终数据帧的小型 PUT/POST 都可以。同样,您需要查看客户端发送的非最终 DATA 帧的大小。 为什么 PING 会导致更多开销?您是否可以不通过 PING 保持长时间会话,以便您可以在同一会话中传输数据,但在很长一段时间后? 重复 PING 可能是恶意行为的标志 (CVE-2019-9512)。 Tomcat 不易受到该 CVE 的攻击,但 Tomcat 仍然认为 PING 是一种开销,作为识别和关闭此类攻击的一种方式。如果这对用户来说是个问题(没有人报告过),那么总是可以修改保护以仅将前一次 ping 的 x 毫秒内的 ping 视为开销。

以上是关于HTTP2 ERR CONNECTION CLOSED(开销太大)的主要内容,如果未能解决你的问题,请参考以下文章

nodejs http2上的ERR_INVALID_HTTP_RESPONSE

使用 HTTP2 和 TLS 的 Cowboy Web 服务器在 Chrome 中获取 ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY

净:ERR_CONNECTION_CLOSED

离子 4 网络::ERR_CONNECTION_REFUSED(http://localhost/)

“ERR_CONNECTION_TIMED_OUT”背后的原因可能是啥?

到达 Tomcat 时出现 ERR_CONNECTION_TIMED_OUT