TocConsulting/ec2-security-scanner
GitHub: TocConsulting/ec2-security-scanner
一款全面的 AWS EC2 安全扫描器,提供 46 项安全检查与多框架合规映射,帮助企业自动化评估云基础设施的安全态势与合规水平。
Stars: 4 | Forks: 0
一个全面且生产就绪的 AWS EC2 安全扫描器,涵盖 8 大类共 46 项安全检查,并提供针对 AWS FSBP、CIS、PCI DSS、HIPAA、SOC 2、ISO 27001/27017/27018、GDPR 和 NIST SP 800-53 Rev5(共计 137 项控制措施)的合规性映射。具有多线程扫描、UserData 密钥检测以及交互式 HTML 仪表板等功能。
## 主要特性
### **全面的安全分析**
- **实例安全**:强制执行 IMDSv2、公网 IP 检测、IAM profile 验证、UserData 密钥扫描
- **网络安全**:安全组分析(SSH、RDP、高风险端口、出站流量、授权端口)、VPC flow logs、NACLs、强制 VPN IKEv2
- **存储安全**:EBS 加密(针对单个卷和账户默认)、公开及跨账户共享的快照、公开的 AMI、备份覆盖情况、EBS 快照阻止公开访问
- **访问控制**:IAM 角色最小权限分析、密钥对使用情况、串行控制台状态、EC2 Instance Connect endpoint
- **日志与监控**:CloudTrail、CloudWatch 警报、SSM 托管状态、GuardDuty runtime 监控
- **补丁与漏洞**:SSM 补丁合规性、AMI 使用期限、Amazon Inspector v2 发现结果
- **网络暴露**:未使用的 EIP、启动模板公网 IP、子网自动分配、VPC 阻止公开访问、Transit Gateway 自动接受、VPC DHCP 自定义 DNS(DNS 劫持)检测
- **标签与清单**:必填标签、长期停止的实例、未使用的安全组
### **合规框架**
- **AWS Foundational Security Best Practices (FSBP)**:32 项控制措施(29 项官方 `EC2.x` 控制措施 + 3 项针对 UserData 密钥、出站流量和公开 AMI 的自定义 `BP.*` 最佳实践控制措施)
- **CIS AWS Foundations Benchmark v5.0**:7 项适用于 EC2 的控制措施
- **PCI DSS v4.0.1**:12 项控制措施
- **HIPAA Security Rule**:10 项控制措施
- **SOC 2**:13 项控制措施(信任服务标准)
- **ISO 27001:2022**:17 项控制措施
- **ISO 27017:2015**:7 项云安全控制措施
- **ISO 27018:2019**:4 项 PII 保护控制措施
- **GDPR (EU) 2016/679**:8 项控制措施(第 5、25、32、33、44-49 条)
- **NIST SP 800-53 Rev5**:27 项控制措施
- **扫描级合规性评分**:自动计算每个框架的合规百分比,其中账户/区域级别的控制措施(GuardDuty、CloudTrail、VPC BPA 等)只计算**一次**,而不是在每个实例上重复计算
### **性能与易用性**
- **多线程扫描**:使用 ThreadPoolExecutor 并行分析实例
- **三层扫描**:账户 → VPC → 实例,避免冗余的 API 调用
- **丰富的控制台输出**:进度条、彩色输出和格式化表格
- **多种报告格式**:JSON、CSV、HTML 以及特定于合规性的报告
- **美观的 HTML 报告**:带有 Chart.js 可视化的交互式仪表板
- **灵活的目标定位**:扫描所有实例、特定 ID,或按标签和状态进行筛选
### **生产就绪**
- **模块化架构**:采用外观模式,包含 8 个专用检查器模块
- **线程安全会话**:线程级的 boto3 会话管理
- **优雅降级**:权限错误(`AccessDenied`、`UnauthorizedOperation`、`AuthFailure` 等)会作为 ERROR 严重级别的发现结果显示,而不会导致扫描崩溃
- **双层评分**:针对实例安全态势的实例评分 + 针对账户/VPC 安全态势的独立环境评分(只计算一次,绝不在实例间成倍增加)
- **非叠加评分**:重叠的安全组入站暴露惩罚(SSH/RDP/高风险/远程管理/未授权端口)仅取最高惩罚扣分
- **严格只读**:没有任何 AWS API 调用会改变状态 — 在生产环境中运行是安全的
## 快速开始
### 安装
```
# 从 PyPI 安装
pip install ec2-security-scanner
# 或从源码安装
git clone https://github.com/TocConsulting/ec2-security-scanner.git
cd ec2-security-scanner
pip install .
```
### Docker 安装
```
# 从 Docker Hub 拉取
docker pull tarekcheikh/ec2-security-scanner:latest
```
### 基本用法
```
# 扫描默认区域中所有正在运行的 EC2 实例
ec2-security-scanner security
# 使用特定的 AWS profile 进行扫描
ec2-security-scanner security --profile production
# 仅扫描特定实例
ec2-security-scanner security -i i-0abc123def456 -i i-0def789abc012
# 包括已停止的实例
ec2-security-scanner security --state-filter all
# 按 tags 过滤
ec2-security-scanner security --tag-filter Environment=production --tag-filter Team=platform
# 仅合规报告
ec2-security-scanner security --compliance-only
```
## 命令
### 安全命令
扫描 EC2 实例的安全漏洞和合规问题。
```
ec2-security-scanner security [OPTIONS]
Options:
-i, --instance-id TEXT Specific instance ID(s) to scan (multiple)
--exclude-instance TEXT Instance ID(s) to exclude
--compliance-only Print detailed per-framework failed controls
--tag-filter TEXT Filter by tag (Key=Value, multiple)
--state-filter TEXT Instance state: running, stopped, all (default: running)
-r, --region TEXT AWS region (default: us-east-1)
-p, --profile TEXT AWS profile name
-o, --output-dir TEXT Output directory (default: ./output)
-f, --output-format TEXT Report format: json, csv, html, all (default: all)
-w, --max-workers INTEGER Worker threads (default: 5)
-q, --quiet Suppress console output except errors
-d, --debug Enable debug logging
-h, --help Show help
# 顶级选项:
# ec2-security-scanner --version
# ec2-security-scanner --help
```
**示例:**
```
# 使用默认设置扫描所有正在运行的实例
ec2-security-scanner security
# 排除特定实例
ec2-security-scanner security --exclude-instance i-0abc123 --exclude-instance i-0def456
# 带有 HTML 输出的快速仅合规扫描
ec2-security-scanner security --compliance-only -f html -p production
# 使用更多 threads 的高性能扫描
ec2-security-scanner security -w 20 -r eu-west-1
# 仅 JSON 报告,静默模式(用于 CI/CD)
ec2-security-scanner security -f json -q
```
## Docker 使用
使用 Docker 运行扫描器,无需在本地安装 Python 依赖。
### 拉取 Docker 镜像
```
# 拉取最新版本
docker pull tarekcheikh/ec2-security-scanner:latest
# 或固定特定版本(将 X.Y.Z 替换为您想要的 release)
docker pull tarekcheikh/ec2-security-scanner:X.Y.Z
```
### 基本 Docker 命令
```
# 显示帮助
docker run --rm tarekcheikh/ec2-security-scanner --help
# 显示 security 命令的帮助
docker run --rm tarekcheikh/ec2-security-scanner security --help
```
### 使用 Docker 进行安全扫描
**AWS 凭证:** 以下示例挂载了 `~/.aws` 以提供凭证。默认情况下,扫描器使用 `default` profile。使用 `--profile
` 指定其他 profile。
```
# 使用默认的 AWS profile 扫描所有实例
docker run --rm \
-v ~/.aws:/root/.aws:ro \
-v $(pwd)/output:/app/output \
tarekcheikh/ec2-security-scanner security
# 使用特定的 AWS profile 进行扫描
docker run --rm \
-v ~/.aws:/root/.aws:ro \
-v $(pwd)/output:/app/output \
tarekcheikh/ec2-security-scanner security --profile production
# 仅扫描特定实例
docker run --rm \
-v ~/.aws:/root/.aws:ro \
-v $(pwd)/output:/app/output \
tarekcheikh/ec2-security-scanner security -i i-0abc123def456
# 仅合规扫描
docker run --rm \
-v ~/.aws:/root/.aws:ro \
-v $(pwd)/output:/app/output \
tarekcheikh/ec2-security-scanner security --compliance-only
```
### 使用环境变量传递 AWS 凭证
除了挂载 `~/.aws` 外,您还可以通过环境变量传递凭证:
```
# 通过环境变量传递 AWS 凭证
docker run --rm \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
-e AWS_DEFAULT_REGION=us-east-1 \
-v $(pwd)/output:/app/output \
tarekcheikh/ec2-security-scanner security
# 带有 session token(临时凭证 / assumed roles)
docker run --rm \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
-e AWS_SESSION_TOKEN \
-e AWS_DEFAULT_REGION=us-east-1 \
-v $(pwd)/output:/app/output \
tarekcheikh/ec2-security-scanner security
```
### Docker 卷挂载说明
| 挂载 | 用途 |
|-------|---------|
| `-v ~/.aws:/root/.aws:ro` | 挂载 AWS 凭证(只读)。除非指定了 `--profile`,否则使用 `default` profile |
| `-v $(pwd)/output:/app/output` | 将报告保存到您本地的 `./output` 目录 |
**重要提示:** 如果没有挂载输出卷,容器退出后将无法访问报告文件。
## 前提条件
### Python 要求
- Python 3.10 或更高版本
- 所需的包(自动安装):
- `boto3>=1.34.0`
- `botocore>=1.34.0`
- `rich>=13.0.0`
- `click>=8.1.0`
- `jinja2>=3.1.0`
### AWS 要求
- 已配置 AWS 凭证(通过 AWS CLI、环境变量或 IAM 角色)
- 所需权限:
```
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeInstances",
"ec2:DescribeInstanceAttribute",
"ec2:DescribeVolumes",
"ec2:DescribeSnapshots",
"ec2:DescribeSnapshotAttribute",
"ec2:DescribeSecurityGroups",
"ec2:DescribeNetworkAcls",
"ec2:DescribeFlowLogs",
"ec2:DescribeSubnets",
"ec2:DescribeAddresses",
"ec2:DescribeLaunchTemplates",
"ec2:DescribeLaunchTemplateVersions",
"ec2:DescribeImages",
"ec2:DescribeInstanceConnectEndpoints",
"ec2:DescribeTransitGateways",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeVpcBlockPublicAccessOptions",
"ec2:DescribeVpcs",
"ec2:DescribeDhcpOptions",
"ec2:DescribeVpnConnections",
"ec2:GetEbsEncryptionByDefault",
"ec2:GetSerialConsoleAccessStatus",
"ec2:GetSnapshotBlockPublicAccessState",
"iam:GetInstanceProfile",
"iam:GetPolicy",
"iam:GetPolicyVersion",
"iam:GetRolePolicy",
"iam:ListAttachedRolePolicies",
"iam:ListRolePolicies",
"ssm:DescribeInstanceInformation",
"ssm:DescribeInstancePatchStates",
"cloudtrail:DescribeTrails",
"cloudtrail:GetTrailStatus",
"cloudtrail:GetEventSelectors",
"cloudwatch:DescribeAlarms",
"guardduty:ListDetectors",
"guardduty:GetDetector",
"inspector2:BatchGetAccountStatus",
"inspector2:ListCoverage",
"inspector2:ListFindings",
"backup:ListProtectedResources",
"backup:DescribeProtectedResource",
"sts:GetCallerIdentity"
],
"Resource": "*"
}
]
}
```
## 安全检查
### 涵盖 8 大类的 46 项检查
| # | 类别 | 检查数 | 重点 |
|---|----------|--------|-------|
| A | 实例安全 | 8 | IMDSv2(实例 + 启动模板)、公网 IP、IAM profile、虚拟化、ENIs、详细监控、UserData 密钥 |
| - | 启动模板 | 1 | 区域级别的所有启动模板审计:IMDSv2、公网 IP、EBS 加密 |
| B | 网络安全 | 11 | 安全组 SSH/RDP/高风险/远程管理/出站/授权端口、源-目标检查、默认安全组、VPC flow logs、NACL 管理端口、VPN IKEv2 |
| C | 存储安全 | 7 | EBS 加密(针对每个卷 + 默认 + 启动模板)、公开快照、公开 AMI、备份覆盖情况、EBS 快照 BPA |
| D | 访问控制 | 4 | IAM 角色(管理员 + 通配符 + `NotAction`/`NotResource`)、密钥对、串行控制台、Instance Connect |
| E | 日志与监控 | 4 | CloudTrail、CloudWatch 警报、SSM 托管状态、GuardDuty EC2 runtime 监控 |
| F | 补丁与漏洞 | 3 | SSM 补丁合规性、AMI 使用期限、Inspector v2 发现结果 |
| G | 网络暴露 | 6 | 未使用的 EIP、启动模板公网 IP、子网自动分配、VPC BPA、Transit Gateway 自动接受、VPC DHCP 自定义 DNS |
| H | 标签与清单 | 3 | 必填标签、已停止的实例、未使用的安全组 |
### UserData 中的密钥检测 (A.8)
扫描器会对 EC2 UserData 进行解码并扫描其中暴露的密钥:
| 模式 | 示例 |
|---------|----------|
| AWS Access Keys | `AKIA...`, `ASIA...` |
| AWS Secret Keys | `aws_secret_access_key=...` |
| 密码 | `PASSWORD=`, `DB_PASSWORD=`, `MYSQL_ROOT_PASSWORD=`, `POSTGRES_PASSWORD=`, `REDIS_PASSWORD=` |
| 私钥 | `-----BEGIN RSA/EC/DSA/OPENSSH PRIVATE KEY-----` |
| API Token | `api_key=`, `api_token=`, `AUTH_TOKEN=` |
| 通用密钥 | `SECRET_KEY`, `JWT_SECRET`, `ENCRYPTION_KEY`, `SIGNING_KEY`, Django/Flask 密钥 |
| 连接字符串 | `postgres://`, `mongodb://`, `mysql://`, `redis://`, `amqp://`, `mssql://`(包含内嵌凭证) |
| GitHub / GitLab | `ghp_…`, `github_pat_…`, `glpat-…` |
| OpenAI | 传统版 (`sk-…`)、项目版 (`sk-proj-…`)、服务账号版 (`sk-svcacct-…`) |
| Anthropic | `sk-ant-…` |
| Stripe | `sk_live_…`, `sk_test_…` |
| SendGrid, Slack, Vault | `SG.…`, `xoxb-…`, `hvs.…` |
| Azure, Docker, npm | `AZURE_CLIENT_SECRET=`, `DOCKER_PASSWORD=`, `npm_…` |
| 内联认证 | `Authorization: Bearer …`, `sshpass -p …` |
### 详细的安全分析
有关各项检查的详细文档(包括攻击向量、利用场景、boto3 调用和修复方法),请参阅 **[security-checks.md](security-checks.md)**。
### 合规性覆盖
有关扫描器每项检查与 AWS FSBP、CIS、PCI DSS、HIPAA、SOC 2、ISO 27001/27017/27018、GDPR 和 NIST 800-53 控制措施的全量映射,请参阅 **[compliance.md](compliance.md)**。
### 安全修复指南
有关扫描器检测到的每一个漏洞的分步修复说明(AWS Console、AWS CLI、boto3 代码),请参阅 **[remediation-guide.md](remediation-guide.md)**。
## 模块化架构
```
ec2_security_scanner/
├── scanner.py # Main scanner orchestration (facade pattern)
├── cli.py # Click CLI interface
├── compliance.py # 137 controls across 10 frameworks
├── html_reporter.py # Jinja2 HTML report generation
├── utils.py # Logging, scoring, formatting
├── checks/
│ ├── base.py # BaseChecker (session factory, error handling)
│ ├── instance_security.py # A.1-A.8: IMDSv2, public IP, secrets
│ ├── network_security.py # B.1-B.11: SG rules, flow logs, NACLs, VPN
│ ├── storage_security.py # C.1-C.7: EBS, snapshots, AMIs, snapshot BPA
│ ├── access_control.py # D.1-D.4: IAM, key pairs, serial console
│ ├── logging_monitoring.py # E.1-E.4: CloudTrail, CloudWatch, SSM, GuardDuty
│ ├── patch_vulnerability.py # F.1-F.3: SSM patches, AMI age, Inspector v2
│ ├── network_exposure.py # G.1-G.5: EIPs, public IP, VPC BPA, TGW
│ └── tagging_inventory.py # H.1-H.3: Tags, stopped instances, unused SGs
└── templates/
└── report.html # Interactive HTML dashboard
```
### 主要优势
- **可维护性**:每个安全域都有自己专用的模块
- **可测试性**:隔离的组件可实现全面的单元测试
- **可扩展性**:轻松添加新的安全检查而不影响现有代码
- **单一职责**:每个模块专注于一个特定的安全领域
- **三层扫描**:账户级和 VPC 级检查在每次扫描中只运行一次,而不是针对每个实例运行
## 安全评分
扫描器会报告 **两个独立的分数**,这样账户/区域级的安全态势就不会在每个实例上成倍重复计算:
- **实例评分** — 针对单个实例,仅反映在该实例及其自身资源(IMDSv2、公网 IP、其安全组、其 EBS 卷、IAM 角色、UserData、补丁等)上可控的内容。标题中的 **"Avg Instance Score"** 就是这些分数的平均值。
- **环境评分** — 账户和 VPC 级别的整体安全态势(GuardDuty、CloudTrail、VPC 阻止公开访问、EBS 快照 BPA、默认安全组、VPC flow logs 等)。在 **每次扫描中只计分一次**,而不是针对每个实例计分,因此单个账户级别的缺陷不会拉低每个实例的分数。
### 实例评分扣分规则
每个实例初始为 **100 分**,并根据特定于实例的问题扣除相应的分数:
| 安全问题 | 扣分 | 严重性 |
|----------------|-----------------|----------|
| UserData 密钥暴露 | -25 | CRITICAL |
| 公开的 EBS 快照(属于该实例的卷) | -20 | CRITICAL |
| EBS 快照与外部账户共享 | -15 | HIGH |
| 开放高风险端口(非叠加) | -20 | CRITICAL |
| SSH 对全网开放(非叠加) | -15 | HIGH |
| RDP 对全网开放(非叠加) | -15 | HIGH |
| 开放远程管理端口(非叠加) | -15 | HIGH |
| 未授权端口对全网开放(非叠加) | -10 | HIGH |
| 未强制执行 IMDSv2 | -15 | HIGH |
| 分配了公网 IP | -15 | HIGH |
| IAM 管理员 / 通配符访问权限 | -15 HIGH |
| 启动模板未强制执行 IMDSv2 | -10 | HIGH |
| 启动模板分配了公网 IP | -10 | HIGH |
| Inspector 已禁用或存在 CRITICAL/HIGH 级别的发现 | -8 | HIGH |
| EBS 卷未加密 | -10 | MEDIUM |
| SSM 补丁不合规 | -10 | MEDIUM |
| 无 IAM 实例 profile | -8 | MEDIUM |
| 启动模板 EBS 未加密 | -5 | MEDIUM |
| 源/目标检查已禁用 | -5 | MEDIUM |
| 未被 SSM 托管 | -5 | MEDIUM |
| 子网自动分配公网 IP | -5 | MEDIUM |
| 无 CloudWatch 警报 | -5 | MEDIUM |
| 过时的 AMI(>180 天) | -5 | MEDIUM |
| 详细监控已禁用 | -5 | MEDIUM |
| 半虚拟化(非 HVM) | -5 | MEDIUM |
| 密钥对未进行 SSM 管理 | -5 | MEDIUM |
| 多个 ENI | -3 | LOW |
| 无 EBS 备份计划 | -3 | LOW |
| 不受限制的出站流量(主观判定 — AWS 默认配置,非 FSBP 强制要求) | -2 | LOW |
| 缺少必填标签 | -2 | LOW |
| 已停止的实例超过阈值 | -2 | LOW |
| IMDSv2 跳数限制 > 2 | -2 | LOW |
### 环境评分扣分规则
账户/VPC 安全态势初始为 **100 分**。即使影响了多个 VPC,VPC 级别的发现结果也只计分 **一次**:
| 发现结果 | 扣分 | 严重性 | 范围 |
|---------|-----------------|----------|-------|
| 公开 AMI 共享 | -20 | CRITICAL | 账户 |
| 默认安全组包含规则 | -10 | HIGH | 每个 VPC |
| 未启用 EBS 快照 BPA | -10 | HIGH | 账户 |
| Transit Gateway 自动接受 | -10 | HIGH | 账户 |
| 无 GuardDuty | -10 | HIGH | 账户 |
| 未启用 VPC 阻止公开访问 | -10 | HIGH | 账户 |
| 无 CloudTrail | -10 | HIGH | 账户 |
| VPN 不是仅使用 IKEv2 | -10 | HIGH | 账户 |
| 无 VPC flow logs | -10 | MEDIUM | 每个 VPC |
| 禁用了 EBS 默认加密 | -5 | MEDIUM | 账户 |
| VPC DHCP 自定义 DNS 解析器 | -5 | MEDIUM | 账户 |
| 启用了串行控制台访问 | -5 | MEDIUM | 账户 |
| NACL 允许管理端口访问 | -5 | MEDIUM | 每个 VPC |
| 未使用的安全组 | -2 | MEDIUM | 账户 |
| 未使用的弹性 IP | -2 | LOW | 账户 |
| 无 Instance Connect endpoint | -1 | LOW | 每个 VPC |
### 非叠加安全组惩罚
所有安全组的 **入站暴露** 检查(SSH、RDP、高风险端口、远程管理端口以及对全网开放的未授权端口)描述的都是同一种底层的“端口对 0.0.0.0/0 开放”的配置错误,因此仅应用 **单次最高惩罚** — 而不是累加:
- 开放高风险端口 = -20,开放 SSH = -15 → **仅扣 20 分**
- SSH 和 RDP 同时开放 → **仅扣 15 分**(而不是 -30)
- 开放 SSH(端口 22)同时触发了 SSH 惩罚和“未授权端口”检查 → **仅扣 15/-20 分**,而不是 -25/-30 分
**计算公式**:`Score = max(0, 100 - total_deductions)`
### 分数解释
| 分数范围 | 安全等级 | 建议 |
|-------------|----------------|----------------|
| **90-100** | 优秀 | 保持当前的安全态势 |
| **70-89** | 良好 | 解决次要的安全缺陷 |
| **50-69** | 需改进 | 修复中等优先级的问题 |
| **0-49** | 极差 | 需立即采取行动 — 存在严重问题 |
### 关键属性
- **无账户级别倍增**:账户/VPC 发现结果只计分一次(环境评分),因此单实例的平均分能真实反映出实例的安全态势
- **错误安全**:因权限错误(`AccessDenied`、`UnauthorizedOperation` 等)而失败的检查将作为 ERROR 严重级别的发现显示,并从评分中排除(而不是默不作声地算作通过)
- **公平加权**:每个有效的实例对平均实例分数的贡献是相等的
- **基于优先级**:公网暴露和密钥泄露将受到最严厉的惩罚
- **可操作性**:分数与安全风险等级直接相关
## 输出示例
### 控制台摘要
```
EC2 Security Scan Summary - us-east-1
┌──────────────────────────────┬─────────────────┐
│ Metric │ Value │
├──────────────────────────────┼─────────────────┤
│ Account │ 123456789012 │
│ Total Instances │ 12 │
│ Running │ 10 │
│ Stopped │ 2 │
│ Public IP │ 4 │
│ With Secrets in UserData │ 1 │
│ Unencrypted Volumes │ 3 │
│ Critical Issues │ 2 │
│ High Issues │ 7 │
│ Avg Instance Score │ 82.6/100 │
│ Environment Score │ 60/100 │
└──────────────────────────────┴─────────────────┘
Environment Posture (account + VPC, counted once)
┌──────────┬──────────────────────────────┬─────────────────────────────────┐
│ Severity │ Finding │ Description │
├──────────┼──────────────────────────────┼─────────────────────────────────┤
│ HIGH │ NO_GUARDDUTY │ GuardDuty not enabled for EC2 │
│ HIGH │ NO_CLOUDTRAIL │ No active CloudTrail trail │
│ HIGH │ VPC_BPA_NOT_ENABLED │ VPC Block Public Access off │
│ MEDIUM │ NO_VPC_FLOW_LOGS │ Flow logs disabled in: vpc-abc │
└──────────┴──────────────────────────────┴─────────────────────────────────┘
```
### 合规性摘要
合规性是在 **扫描级别** 进行评估的:每个框架控制措施都只计算一次。账户/区域级别的控制措施(GuardDuty、CloudTrail、VPC BPA 等)只进行一次评估;实例级别的控制措施(IMDSv2、SSH 暴露等)如果未通过,也只计为一次失败并列出受影响的实例。缺少 GuardDuty 的账户在每个区域只算一个未通过的控制措施 — 而不是每个实例算一个 — 因此该百分比不会随着集群规模的变化而改变。
```
Compliance Framework Summary (scan level — account controls counted once)
┌──────────────┬────────┬──────────┬────────┬─────────────────┐
│ Framework │ Passed │ Controls │ Rate │ Status │
├──────────────┼────────┼──────────┼────────┼─────────────────┤
│ AWS-FSBP │ 27 │ 32 │ 84.4% │ Good │
│ CIS-v5.0 │ 5 │ 7 │ 71.4% │ Needs Work │
│ PCI-DSS-v4.0 │ 9 │ 12 │ 75.0% │ Good │
│ HIPAA │ 7 │ 10 │ 70.0% │ Needs Work │
│ SOC2 │ 11 │ 13 │ 84.6% │ Good │
│ ISO27001 │ 14 │ 17 │ 82.4% │ Good │
│ NIST-800-53 │ 23 │ 27 │ 85.2% │ Good │
└──────────────┴────────┴──────────┴────────┴─────────────────┘
```
## 输出文件
扫描器会在指定的输出目录中生成报告。
### JSON 报告 (`ec2_scan_region_timestamp.json`)
```
{
"summary": {
"scan_time": "2026-05-15T10:30:45.123456",
"region": "us-east-1",
"account_id": "123456789012",
"total_instances": 12,
"running_instances": 10,
"public_instances": 4,
"average_security_score": 82.6,
"environment_security_score": 60,
"environment_findings": [
{"severity": "HIGH", "issue_type": "NO_GUARDDUTY", "description": "...", "recommendation": "..."}
]
},
"results": [...]
}
```
### CSV 报告 (`ec2_scan_region_timestamp.csv`)
适合电子表格的格式,包含每个实例的所有关键指标和合规状态。
### HTML 报告 (`ec2_scan_region_timestamp.html`)
美观的交互式仪表板,包含:
- **执行摘要**:关键指标和风险指标
- **分数分布**:实例安全分数的柱状图
- **合规性概览**:所有 10 个框架的柱状图
- **严重性划分**:按严重性划分发现的环形图
- **实例详情**:带分数条的排序表格
- **关键发现**:高危/严重级别问题的表格
### 合规性报告 (`ec2_compliance_region_timestamp.json`)
跨越所有 10 个框架的实例级合规性评估,包含通过/未通过的控制措施详情。
### 日志文件 (`ec2_scan_timestamp.log`)
包含调试信息和错误详情的全面执行日志。
## 开发
### 配置开发环境
```
# 克隆 repository
git clone https://github.com/TocConsulting/ec2-security-scanner.git
cd ec2-security-scanner
# 创建虚拟环境
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# 以开发模式安装
pip install -e ".[dev]"
```
完整的贡献者指南请参阅 **[CONTRIBUTING.md](CONTRIBUTING.md)**。
## 测试
### 运行测试
本项目使用 Python 的 `unittest` 框架和 `moto`(用于模拟 AWS 服务)进行了全面的单元测试。
```
# 安装包含 moto 在内的开发依赖
pip install -e ".[dev]"
# 运行所有测试
python -m pytest tests/ -v
# 运行特定测试文件
python -m pytest tests/test_compliance.py -v
# 运行 coverage
python -m pytest tests/ --cov=ec2_security_scanner --cov-report=html
```
### 测试结构
```
tests/
├── __init__.py
├── test_cli.py # CLI option and command tests
├── test_compliance.py # 137 controls / 10 frameworks validation
├── test_scoring.py # Non-stacking scoring logic
├── test_instance_security.py # A.1-A.8 checks (IMDSv2, secrets)
├── test_network_security.py # B.x checks (SG rules)
├── test_storage_security.py # C.x checks (EBS, AMI)
└── test_utils.py # Logging, formatting utilities
```
测试使用 `unittest.mock` 和 `moto` 来模拟 AWS 服务,允许在不要求实际 AWS 资源或不产生费用的情况下进行全面测试。
## 支持与贡献
### 获取帮助
- **文档**:查看此 README 和内联帮助 (`--help`)
- **问题**:通过 [GitHub Issues](https://github.com/TocConsulting/ec2-security-scanner/issues) 报告 bug
- **讨论**:在 [GitHub Discussions](https://github.com/TocConsulting/ec2-security-scanner/discussions) 中加入讨论
### 贡献
我们欢迎您的贡献!请参阅我们的 [贡献指南](CONTRIBUTING.md) 了解以下详情:
- 代码风格和标准
- 测试要求
- Pull Request 流程
- 开发设置
## 许可证
本项目基于 MIT 许可证授权 - 详情请参阅 [LICENSE](LICENSE) 文件。
## 致谢
- **AWS 安全最佳实践**:基于官方 AWS 安全建议
- **CIS Benchmarks**:实施了 CIS AWS Foundations Benchmark v5.0 控制措施
- **[s3-security-scanner](https://github.com/TocConsulting/s3-security-scanner)**:架构和设计模式
**安全声明**:此工具仅供防御性安全目的使用。在扫描 AWS 资源之前,请务必确保您已获得适当的授权。扫描器仅需要只读权限,不会修改任何 AWS 资源。
**性能提示**:扫描器采用三层扫描(账户 → VPC → 实例)以最大程度地减少冗余的 API 调用。安全组规则在每个实例上仅获取一次,并在 6 项检查中重复使用。使用 `-w` 调整并行度。标签:AWS, DPI, Python, 安全扫描, 无后门, 时序注入, 请求拦截, 逆向工具