如何用boto3查询AWS IAM用户闲置天数及实现未登录用户锁定?
嘿,这个需求在AWS权限治理里太常见了!我来给你拆解成几个步骤,用boto3一步步实现——从查询闲置天数,到轮询活动记录,再到锁定长期未登录的用户。
1. 查询IAM用户的闲置天数
首先得明确:IAM本身不会直接存储用户的最后活跃时间,得从CloudTrail的事件日志里捞。用户通过用户名密码登录控制台的动作,会被CloudTrail记录为ConsoleLogin事件,咱们就靠这个来判断闲置时长。
步骤如下:
- 初始化boto3的IAM和CloudTrail客户端
- 获取所有IAM用户列表
- 对每个用户,查询CloudTrail中最近的
ConsoleLogin事件 - 计算当前时间与最后登录时间的差值,得到闲置天数
代码示例:
import boto3 from datetime import datetime, timezone def get_iam_user_idle_days(): # 初始化AWS客户端 iam_client = boto3.client('iam') cloudtrail_client = boto3.client('cloudtrail') # 获取账户下所有IAM用户 users = iam_client.list_users()['Users'] idle_user_info = [] for user in users: username = user['UserName'] user_create_date = user['CreateDate'].replace(tzinfo=timezone.utc) try: # 查询该用户最近一次控制台登录事件 events = cloudtrail_client.lookup_events( LookupAttributes=[ {'AttributeKey': 'Username', 'AttributeValue': username}, {'AttributeKey': 'EventName', 'AttributeValue': 'ConsoleLogin'} ], MaxResults=1, StartTime=datetime(2000, 1, 1, tzinfo=timezone.utc) # 覆盖所有历史记录 ) if events['Events']: last_login_time = events['Events'][0]['EventTime'] last_login_utc = last_login_time.replace(tzinfo=timezone.utc) idle_days = (datetime.now(timezone.utc) - last_login_utc).days last_login_str = last_login_time.strftime('%Y-%m-%d %H:%M:%S') else: # 用户从未登录过,闲置天数从创建时间算起 idle_days = (datetime.now(timezone.utc) - user_create_date).days last_login_str = '从未登录过' idle_user_info.append({ '用户名': username, '最后登录时间': last_login_str, '闲置天数': idle_days }) except Exception as e: print(f"获取用户 {username} 数据时出错: {str(e)}") continue return idle_user_info # 调用函数并打印结果 for info in get_iam_user_idle_days(): print(f"用户: {info['用户名']}, 最后登录: {info['最后登录时间']}, 闲置天数: {info['闲置天数']}")
2. 轮询用户活动并获取最后活跃时间
如果要长期监控用户活动,你可以把上面的脚本做成定时任务:
- 用Linux cron定期运行脚本(适合自建服务器)
- 或者用AWS Lambda配合CloudWatch Events(全托管方案,不用管服务器)
需要注意的细节:
- CloudTrail默认只保留90天的事件,要是需要查更久的历史,得提前配置CloudTrail归档到S3存储桶
- 如果你想监控API密钥的活动(不止控制台登录),可以去掉
EventName过滤,查该用户所有的CloudTrail事件,比如CreateAccessKey、ListRoles等操作
优化后的活跃时间查询函数(支持全活动类型):
def get_user_last_activity(username): cloudtrail_client = boto3.client('cloudtrail') # 查询该用户最近一次的任何活动事件 events = cloudtrail_client.lookup_events( LookupAttributes=[ {'AttributeKey': 'Username', 'AttributeValue': username} ], MaxResults=1, StartTime=datetime(2000, 1, 1, tzinfo=timezone.utc) ) if events['Events']: last_activity_time = events['Events'][0]['EventTime'] activity_type = events['Events'][0]['EventName'] return { '最后活跃时间': last_activity_time.strftime('%Y-%m-%d %H:%M:%S'), '活动类型': activity_type } else: return { '最后活跃时间': '无活动记录', '活动类型': 'N/A' }
3. 锁定未使用用户名密码登录的用户
对于长期闲置(比如超过30天)或者从未登录过的用户,咱们可以禁用他们的控制台登录配置文件——这样用户就没法用用户名密码登录控制台了(如果用户有API密钥,你可以额外逻辑禁用密钥)。
代码示例(锁定闲置超过30天的用户):
def lock_idle_users(idle_threshold=30): iam_client = boto3.client('iam') idle_users = get_iam_user_idle_days() for user_info in idle_users: username = user_info['用户名'] idle_days = user_info['闲置天数'] if idle_days >= idle_threshold: try: # 先检查用户是否有登录配置文件(即是否设置过密码) iam_client.get_login_profile(UserName=username) # 禁用控制台登录功能 iam_client.update_login_profile( UserName=username, PasswordEnabled=False ) print(f"已锁定用户 {username} - 闲置时长: {idle_days} 天") except iam_client.exceptions.NoSuchEntityException: # 用户没有登录配置文件,本来就没法用密码登录,直接跳过 print(f"用户 {username} 未设置过登录密码,无需锁定") except Exception as e: print(f"锁定用户 {username} 失败: {str(e)}") # 调用函数,锁定闲置30天以上的用户 lock_idle_users(idle_threshold=30)
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

