我正在寻找编写一小段速率限制中间件:
允许我为每个远程 IP 设置合理的速率(例如 10 req/s)
可能(但不是必须)允许爆发
丢弃(关闭?)超过速率的连接并返回 HTTP 429
然后,我可以围绕身份验证路由或其他可能容易受到暴力攻击的路由(即使用过期令牌等的密码重置 URL)进行包装。有人强行使用 16 或 24 字节令牌的可能性非常低,但多走一步也无妨。
我看过https://code.google.com/p/go-wiki/wiki/RateLimiting但我不确定如何将它与 http.Request(s) 协调。此外,我不确定我们如何在任何时间段内“跟踪”来自给定 IP 的请求。
理想情况下,我最终会得到这样的结果,注意我在反向代理 (nginx) 后面,所以我们正在检查REMOTE_ADDR
HTTP 标头而不是使用r.RemoteAddr
:
// Rate-limiting middleware
func rateLimit(h http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
remoteIP := r.Header.Get("REMOTE_ADDR")
for req := range (what here?) {
// what here?
// w.WriteHeader(429) and close the request if it exceeds the limit
// else pass to the next handler in the chain
h.ServeHTTP(w, r)
}
}
// Example routes
r.HandleFunc("/login", use(loginForm, rateLimit, csrf)
r.HandleFunc("/form", use(editHandler, rateLimit, csrf)
// Middleware wrapper, for context
func use(h http.HandlerFunc, middleware ...func(http.HandlerFunc) http.HandlerFunc) http.HandlerFunc {
for _, m := range middleware {
h = m(h)
}
return h
}
我很感激这里的一些指导。
相关分类