跳到正文
Træfɪk

HTTP/2 请求头内存耗尽

Traefik 通过 Go 标准库提供 HTTP/2 服务。 在 HTTP/2 中,一个连接可以复用多个并发请求,每个请求都有自己的请求头块。

客户端可以结合 HPACK 请求头压缩和 HTTP/2 流量控制窗口,将少量网络传输数据扩展为代理上的大量内存分配,并通过停滞数据流使这些内存一直无法释放。 当并发流和连接足够多时,就可能耗尽可用内存并导致 Traefik 进程终止。

以下两个入口点选项可以限制这一风险,建议同时使用。

限制请求头大小

maxHeaderBytes 选项限制 Traefik 为每个请求读取的请求头大小,单位为字节。 将其从默认值(1048576,即 1 MiB)调低到能够容纳最大合法请求头的最小值,可以让 Traefik 在请求头块被放大之前就拒绝超大请求头。

entryPoints:
  websecure:
    address: ':443'
    http:
      maxHeaderBytes: 65536
[entryPoints.websecure]
  address = ":443"

  [entryPoints.websecure.http]
    maxHeaderBytes = 65536
--entryPoints.websecure.address=:443
--entryPoints.websecure.http.maxHeaderBytes=65536

限制每个连接的并发流数量

maxConcurrentStreams 选项限制每个客户端能够在单个连接上发起的并发 HTTP/2 流数量(默认值为 250)。 调低该值可减少单个连接能够持续占用的内存量。

entryPoints:
  websecure:
    address: ':443'
    http2:
      maxConcurrentStreams: 100
[entryPoints.websecure]
  address = ":443"

  [entryPoints.websecure.http2]
    maxConcurrentStreams = 100
--entryPoints.websecure.address=:443
--entryPoints.websecure.http2.maxConcurrentStreams=100

纵深防御

这两个限制可以约束单个连接的内存消耗。 如需进一步防护,还应在前置负载均衡器或防火墙上限制每个来源 IP 的并发连接数及请求速率,并为 Traefik 实例配置足够的内存,以处理预期的合法负载。


版权所有 © 头文件软件工作室

文档由 HeadFile Studio 翻译。

Traefik v3.7 中文快照 · 原文版权归 Traefik Labs 及贡献者所有 · MIT 许可证