You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现AWS IAM用户3次登录失败后锁定并定时解锁?

IAM用户连续登录失败锁定方案审核与改进

现有方案的问题点

1. IAM策略问题

  • 直接Deny *过于严格,会禁止该用户所有AWS操作(包括已授权的资源访问),风险过高,应仅限制登录相关操作。
  • 条件aws:MultiFactorAuthAge针对已完成MFA验证的会话,与目标的「未使用MFA的用户」场景不匹配,属于无效条件。
  • aws:FailedLoginAttempts的逻辑依赖AWS内部的失败次数统计,但该值并非实时累计的连续失败次数,无法准确触发预期规则。

2. Lambda函数问题

  • 未处理重复触发场景:用户第4次登录失败时,会重复执行attach_user_policy,导致同一策略多次附加(属于冗余操作)。
  • 缺少自动解锁逻辑:仅实现锁定,无法满足「5分钟后自动解锁」的需求。
  • 未添加异常处理:若事件中userName字段缺失或IAM调用失败,Lambda会直接报错终止。

3. CloudWatch事件规则问题

  • 仅捕获单次登录失败事件,无法实现「60秒内3次失败」的统计触发逻辑,会导致每次失败都调用Lambda,而非累计到3次才触发。

改进后的成熟实现方案

1. 优化后的IAM锁定策略(仅限制登录操作)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyConsoleLogin",
            "Effect": "Deny",
            "Action": [
                "sts:GetSessionToken",
                "sts:GetFederationToken",
                "iam:ListAccountAliases",
                "signin:Login"
            ],
            "Resource": "*"
        }
    ]
}

说明:仅禁止控制台登录、获取会话令牌等核心登录操作,不影响用户已授权的资源访问(如S3、EC2等)。

2. 完善后的Lambda函数(含锁定+定时解锁)

import boto3
import os
from datetime import datetime, timedelta
import json

iam = boto3.client('iam')
events = boto3.client('events')

LOCK_POLICY_ARN = os.environ['LOCK_POLICY_ARN']
LOCK_DURATION_MINUTES = 5

def lambda_handler(event, context):
    try:
        # 提取用户名
        username = event['detail']['userIdentity']['userName']
        
        # 检查是否已附加锁定策略,避免重复操作
        attached_policies = iam.list_attached_user_policies(UserName=username)
        policy_exists = any(policy['PolicyArn'] == LOCK_POLICY_ARN for policy in attached_policies['AttachedPolicies'])
        
        if not policy_exists:
            iam.attach_user_policy(
                UserName=username,
                PolicyArn=LOCK_POLICY_ARN
            )
            print(f"已锁定用户: {username}")
            
            # 配置5分钟后自动解锁的定时事件
            unlock_time = datetime.utcnow() + timedelta(minutes=LOCK_DURATION_MINUTES)
            rule_name = f"UnlockUser-{username}-{int(datetime.utcnow().timestamp())}"
            events.put_rule(
                Name=rule_name,
                ScheduleExpression=f"at({unlock_time.strftime('%Y-%m-%dT%H:%M:%S')})",
                State='ENABLED'
            )
            events.put_targets(
                Rule=rule_name,
                Targets=[
                    {
                        'Id': '1',
                        'Arn': context.invoked_function_arn.replace('lock', 'unlock'),
                        'Input': json.dumps({'username': username, 'rule_name': rule_name})
                    }
                ]
            )
        else:
            print(f"用户 {username} 已处于锁定状态,无需重复操作")
            
    except Exception as e:
        print(f"处理失败: {str(e)}")
        raise e

# 解锁专用Lambda函数
def unlock_user_handler(event, context):
    try:
        username = event['username']
        rule_name = event['rule_name']
        
        iam.detach_user_policy(
            UserName=username,
            PolicyArn=LOCK_POLICY_ARN
        )
        print(f"已解锁用户: {username}")
        
        # 删除临时解锁规则
        events.remove_targets(Rule=rule_name, Ids=['1'])
        events.delete_rule(Name=rule_name)
        
    except Exception as e:
        print(f"解锁失败: {str(e)}")
        raise e

说明:

  • 通过环境变量配置策略ARN,提高可维护性。
  • 锁定前检查策略是否已附加,避免冗余操作。
  • 利用CloudWatch Events定时触发解锁逻辑,实现5分钟自动解锁。
  • 添加异常捕获与日志输出,便于问题排查。

3. CloudWatch Alarm(实现60秒内3次失败触发)

  1. 基于CloudTrail的ConsoleLogin失败事件创建Metric Filter:

    • 过滤规则:{$.eventName = "ConsoleLogin" && $.responseElements.ConsoleLogin = "Failure"}
    • 命名空间:IAM/LoginFailures
    • 指标名称:FailedLoginAttempts
    • 维度:userName
  2. 创建CloudWatch Alarm:

    • 指标:IAM/LoginFailures/FailedLoginAttempts(按userName维度)
    • 统计周期:60秒
    • 阈值:>=3
    • 触发动作:调用锁定Lambda函数

额外优化建议

  • 针对使用MFA的用户,可在策略中添加例外规则,避免影响已启用MFA的安全用户。
  • 记录锁定/解锁操作到CloudTrail,便于审计追溯。
  • 配置SNS通知,当用户被锁定时发送告警邮件给管理员。

内容的提问来源于stack exchange,提问作者Mohamad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 23:00:43