Prevent brute forcing : telemetry oss changes (#18718)
* Prevent brute forcing : telemetry oss changes * adding changelog
This commit is contained in:
parent
cdae007e30
commit
6e04e4ede1
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:improvement
|
||||||
|
core: Add vault.core.locked_users telemetry metric to emit information about total number of locked users.
|
||||||
|
```
|
|
@ -3425,6 +3425,7 @@ func (c *Core) runLockedUserEntryUpdates(ctx context.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
totalLockedUsersCount := 0
|
||||||
for _, nsID := range nsIDs {
|
for _, nsID := range nsIDs {
|
||||||
// get the list of mount accessors of locked users for each namespace
|
// get the list of mount accessors of locked users for each namespace
|
||||||
mountAccessors, err := c.barrier.List(ctx, coreLockedUsersPath+nsID)
|
mountAccessors, err := c.barrier.List(ctx, coreLockedUsersPath+nsID)
|
||||||
|
@ -3439,18 +3440,23 @@ func (c *Core) runLockedUserEntryUpdates(ctx context.Context) error {
|
||||||
// if incorrect, update the entry in userFailedLoginInfo map
|
// if incorrect, update the entry in userFailedLoginInfo map
|
||||||
for _, mountAccessorPath := range mountAccessors {
|
for _, mountAccessorPath := range mountAccessors {
|
||||||
mountAccessor := strings.TrimSuffix(mountAccessorPath, "/")
|
mountAccessor := strings.TrimSuffix(mountAccessorPath, "/")
|
||||||
if err := c.runLockedUserEntryUpdatesForMountAccessor(ctx, mountAccessor, coreLockedUsersPath+nsID+mountAccessorPath); err != nil {
|
lockedAliasesCount, err := c.runLockedUserEntryUpdatesForMountAccessor(ctx, mountAccessor, coreLockedUsersPath+nsID+mountAccessorPath)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
totalLockedUsersCount = totalLockedUsersCount + lockedAliasesCount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// emit locked user count metrics
|
||||||
|
metrics.SetGaugeWithLabels([]string{"core", "locked_users"}, float32(totalLockedUsersCount), nil)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// runLockedUserEntryUpdatesForMountAccessor updates the storage entry for each locked user (alias name)
|
// runLockedUserEntryUpdatesForMountAccessor updates the storage entry for each locked user (alias name)
|
||||||
// if the entry is stale, it removes it from storage and userFailedLoginInfo map if present
|
// if the entry is stale, it removes it from storage and userFailedLoginInfo map if present
|
||||||
// if the entry is not stale, it updates the userFailedLoginInfo map with correct values for entry if incorrect
|
// if the entry is not stale, it updates the userFailedLoginInfo map with correct values for entry if incorrect
|
||||||
func (c *Core) runLockedUserEntryUpdatesForMountAccessor(ctx context.Context, mountAccessor string, path string) error {
|
func (c *Core) runLockedUserEntryUpdatesForMountAccessor(ctx context.Context, mountAccessor string, path string) (int, error) {
|
||||||
// get mount entry for mountAccessor
|
// get mount entry for mountAccessor
|
||||||
mountEntry := c.router.MatchingMountByAccessor(mountAccessor)
|
mountEntry := c.router.MatchingMountByAccessor(mountAccessor)
|
||||||
if mountEntry == nil {
|
if mountEntry == nil {
|
||||||
|
@ -3462,9 +3468,11 @@ func (c *Core) runLockedUserEntryUpdatesForMountAccessor(ctx context.Context, mo
|
||||||
// get the list of aliases for mount accessor
|
// get the list of aliases for mount accessor
|
||||||
aliases, err := c.barrier.List(ctx, path)
|
aliases, err := c.barrier.List(ctx, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lockedAliasesCount := len(aliases)
|
||||||
|
|
||||||
// check storage entry for each alias to update
|
// check storage entry for each alias to update
|
||||||
for _, alias := range aliases {
|
for _, alias := range aliases {
|
||||||
loginUserInfoKey := FailedLoginUser{
|
loginUserInfoKey := FailedLoginUser{
|
||||||
|
@ -3474,7 +3482,7 @@ func (c *Core) runLockedUserEntryUpdatesForMountAccessor(ctx context.Context, mo
|
||||||
|
|
||||||
existingEntry, err := c.barrier.Get(ctx, path+alias)
|
existingEntry, err := c.barrier.Get(ctx, path+alias)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if existingEntry == nil {
|
if existingEntry == nil {
|
||||||
|
@ -3484,7 +3492,7 @@ func (c *Core) runLockedUserEntryUpdatesForMountAccessor(ctx context.Context, mo
|
||||||
var lastLoginTime int
|
var lastLoginTime int
|
||||||
err = jsonutil.DecodeJSON(existingEntry.Value, &lastLoginTime)
|
err = jsonutil.DecodeJSON(existingEntry.Value, &lastLoginTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
lastFailedLoginTimeFromStorageEntry := time.Unix(int64(lastLoginTime), 0)
|
lastFailedLoginTimeFromStorageEntry := time.Unix(int64(lastLoginTime), 0)
|
||||||
|
@ -3497,15 +3505,16 @@ func (c *Core) runLockedUserEntryUpdatesForMountAccessor(ctx context.Context, mo
|
||||||
if time.Now().After(lastFailedLoginTimeFromStorageEntry.Add(lockoutDurationFromConfiguration)) {
|
if time.Now().After(lastFailedLoginTimeFromStorageEntry.Add(lockoutDurationFromConfiguration)) {
|
||||||
// stale entry, remove from storage
|
// stale entry, remove from storage
|
||||||
if err := c.barrier.Delete(ctx, path+alias); err != nil {
|
if err := c.barrier.Delete(ctx, path+alias); err != nil {
|
||||||
return err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove entry for this user from userFailedLoginInfo map if present as the user is not locked
|
// remove entry for this user from userFailedLoginInfo map if present as the user is not locked
|
||||||
if failedLoginInfoFromMap != nil {
|
if failedLoginInfoFromMap != nil {
|
||||||
if err = c.UpdateUserFailedLoginInfo(ctx, loginUserInfoKey, nil, true); err != nil {
|
if err = c.UpdateUserFailedLoginInfo(ctx, loginUserInfoKey, nil, true); err != nil {
|
||||||
return err
|
return 0, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
lockedAliasesCount -= 1
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3519,11 +3528,11 @@ func (c *Core) runLockedUserEntryUpdatesForMountAccessor(ctx context.Context, mo
|
||||||
if failedLoginInfoFromMap != &actualFailedLoginInfo {
|
if failedLoginInfoFromMap != &actualFailedLoginInfo {
|
||||||
// entry is invalid, updating the entry in userFailedLoginMap with correct information
|
// entry is invalid, updating the entry in userFailedLoginMap with correct information
|
||||||
if err = c.UpdateUserFailedLoginInfo(ctx, loginUserInfoKey, &actualFailedLoginInfo, false); err != nil {
|
if err = c.UpdateUserFailedLoginInfo(ctx, loginUserInfoKey, &actualFailedLoginInfo, false); err != nil {
|
||||||
return err
|
return 0, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return lockedAliasesCount, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PopMFAResponseAuthByID pops an item from the mfaResponseAuthQueue by ID
|
// PopMFAResponseAuthByID pops an item from the mfaResponseAuthQueue by ID
|
||||||
|
|
Loading…
Reference in New Issue