feat: add per-IP rate limiting to login endpoint
All checks were successful
check / check (push) Successful in 59s
All checks were successful
check / check (push) Successful in 59s
Add a token-bucket rate limiter (golang.org/x/time/rate) that limits login attempts per client IP on POST /api/v1/login. Returns 429 Too Many Requests with a Retry-After header when the limit is exceeded. Configurable via LOGIN_RATE_LIMIT (requests/sec, default 1) and LOGIN_RATE_BURST (burst size, default 5). Stale per-IP entries are automatically cleaned up every 10 minutes. Only the login endpoint is rate-limited per sneak's instruction — session creation and registration use hashcash proof-of-work instead.
This commit is contained in:
@@ -48,6 +48,8 @@ type Config struct {
|
||||
HashcashBits int
|
||||
OperName string
|
||||
OperPassword string
|
||||
LoginRateLimit float64
|
||||
LoginRateBurst int
|
||||
params *Params
|
||||
log *slog.Logger
|
||||
}
|
||||
@@ -82,6 +84,8 @@ func New(
|
||||
viper.SetDefault("NEOIRC_HASHCASH_BITS", "20")
|
||||
viper.SetDefault("NEOIRC_OPER_NAME", "")
|
||||
viper.SetDefault("NEOIRC_OPER_PASSWORD", "")
|
||||
viper.SetDefault("LOGIN_RATE_LIMIT", "1")
|
||||
viper.SetDefault("LOGIN_RATE_BURST", "5")
|
||||
|
||||
err := viper.ReadInConfig()
|
||||
if err != nil {
|
||||
@@ -110,6 +114,8 @@ func New(
|
||||
HashcashBits: viper.GetInt("NEOIRC_HASHCASH_BITS"),
|
||||
OperName: viper.GetString("NEOIRC_OPER_NAME"),
|
||||
OperPassword: viper.GetString("NEOIRC_OPER_PASSWORD"),
|
||||
LoginRateLimit: viper.GetFloat64("LOGIN_RATE_LIMIT"),
|
||||
LoginRateBurst: viper.GetInt("LOGIN_RATE_BURST"),
|
||||
log: log,
|
||||
params: ¶ms,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user