mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2025-03-04 05:55:56 +01:00
Improve rate limiting to combination of IP and username
This commit is contained in:
parent
b6b37ee68b
commit
e1b992526e
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user