mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-06 21:49:08 +02:00
configurable rate limit
This commit is contained in:
@@ -5,6 +5,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -48,6 +50,9 @@ type GRPCServer struct {
|
|||||||
ephemeralManager *EphemeralManager
|
ephemeralManager *EphemeralManager
|
||||||
peerLocks sync.Map
|
peerLocks sync.Map
|
||||||
authManager auth.Manager
|
authManager auth.Manager
|
||||||
|
|
||||||
|
syncLimiter *rate.Limiter
|
||||||
|
loginLimiter *rate.Limiter
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewServer creates a new Management server
|
// NewServer creates a new Management server
|
||||||
@@ -77,6 +82,16 @@ func NewServer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loginRatePerS, err := strconv.Atoi(os.Getenv("NB_LOGIN_RATE_PER_M"))
|
||||||
|
if loginRatePerS == 0 || err != nil {
|
||||||
|
loginRatePerS = 300
|
||||||
|
}
|
||||||
|
|
||||||
|
syncRatePerS, err := strconv.Atoi(os.Getenv("NB_SYNC_RATE_PER_M"))
|
||||||
|
if syncRatePerS == 0 || err != nil {
|
||||||
|
syncRatePerS = 300
|
||||||
|
}
|
||||||
|
|
||||||
return &GRPCServer{
|
return &GRPCServer{
|
||||||
wgKey: key,
|
wgKey: key,
|
||||||
// peerKey -> event channel
|
// peerKey -> event channel
|
||||||
@@ -88,6 +103,8 @@ func NewServer(
|
|||||||
authManager: authManager,
|
authManager: authManager,
|
||||||
appMetrics: appMetrics,
|
appMetrics: appMetrics,
|
||||||
ephemeralManager: ephemeralManager,
|
ephemeralManager: ephemeralManager,
|
||||||
|
syncLimiter: rate.NewLimiter(rate.Every(time.Minute/time.Duration(syncRatePerS)), 1),
|
||||||
|
loginLimiter: rate.NewLimiter(rate.Every(time.Minute/time.Duration(loginRatePerS)), 1),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,12 +143,10 @@ func getRealIP(ctx context.Context) net.IP {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var syncLimiter = rate.NewLimiter(rate.Every(time.Minute/300), 1)
|
|
||||||
|
|
||||||
// Sync validates the existence of a connecting peer, sends an initial state (all available for the connecting peers) and
|
// Sync validates the existence of a connecting peer, sends an initial state (all available for the connecting peers) and
|
||||||
// notifies the connected peer of any updates (e.g. new peers under the same account)
|
// notifies the connected peer of any updates (e.g. new peers under the same account)
|
||||||
func (s *GRPCServer) Sync(req *proto.EncryptedMessage, srv proto.ManagementService_SyncServer) error {
|
func (s *GRPCServer) Sync(req *proto.EncryptedMessage, srv proto.ManagementService_SyncServer) error {
|
||||||
if !syncLimiter.Allow() {
|
if !s.syncLimiter.Allow() {
|
||||||
return status.Errorf(codes.Internal, "temp rate limit reached")
|
return status.Errorf(codes.Internal, "temp rate limit reached")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,14 +433,12 @@ func (s *GRPCServer) parseRequest(ctx context.Context, req *proto.EncryptedMessa
|
|||||||
return peerKey, nil
|
return peerKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var loginLimiter = rate.NewLimiter(rate.Every(time.Minute/300), 1)
|
|
||||||
|
|
||||||
// Login endpoint first checks whether peer is registered under any account
|
// Login endpoint first checks whether peer is registered under any account
|
||||||
// In case it is, the login is successful
|
// In case it is, the login is successful
|
||||||
// In case it isn't, the endpoint checks whether setup key is provided within the request and tries to register a peer.
|
// In case it isn't, the endpoint checks whether setup key is provided within the request and tries to register a peer.
|
||||||
// In case of the successful registration login is also successful
|
// In case of the successful registration login is also successful
|
||||||
func (s *GRPCServer) Login(ctx context.Context, req *proto.EncryptedMessage) (*proto.EncryptedMessage, error) {
|
func (s *GRPCServer) Login(ctx context.Context, req *proto.EncryptedMessage) (*proto.EncryptedMessage, error) {
|
||||||
if !loginLimiter.Allow() {
|
if !s.loginLimiter.Allow() {
|
||||||
return nil, status.Errorf(codes.Internal, "temp rate limit reached")
|
return nil, status.Errorf(codes.Internal, "temp rate limit reached")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user