Gin默认不防slowloris攻击,因其依赖net/http且标准库http.Server默认无连接层超时控制;必须显式配置ReadTimeout、WriteTimeout和IdleTimeout三个参数,其中IdleTimeout是防slowloris的关键,它主动关闭空闲超时连接,而MaxBytesReader仅限制body读取,无法防御仅发header的慢速攻击。

为什么 Gin 默认不防 slowloris 攻击
Gin 本身不拦截慢速连接,因为它运行在 net/http 之上,而标准库的 http.Server 默认没有连接层超时控制。slowloris 类攻击(如逐字节发 POST、长时间不发完 body)会持续占用 goroutine 和内存,直到 handler 被调用或超时——但这个“等到 handler”过程本身不受限。
必须配置 http.Server 的 IdleTimeout 和 ReadTimeout
仅靠 gin.SetMode(gin.ReleaseMode) 或中间件无法解决慢速连接问题,真正起效的是底层 http.Server 实例的超时参数:
-
ReadTimeout:从连接建立到读完 request header 的最大时间(含 slowloris 头部拖延) -
WriteTimeout:从 handler 开始执行到 response 写完的最大时间 -
IdleTimeout:两次读/写之间的最大空闲时间(防 slowloris 续发字节)
示例中 IdleTimeout: 60 * time.Second 是关键——它会让空闲超过 60 秒的连接被主动关闭,不管是否已进入 handler。
MaxBytesReader 只管 body,不管连接本身
http.MaxBytesReader 不能替代服务器超时,它只在 handler 内部读 r.Body 时生效:
- 如果攻击者只发 header 不发 body,
MaxBytesReader完全不触发 - 如果攻击者缓慢发 body,但每字节间隔
,连接仍保持,直到读满限制或 handler 超时 - 必须显式赋值:
r.Body = http.MaxBytesReader(w, r.Body, 10,否则无效
信任代理配置影响超时判断逻辑
如果你用了 Nginx 或 ALB 做反向代理,r.SetTrustedProxies([]string{"127.0.0.1"}) 不只是安全设置,还关系到超时是否作用于真实客户端:
- 未设可信代理时,
http.Server对每个 TCP 连接单独计时,但实际是代理在维持长连接 - 设了可信代理后,Gin 会解析
X-Forwarded-For并尝试按客户端 IP 分流,但超时仍由 Go server 针对代理连接执行 - 真正端到端防护需在代理层(如 Nginx 的
client_header_timeout/client_body_timeout)+ Go 层双重设限
最容易被忽略的是:超时参数必须在 http.Server 启动前全部设定,一旦 server.ListenAndServe() 运行,就无法动态修改。


















