beego默认不防护慢连接攻击,必须手动配置net/http层超时参数:readtimeout(≤5s)、writetimeout(≤10s)、idletimeout(≤60s)、maxheaderbytes(≤8192),并在main.go中显式启动自定义http.server,而非调用beego.run()。

Beego 默认不防护慢连接攻击,必须手动配置 net/http 层
Beego 本身没有内置慢连接(Slowloris、Slow POST)防护机制。它运行在 net/http 之上,所有底层连接生命周期由 Go 标准库管理。这意味着超时、读写限制、连接数控制等都得在 http.Server 级别设置,而不是在 Beego 的 app.conf 或中间件里加几行配置就能生效。
常见错误现象:应用在压测或真实流量下出现 goroutine 暴涨、内存持续上升、新请求无法建立连接 —— 很可能不是业务逻辑问题,而是慢连接耗尽了 net/http.Server 的空闲连接或读缓冲区。
- Beego 启动时默认使用
http.ListenAndServe,其底层http.Server实例未显式配置超时参数,ReadTimeout/WriteTimeout等均为 0(即无限) - Go 1.19+ 虽引入了
ReadHeaderTimeout和IdleTimeout,但 Beego 未自动启用;若不覆盖,默认值仍为 0 - Beego 的
beego.BConfig.Listen.HTTPPort只控制监听端口,不触达http.Server的连接级参数
如何在 Beego 中正确设置连接超时与并发限制
必须在 main.go 中接管 http.Server 实例,不能依赖 beego.Run() 的默认启动方式。否则所有超时和限制配置都会被忽略。
实操建议:
- 调用
beego.BeeApp.StartServer()前,先构造自定义http.Server,显式设置以下字段:ReadTimeout(建议 ≤ 5s)、WriteTimeout(建议 ≤ 10s)、IdleTimeout(建议 ≤ 60s)、MaxHeaderBytes(建议 ≤ 8192) - 通过
http.Server.Handler指向beego.BeeApp.Handlers,确保路由和中间件逻辑不丢失 - 若需限制总并发连接数,需配合第三方包如
golang.org/x/net/netutil的LimitListener,Beego 无原生支持
示例关键代码片段:
srv := &http.Server{
Addr: ":" + beego.BConfig.Listen.HTTPPort,
Handler: beego.BeeApp.Handlers,
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
IdleTimeout: 60 * time.Second,
MaxHeaderBytes: 8192,
}
log.Fatal(srv.ListenAndServe())
Beego 中间件无法拦截慢连接,别在这儿浪费时间
所有 Beego 中间件(包括 beego.InsertFilter 注册的函数)都在 HTTP 请求头解析完成、路由匹配成功后才执行。而慢连接攻击发生在请求头未发完、或 Body 分块极慢的阶段 —— 此时中间件根本不会被调用。
容易踩的坑:
- 在
BeforeRouter或BeforeExec里加日志或计时,发现“完全没触发”,误以为是中间件注册失败 - 试图用
ctx.Input.SetData或自定义 context 字段做连接限流,实际毫无意义 —— 连接还没进入 Beego 的处理管道 - 依赖
beego.GlobalSessions的 session 初始化来阻断异常连接,同样无效,session 启动更晚
生产环境还需补充的底层防护点
仅靠 Go 层超时配置还不够。慢连接攻击往往利用 TCP 层特性,需要操作系统和反向代理协同防御。
必须检查并确认:
- 前端反向代理(如 Nginx)已启用
client_header_timeout、client_body_timeout、keepalive_timeout,且值严格小于 Beego 层设置 - Linux 内核参数
net.ipv4.tcp_fin_timeout和net.ipv4.tcp_tw_reuse已调优,避免 TIME_WAIT 连接堆积 - 若直接暴露 Beego 服务(无 Nginx),务必启用
http.Server.TLSConfig并禁用弱 TLS 版本 —— 某些慢 SSL 握手攻击会绕过纯 HTTP 超时
最易被忽略的一点:Beego 日志默认不记录连接建立/断开时间戳,也无连接状态监控指标。不接入 expvar 或 Prometheus Exporter,你根本不知道慢连接是否仍在堆积。











