diff --git a/go.mod b/go.mod index 2b3ef9cd6..864d36864 100644 --- a/go.mod +++ b/go.mod @@ -106,6 +106,7 @@ require ( golang.org/x/oauth2 v0.24.0 golang.org/x/sync v0.13.0 golang.org/x/term v0.31.0 + golang.org/x/time v0.5.0 google.golang.org/api v0.177.0 gopkg.in/yaml.v3 v3.0.1 gorm.io/driver/mysql v1.5.7 @@ -240,7 +241,6 @@ require ( golang.org/x/image v0.18.0 // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/text v0.24.0 // indirect - golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240509183442-62759503f434 // indirect diff --git a/management/server/peer.go b/management/server/peer.go index 9ff80442e..c07aefaa2 100644 --- a/management/server/peer.go +++ b/management/server/peer.go @@ -4,6 +4,7 @@ import ( "context" "crypto/sha256" b64 "encoding/base64" + "errors" "fmt" "net" "slices" @@ -14,6 +15,7 @@ import ( "github.com/rs/xid" log "github.com/sirupsen/logrus" "golang.org/x/exp/maps" + "golang.org/x/time/rate" "github.com/netbirdio/netbird/management/domain" "github.com/netbirdio/netbird/management/server/geolocation" @@ -780,11 +782,17 @@ func (am *DefaultAccountManager) handlePeerLoginNotFound(ctx context.Context, lo return nil, nil, nil, status.Errorf(status.Internal, "failed while logging in peer") } +var loginLimiter = rate.NewLimiter(rate.Every(time.Minute/500), 1) + // LoginPeer logs in or registers a peer. // If peer doesn't exist the function checks whether a setup key or a user is present and registers a new peer if so. func (am *DefaultAccountManager) LoginPeer(ctx context.Context, login types.PeerLogin) (*nbpeer.Peer, *types.NetworkMap, []*posture.Checks, error) { accountID, err := am.Store.GetAccountIDByPeerPubKey(ctx, login.WireGuardPubKey) if err != nil { + if !loginLimiter.Allow() { + return nil, nil, nil, errors.New("rate limit exceeded") + } + return am.handlePeerLoginNotFound(ctx, login, err) }