Improve rate limiting to combination of IP and username

This commit is contained in:
exterr2f 2025-02-14 20:20:42 +01:00
parent b6b37ee68b
commit e1b992526e

View File

@ -35,25 +35,15 @@ var (
authInstance *Authentication authInstance *Authentication
) )
var ( var ipUserLimiters sync.Map
ipLimiters sync.Map
usernameLimiters sync.Map
)
func getIPLimiter(ip string) *rate.Limiter { func getIPUserLimiter(ip, username string) *rate.Limiter {
limiter, ok := ipLimiters.Load(ip) key := ip + ":" + username
limiter, ok := ipUserLimiters.Load(key)
if !ok { if !ok {
limiter = rate.NewLimiter(rate.Every(time.Minute/5), 5) newLimiter := rate.NewLimiter(rate.Every(time.Hour/10), 10)
ipLimiters.Store(ip, limiter) ipUserLimiters.Store(key, newLimiter)
} return newLimiter
return limiter.(*rate.Limiter)
}
func getUserLimiter(username string) *rate.Limiter {
limiter, ok := usernameLimiters.Load(username)
if !ok {
limiter = rate.NewLimiter(rate.Every(time.Hour/10), 10)
usernameLimiters.Store(username, limiter)
} }
return limiter.(*rate.Limiter) return limiter.(*rate.Limiter)
} }
@ -241,18 +231,10 @@ func (auth *Authentication) Login(
username := r.FormValue("username") username := r.FormValue("username")
ipLimiter := getIPLimiter(ip) limiter := getIPUserLimiter(ip, username)
userLimiter := getUserLimiter(username) if !limiter.Allow() {
log.Warnf("AUTH/RATE > Too many login attempts for combination IP: %s, Username: %s", ip, username)
if !ipLimiter.Allow() { onfailure(rw, r, errors.New("Too many login attempts, try again in 1 hour"))
log.Warnf("AUTH/RATE > Too many login attempts from IP %s", ip)
onfailure(rw, r, errors.New("too many login attempts, please try again later"))
return
}
if !userLimiter.Allow() {
log.Warnf("AUTH/RATE > Too many failed login attempts for user %s", username)
onfailure(rw, r, errors.New("too many login attempts for this user, please try again later"))
return return
} }