gerardokaztro/iam-audit
GitHub: gerardokaztro/iam-audit
跨 AWS Organizations 多账户的 IAM 安全审计工具,自动发现陈旧 Access Key、MFA 缺失等问题并生成交互式报告。
Stars: 5 | Forks: 1
# 🔍 iam-audit
[](https://python.org)
[](https://boto3.amazonaws.com)
[](https://hub.docker.com/r/gerardokaztro/iam-audit)
[](https://terraform.io)
[](LICENSE)
[](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, 凭据安全, 后端开发, 多云账户管理, 安全合规, 安全防御评估, 无后门, 漏洞探索, 网络代理, 访问键检查, 请求拦截, 逆向工具