我们正在开发一个项目,在前端使用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问题的根源似乎是服务器认为来自同一客户端的开销太大,于是关闭了连接。
问题是?我们可以调整服务器以接受一定限度的开销吗??如何?我相信这是我们应该能够在春天或tomcat或那里的某个地方调整的事情。
干杯Ignacio
开销保护是针对2019年年中针对HTTP/2报告的CVE集合而实施的。虽然Tomcat没有受到直接影响(恶意输入没有触发过多负载(,但我们确实采取了措施来阻止与恶意配置文件匹配的输入。
从你的GitHub评论中,你可以看到海报的问题。这强烈表明客户端是以多个小数据包发送POST数据,而不是以较小数量的较大数据包发送。一些客户端(例如Chrome(偶尔会这样做,因为它们缓冲数据的方式。
许多HTTP/2 DoS攻击可以概括为发送比数据更多的开销。虽然Tomcat没有受到直接影响,但我们决定监控以这种方式运行的客户端,如果发现任何连接,我们会以客户端可能是恶意的为由放弃连接。
通常,数据包会减少开销计数,非数据包会增加开销计数,(潜在的(恶意包会显著增加开销计数。其想法是,一个已建立的、通常表现良好的连接应该能够在偶尔的"可疑"数据包中幸存下来,但超过这一点将迅速触发连接关闭。
就小型POST数据包而言,关键配置设置为:
overheadCountFactor
overheadDataThreshold
开销计数从-10开始。对于接收到的每个DATA帧,它被减少1。对于每个SETTINGS、PRIORITY和PING帧,它都会增加overheadCountFactor
。如果开销计数超过0,则连接关闭。
此外,如果接收到的非最终DATA帧和先前接收到的DATA帧(在同一流上(的平均大小小于overheadDataThreshold
,则开销计数增加overheadDataThreshold/(average size of current and previous DATA frames)
。这样,DATA帧越小,开销的增加就越大。少量的非最终数据帧应该足以触发连接关闭。
平均值是存在的,因此Chrome所展示的缓冲不会触发开销保护。
要诊断此问题,您需要查看日志,以查看客户端发送的非最终DATA帧的大小。我怀疑这将显示一系列大小小于1024(overheadDataThreshold
的默认值(的非最终DATA帧。
为了解决这个问题,我的建议是先看看客户。为什么它要发送小的非最终数据帧,可以做些什么来阻止它?
如果你需要立即缓解,那么你可以减少overheadDataThreshold
。你从客户端发送的DATA帧大小信息应该指导你将其设置为什么。它需要小于客户端发送的数据帧。在极端情况下,您可以将overheadDataThreshold
设置为零以禁用保护。