gerardokaztro/iam-audit

GitHub: gerardokaztro/iam-audit

跨 AWS Organizations 多账户的 IAM 安全审计工具,自动发现陈旧 Access Key、MFA 缺失等问题并生成交互式报告。

Stars: 5 | Forks: 1

# 🔍 iam-audit [![Python](https://img.shields.io/badge/Python-3.13+-3776AB?style=flat&logo=python&logoColor=white)](https://python.org) [![AWS](https://img.shields.io/badge/AWS-boto3-FF9900?style=flat&logo=amazonaws&logoColor=white)](https://boto3.amazonaws.com) [![Docker](https://img.shields.io/badge/Docker-ready-2496ED?style=flat&logo=docker&logoColor=white)](https://hub.docker.com/r/gerardokaztro/iam-audit) [![Terraform](https://img.shields.io/badge/Terraform-1.14+-7B42BC?style=flat&logo=terraform&logoColor=white)](https://terraform.io) [![License](https://img.shields.io/badge/License-MIT-green?style=flat)](LICENSE) [![Author](https://img.shields.io/badge/AWS-Security%20Hero-FF9900?style=flat&logo=amazonaws&logoColor=white)](https://aws.amazon.com/developer/community/heroes/) ## 它的功能是什么? `iam-audit` 会自动遍历你的 AWS Organization 中所有活跃账户,在每个账户中扮演一个审计角色,并生成一份包含以下内容的合并报告: - ✅ 每个用户的所有 **Access Keys** —— 状态、创建日期、最后使用时间和服务 - ✅ 每个用户的 **MFA** 状态(虚拟、硬件或缺失) - ✅ **控制台** 访问 —— 登录配置文件、最后使用时间、密码轮换 - ✅ 每个账户的 **Root account** —— 启用 MFA、活跃 Access Keys、通过 CloudTrail 记录的最后登录时间 - ✅ 每个用户的 **Risk scoring** —— 自动优先排序发现结果 - ✅ 通过 CloudTrail 的 **修复趋势** —— 追踪随时间推移的纠正措施 - ✅ **交互式 HTML Dashboard** —— 具有全局过滤器、图表和发现结果表 所有这些都无需创建额外的长期凭证。该脚本使用 `sts:AssumeRole` —— 自动过期的临时凭证。 ## 为什么会有这个工具? 在多账户环境中,没有人能拥有凭证的统一视图。旧的 Access Keys 不会出现在任何默认的 Dashboard 中。它们不会生成警报。也不会打扰任何人。它们只是在等待。 这个脚本会找到它们。 ## 使用模式 | | **本地模式 (Local)** | **Fargate** | |---|---|---| | **运行方式** | 你机器上的 Docker | ECS Fargate —— 自动 | | **触发器** | 手动 | EventBridge —— 周一上午 9 点 | | **输出** | 本地 `./output/` + `localhost:8000` | S3 + 带有预签名 URL 的 Slack | | **基础设施** | 无 | Security 账户中的 Terraform | | **适用场景** | 临时审计 | 每周持续监控 | ## 先决条件 ### 本地模式 - 已安装 Docker - 本地已配置 AWS 凭证 (`~/.aws`) - 在每个成员账户中部署了具有 IAM 和 CloudTrail 读取权限的审计角色 - Management 账户中具有 `organizations:ListAccounts` 和向子账户 `sts:AssumeRole` 的角色 ### Fargate 模式 除了上述内容外,还需要: - Terraform >= 1.14.0 - 具有 Security 账户管理员访问权限的 AWS CLI - 一个 Slack webhook URL —— [如何创建](https://api.slack.com/messaging/webhooks) - 一个用于 Terraform state 的 S3 bucket(只需手动创建一次 —— 见下方说明) - Management 账户中的 `iam-audit-org-reader` 角色(只需手动创建一次 —— 见下方说明) ## 快速开始 —— 本地模式 ### 选项 A —— Docker Hub(推荐) 无需克隆仓库,无需安装 Python,无需安装依赖。 ``` docker run --rm \ -v ~/.aws:/root/.aws \ -v $(pwd)/output:/app/output \ -p 8000:8000 \ gerardokaztro/iam-audit \ --profile YOUR-AWS-PROFILE \ --role YOUR-AUDIT-ROLE ``` 可用镜像位于:[hub.docker.com/r/gerardokaztro/iam-audit](https://hub.docker.com/r/gerardokaztro/iam-audit) ### 选项 B —— 本地构建 ``` git clone https://github.com/gerardokaztro/iam-audit cd iam-audit docker buildx build \ --platform linux/amd64,linux/arm64 \ -t iam-audit . docker run --rm \ -v ~/.aws:/root/.aws \ -v $(pwd)/output:/app/output \ -p 8000:8000 \ iam-audit \ --profile YOUR-AWS-PROFILE \ --role YOUR-AUDIT-ROLE ``` ### 选项 C —— 无 Docker ``` pip install -r requirements.txt python src/iam_audit.py --profile YOUR-AWS-PROFILE --role YOUR-AUDIT-ROLE ``` 扫描完成后,在浏览器中打开 `http://localhost:8000` 查看交互式 Dashboard。 按 `Ctrl+C` 停止服务器。 ## 快速开始 —— Fargate 模式 ### 第 1 步 —— 创建 Terraform state bucket(一次性) ``` # 将 ACCOUNT-ID 替换为您的 Security 账户 ID aws s3api create-bucket \ --bucket iam-audit-tfstate-ACCOUNT-ID \ --profile YOUR-SECURITY-PROFILE aws s3api put-bucket-versioning \ --bucket iam-audit-tfstate-ACCOUNT-ID \ --versioning-configuration Status=Enabled \ --profile YOUR-SECURITY-PROFILE aws s3api put-public-access-block \ --bucket iam-audit-tfstate-ACCOUNT-ID \ --public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true" \ --profile YOUR-SECURITY-PROFILE ``` ### 第 2 步 —— 在 Management 账户中创建审计角色(一次性) 此角色允许 Security 账户中的 Task Role 列出组织账户,然后扮演每个子账户中的审计角色。 ``` # 将 SECURITY-ACCOUNT-ID 替换为您的 Security 账户 ID aws iam create-role \ --role-name iam-audit-org-reader \ --assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::SECURITY-ACCOUNT-ID:role/iam-audit-task-role" }, "Action": "sts:AssumeRole" }] }' \ --profile YOUR-MANAGEMENT-PROFILE aws iam attach-role-policy \ --role-name iam-audit-org-reader \ --policy-arn arn:aws:iam::aws:policy/AWSOrganizationsReadOnlyAccess \ --profile YOUR-MANAGEMENT-PROFILE aws iam put-role-policy \ --role-name iam-audit-org-reader \ --policy-name assume-member-accounts \ --policy-document '{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::*:role/YOUR-AUDIT-ROLE-NAME" }] }' \ --profile YOUR-MANAGEMENT-PROFILE ``` ### 第 3 步 —— 配置并部署 Terraform ``` cd infra cp backend.hcl.example backend.hcl cp terraform.tfvars.example terraform.tfvars ``` 使用你的 state bucket 信息编辑 `backend.hcl`: ``` bucket = "iam-audit-tfstate-ACCOUNT-ID" key = "iam-audit/terraform.tfstate" region = "us-east-1" profile = "YOUR-SECURITY-PROFILE" ``` 使用你的值编辑 `terraform.tfvars`: ``` aws_region = "us-east-1" aws_profile = "YOUR-SECURITY-PROFILE" environment = "production" tfstate_bucket = "iam-audit-tfstate-ACCOUNT-ID" reports_bucket_name = "iam-audit-reports-ACCOUNT-ID" management_account_id = "YOUR-MANAGEMENT-ACCOUNT-ID" audit_role_name = "YOUR-AUDIT-ROLE-NAME" slack_webhook_url = "https://hooks.slack.com/services/XXX/YYY/ZZZ" ``` 部署: ``` terraform init -backend-config=backend.hcl terraform plan terraform apply ``` 审计将自动在每周一上午 9 点(利马,UTC-5)运行。手动触发: ``` aws ecs run-task \ --cluster iam-audit-cluster \ --task-definition iam-audit \ --launch-type FARGATE \ --network-configuration "awsvpcConfiguration={subnets=[SUBNET-ID],securityGroups=[SG-ID],assignPublicIp=ENABLED}" \ --profile YOUR-SECURITY-PROFILE ``` ## 权限配置 每个子账户中的角色需要 IAM 和 CloudTrail 的读取权限: ``` { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "iam:ListUsers", "iam:ListAccessKeys", "iam:GetAccessKeyLastUsed", "iam:ListMFADevices", "iam:GetLoginProfile", "iam:GetAccountSummary", "cloudtrail:LookupEvents" ], "Resource": "*" } ] } ``` ## 输出 **本地模式** —— 文件保存在 `./output/`: | 文件 | 内容 | |---|---| | `iam_audit_report_TIMESTAMP.html` | 带有过滤器、图表和发现结果表的交互式 Dashboard | | `iam_audit_report_TIMESTAMP.csv` | 按用户和账户列出的 IAM 发现结果 | | `root_audit_report_TIMESTAMP.csv` | 按账户列出的 Root 账户状态 | | `cloudtrail_events_TIMESTAMP.csv` | 用于追踪修复情况的 CloudTrail IAM 事件 | **Fargate 模式** —— 文件上传至 S3: ``` s3://iam-audit-reports-ACCOUNT-ID/ └── reports/ └── YYYY-MM-DD/ ├── iam_audit_report_TIMESTAMP.html ├── iam_audit_report_TIMESTAMP.csv ├── root_audit_report_TIMESTAMP.csv └── cloudtrail_events_TIMESTAMP.csv ``` 报告将在 90 天后自动删除(生命周期策略)。HTML Dashboard 的预签名 URL 有效期为 48 小时,并通过 Slack 发送。 ## 已部署的基础设施(Fargate 模式) 所有基础设施都位于 Security 账户中,并使用 Terraform 管理: | 资源 | 用途 | |---|---| | ECS Fargate Task | 运行审计脚本 | | EventBridge Scheduler | 每周一利马时间上午 9 点触发任务 | | S3 Bucket | 存储报告(生命周期 90 天) | | Secrets Manager | 加密存储 Slack webhook URL | | IAM Task Role | 扮演角色和写入 S3 的权限 | | IAM Execution Role | 启动容器和读取 secrets 的权限 | | CloudWatch Log Group | 任务日志 —— 保留 30 天 | | Security Group | 仅出站 (Egress only) —— 容器不暴露端口 | ## 与 AWS Security Maturity Model v2 的关系 此脚本有助于推进 [AWS Security Maturity Model v2](https://maturitymodel.security.aws.dev/en/model/) 中的特定控制项: | 阶段 | 控制项 | 此脚本如何提供帮助 | |---|---|---| | Phase 1 — Quick Wins | Multi-Factor Authentication | 识别没有 MFA 的用户和 Root 账户 | | Phase 2 — Foundational | Use Temporary Credentials | 暴露拥有活跃长期 Access Keys 的用户 | | Phase 2 — Foundational | Protect Root Credentials | 检测没有 MFA、拥有活跃 AK 且近期有登录记录的 Root | ## 已知限制 - CloudTrail 默认在 `us-east-1` 查询 —— IAM 是全球性的,但事件是区域性的 - 未部署审计角色的账户将被忽略并在控制台显示错误 —— 这本身就是一个发现 - 由于 CloudTrail API 的限制,`lookup_events` 仅返回过去 90 天的事件 - 如果 Management 账户未部署审计角色,它将被排除在子账户审计之外 —— 这是预期行为 ## 路线图 - [x] 多账户 IAM 用户和 Access Keys 审计 - [x] 用户风险评分 - [x] 带有全局过滤器的交互式 HTML Dashboard - [x] 通过 CloudTrail 的修复趋势 - [x] Root 账户检测 —— MFA、Access Keys、最后登录 - [x] Docker 化 —— 镜像可在 Docker Hub 上获取 - [x] 带有摘要卡片和预签名 URL 的 Slack 通知 - [x] 通过 ECS Fargate + EventBridge 进行计划执行 - [x] 使用 Terraform 的基础设施即代码 - [x] 使用 GitHub Actions 的安全管道 —— secrets、SAST、镜像扫描、IaC 扫描 - [x] 供应链加固 —— digest pinning + 使用 Harden-Runner 进行出站阻断 ## 仓库结构 ``` iam-audit/ ├── src/ │ ├── iam_audit.py # Script principal │ └── template.html # Template del dashboard HTML ├── infra/ │ ├── main.tf # Orquestador — llama a todos los módulos │ ├── variables.tf # Variables globales │ ├── outputs.tf # Outputs globales │ ├── backend.hcl.example # Template de configuración del backend │ ├── terraform.tfvars.example # Template de variables │ └── modules/ │ ├── s3/ # Bucket de reportes │ ├── iam/ # Task Role + Execution Role │ ├── ecs/ # Cluster + Task Definition │ ├── secrets/ # Secrets Manager │ └── eventbridge/ # Scheduler semanal ├── examples/ │ └── iam_audit_report_example.csv ├── output/ # Generado en tiempo de ejecución — en .gitignore ├── Dockerfile ├── requirements.txt └── README.md ``` ## 作者 **Gerardo Castro** —— AWS Security Hero · Cloud Security Engineer 我为 LATAM 的真实 AWS 环境构建安全工具。这个脚本源于现场的具体需求 —— 就像大多数值得使用的工具一样。 🔗 [LinkedIn](https://linkedin.com/in/gerardokaztro) 🔗 [Blog](https://roadtocloudsec.hashnode.dev) 📝 [包含背景和发现结果的完整文章](https://roadtocloudsec.hashnode.dev/encontre-access-key-2018-activa-produccion-python-boto3) ## 许可证 MIT —— 使用它,修改它,分享它。如果你用它发现了什么有趣的东西,请告诉我。
标签:AWS, Docker, DPI, ECS, ECS Fargate, HTML 仪表盘, IAM 审计, MFA 状态, Python, Root 账户安全, Slack 告警, Terraform, 凭据安全, 后端开发, 多云账户管理, 安全合规, 安全防御评估, 无后门, 漏洞探索, 网络代理, 访问键检查, 请求拦截, 逆向工具