ROX-13714: Implement a new rate limited logger, and use it to log failed auth messages. by clickboo · Pull Request #3984 · stackrox/stackrox · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions go.mod
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,8 @@ github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/golang-lru/v2 v2.0.1 h1:5pv5N1lT1fjLg2VQ5KWc7kmucp2x/kvFOnxuVTqZ6x4=
github.com/hashicorp/golang-lru/v2 v2.0.1/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
Expand Down
21 changes: 18 additions & 3 deletions pkg/grpc/authn/basic/extractor.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,26 @@ import (
"encoding/base64"
"fmt"
"strings"
"time"

"github.com/grpc-ecosystem/go-grpc-middleware/util/metautils"
"github.com/pkg/errors"
"github.com/stackrox/rox/pkg/auth/authproviders"
"github.com/stackrox/rox/pkg/errox"
"github.com/stackrox/rox/pkg/grpc/authn"
"github.com/stackrox/rox/pkg/grpc/requestinfo"
"github.com/stackrox/rox/pkg/logging"
)

var log = logging.LoggerForModule()
const (
cacheSize = 500
rateLimitFrequency = 5 * time.Minute
logBurstSize = 5
)

var (
log = logging.NewRateLimitLogger(logging.LoggerForModule(), cacheSize, 1, rateLimitFrequency, logBurstSize)
)

// Extractor is the identity extractor for the basic auth identity.
type Extractor struct {
Expand Down Expand Up @@ -52,11 +62,16 @@ func (e *Extractor) IdentityForRequest(ctx context.Context, ri requestinfo.Reque

username, password, err := parseBasicAuthToken(basicAuthToken)
if err != nil {
log.Warnf("failed to parse basic auth token: %s", err)
log.WarnL(ri.Hostname, "failed to parse basic auth token from %q: %v", ri.Hostname, err)
return nil, errors.New("failed to parse basic auth token")
}

return e.manager.IdentityForCreds(ctx, username, password, e.authProvider)
id, err := e.manager.IdentityForCreds(ctx, username, password, e.authProvider)
if errors.Is(err, errox.NotAuthorized) {
log.WarnL(ri.Hostname, "%q: %v", ri.Hostname, err)
return nil, err
}
return id, err
}

// NewExtractor returns a new identity extractor for basic auth.
Expand Down
14 changes: 11 additions & 3 deletions pkg/grpc/authn/interceptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package authn
import (
"context"
"errors"
"time"

"github.com/stackrox/rox/pkg/auth"
"github.com/stackrox/rox/pkg/contextutil"
Expand All @@ -12,21 +13,28 @@ import (
"gopkg.in/square/go-jose.v2/jwt"
)

const (
cacheSize = 500
rateLimitFrequency = 5 * time.Minute
logBurstSize = 5
)

var (
log = logging.LoggerForModule()
log = logging.NewRateLimitLogger(logging.LoggerForModule(), cacheSize, 1, rateLimitFrequency, logBurstSize)
)

type contextUpdater struct {
extractor IdentityExtractor
}

func (u contextUpdater) updateContext(ctx context.Context) (context.Context, error) {
id, err := u.extractor.IdentityForRequest(ctx, requestinfo.FromContext(ctx))
ri := requestinfo.FromContext(ctx)
id, err := u.extractor.IdentityForRequest(ctx, ri)
if err != nil {
if errors.Is(err, jwt.ErrExpired) {
log.Debugf("Cannot extract identity: token expired")
} else {
log.Warnf("Cannot extract identity: %v", err)
log.WarnL(ri.Hostname, "Cannot extract identity: %v", err)
}
// Ignore id value if error is not nil.
return context.WithValue(ctx, identityErrorContextKey{}, errox.NoCredentials.CausedBy(err)), nil
Expand Down
14 changes: 11 additions & 3 deletions pkg/grpc/authn/tokenbased/extractor.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"strings"
"time"

"github.com/pkg/errors"
"github.com/stackrox/rox/pkg/auth/authproviders"
Expand All @@ -16,7 +17,15 @@ import (
"github.com/stackrox/rox/pkg/sac"
)

var log = logging.LoggerForModule()
const (
cacheSize = 500
rateLimitFrequency = 5 * time.Minute
logBurstSize = 5
)

var (
log = logging.NewRateLimitLogger(logging.LoggerForModule(), cacheSize, 1, rateLimitFrequency, logBurstSize)
)

// NewExtractor returns a new token-based identity extractor.
func NewExtractor(roleStore permissions.RoleStore, tokenValidator tokens.Validator) authn.IdentityExtractor {
Expand All @@ -36,10 +45,9 @@ func (e *extractor) IdentityForRequest(ctx context.Context, ri requestinfo.Reque
if rawToken == "" {
return nil, nil
}

token, err := e.validator.Validate(ctx, rawToken)
if err != nil {
log.Warnf("Token validation failed: %v", err)
log.WarnL(ri.Hostname, "Token validation failed for hostname %v: %v", ri.Hostname, err)
return nil, errors.New("token validation failed")
}

Expand Down
10 changes: 9 additions & 1 deletion pkg/grpc/authn/userpki/extractor.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package userpki

import (
"context"
"time"

"github.com/stackrox/rox/pkg/auth/authproviders"
"github.com/stackrox/rox/pkg/auth/permissions"
Expand All @@ -12,8 +13,14 @@ import (
"github.com/stackrox/rox/pkg/sac"
)

const (
cacheSize = 500
rateLimitFrequency = 5 * time.Minute
logBurstSize = 5
)

var (
log = logging.LoggerForModule()
log = logging.NewRateLimitLogger(logging.LoggerForModule(), cacheSize, 1, rateLimitFrequency, logBurstSize)
)

// NewExtractor returns an IdentityExtractor that will map identities based
Expand Down Expand Up @@ -73,6 +80,7 @@ func (i extractor) IdentityForRequest(ctx context.Context, ri requestinfo.Reques
}
resolvedRoles, err := provider.RoleMapper().FromUserDescriptor(ctx, ud)
if err != nil {
log.WarnL(ri.Hostname, "Token validation failed for hostname %v: %v", ri.Hostname, err)
return nil, err
}
identity.resolvedRoles = resolvedRoles
Expand Down
68 changes: 68 additions & 0 deletions pkg/logging/rate_limited_logger.go