srini-cybersec/cloudguardian
GitHub: srini-cybersec/cloudguardian
一款支持多云 IaC 配置(Terraform、CloudFormation、Kubernetes、IAM)的静态安全态势扫描器,将云安全检测左移至 CI/CD 流水线和 PR 阶段。
Stars: 0 | Forks: 0
# CloudGuardian
[](https://github.com/srini-cybersec/cloudguardian/actions/workflows/ci.yml)
[](LICENSE)
[](https://www.python.org/downloads/)
[](https://github.com/psf/black)
## 为什么选择 CloudGuardian?
云安全漏洞几乎从来都不像是零日漏洞——它们通常表现为**配置错误**。一个公开的 S3 存储桶,一个对 `0.0.0.0/0` 开放的 SSH 端口,一个包含 `Action="*" Resource="*"` 的 IAM 策略。云安全态势管理(CSPM)工具会在运行时捕获这些问题;**而 CloudGuardian 将此过程左移**到了 pull request 中,在资源配置之前进行拦截。
它的特点是:
- **气隙安全** — 纯 Python 编写,零网络调用,无遥测。适用于受监管的环境和离线 CI 运行器。
- **多格式** — 一个工具即可搞定 Terraform HCL、CloudFormation (YAML + JSON)、Kubernetes manifests 以及独立的 IAM 策略文档。
- **原生的 CI/CD 支持** — 为 GitHub Code Scanning 输出 SARIF 2.1.0,并支持 JSON / CSV / HTML / Rich-console 格式。
- **主观但可调节** — 每条规则都包含 CWE、参考文档、合规性映射和修复代码片段。只需一个 flag 即可禁用任何规则。
## 问题描述
现代团队每周会发布数百个 IaC 变更。手动审查每一个变更是否符合云安全最佳实践是不可能的。现有的扫描工具要么:
- 仅在运行时运行(太晚了——违规行为已经发生),或者
- 仅针对一种格式(仅限 Terraform,或仅限 Kubernetes),迫使团队将十几个 pipeline 拼凑在一起。
CloudGuardian 是一个单一的 Python 工具,它可以接收四种最常见的云配置格式,并应用统一且引用完善的规则包,具有统一的阈值和退出代码。
## 架构
```
┌──────────────────────────────────────────────────────────────────┐
│ CloudGuardian CLI │
│ (Click — scan / rules / stats subcommands) │
└─────────────┬───────────────────────────────────────┬────────────┘
│ │
▼ ▼
┌─────────────┐ ┌──────────────┐
│ File walker │ ──► classifier ──► │ Config │
│ (recursive) │ (TF / CFN / K8S / │ (.cloudguardian.yml +
└─────┬───────┘ IAM JSON) │ env vars + CLI flags)
│ └──────────────┘
▼
┌──────────────────────────────────────────────────────┐
│ Parsers │
│ ┌──────────┐ ┌──────────────┐ ┌──────┐ ┌─────────┐ │
│ │ HCL/TF │ │ CloudFormation│ │ K8s │ │ IAM JSON│ │
│ │ lexer + │ │ (YAML + JSON │ │ YAML │ │ │ │
│ │ parser │ │ intrinsics) │ │ │ │ │ │
│ └──────────┘ └──────────────┘ └──────┘ └─────────┘ │
│ ──► Resource (unified schema) │
└──────────────────────────┬───────────────────────────┘
▼
┌──────────────────────────────────────────────────────┐
│ Rule engine │
│ 25+ rules across AWS / Azure / GCP / Kubernetes │
│ Each rule: id, severity, CWE, compliance, fix │
└──────────────────────────┬───────────────────────────┘
▼
┌──────────────────────────────────────────────────────┐
│ Reporters │
│ console (Rich) │ json │ sarif │ html │ csv │
│ + risk score (0-100) + verdict │
└──────────────────────────────────────────────────────┘
```
## 快速开始
### 安装
```
git clone https://github.com/srini-cybersec/cloudguardian
cd cloudguardian
pip install -e .
```
### 扫描目录
```
cloudguardian scan ./infra
```
```
╭───────────────────── CloudGuardian ─────────────────────╮
│ Tool version 1.0.0 │
│ Files scanned 4 │
│ Resources 12 │
│ Findings 9 │
│ Risk score 100 / 100 │
│ Verdict CRITICAL │
╰─────────────────────────────────────────────────────────╯
Findings by severity
┏━━━━━━━━━━┳━━━━━━━┓
┃ Severity ┃ Count ┃
┡━━━━━━━━━━╇━━━━━━━┩
│ CRITICAL │ 4 │
│ HIGH │ 3 │
│ MEDIUM │ 2 │
│ LOW │ 0 │
│ INFO │ 0 │
└──────────┴───────┘
```
### 为 GitHub Code Scanning 输出 SARIF
```
cloudguardian scan ./infra \
--format sarif \
--output cloudguardian.sarif \
--fail-on HIGH
```
将其接入 Actions:
```
- name: CloudGuardian
run: |
pip install cloudguardian
cloudguardian scan . --format sarif --output cg.sarif --fail-on HIGH
- uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: cg.sarif
```
### 列出规则和统计信息
```
cloudguardian rules --cloud aws --severity HIGH
cloudguardian stats
```
### Docker
```
docker build -t cloudguardian:local .
docker run --rm -v "$(pwd):/work:ro" cloudguardian:local scan /work --fail-on HIGH
```
## 内置规则(节选)
| ID | 云平台 | 严重程度 | 标题 |
|----|-------|----------|-------|
| CG-AWS-S3-001 | aws | CRITICAL | S3 存储桶授予了公共的预定义 ACL |
| CG-AWS-S3-002 | aws | HIGH | S3 存储桶未启用服务器端加密 |
| CG-AWS-S3-003 | aws | MEDIUM | S3 存储桶禁用了版本控制 |
| CG-AWS-SG-001 | aws | CRITICAL | 安全组向 0.0.0.0/0 暴露了 SSH/RDP/DB |
| CG-AWS-SG-002 | aws | CRITICAL | 安全组允许来自公共互联网的所有端口访问 |
| CG-AWS-EBS-001 | aws | HIGH | 创建的 EBS 卷未加密 |
| CG-AWS-RDS-001 | aws | HIGH | RDS 实例可被公开访问 |
| CG-AWS-RDS-002 | aws | HIGH | RDS 存储未加密 |
| CG-AWS-IAM-001 | aws | CRITICAL | IAM 策略授予了 `*:*` 管理员权限 |
| CG-AWS-IAM-002 | aws | CRITICAL | 配置了 Root 账户访问密钥 |
| CG-AWS-EC2-001 | aws | HIGH | EC2 未强制执行 IMDSv2 |
| CG-AWS-LAMBDA-001 | aws | HIGH | Lambda 权限中包含 `Principal="*"` |
| CG-AWS-CT-001 | aws | MEDIUM | CloudTrail 未配置为多区域 |
| CG-AWS-KMS-001 | aws | MEDIUM | KMS CMK 密钥轮换被禁用 |
| CG-AZ-STG-001 | azure | CRITICAL | Azure 存储允许公共 blob 访问 |
| CG-AZ-NET-001 | azure | CRITICAL | NSG 公开暴露了 SSH/RDP |
| CG-AZ-SQL-001 | azure | HIGH | Azure SQL 允许使用已废弃的 TLS |
| CG-GCP-STG-001 | gcp | CRITICAL | GCS 存储桶公开 (allUsers) |
| CG-GCP-NET-001 | gcp | CRITICAL | GCP 防火墙暴露了管理端口 |
| CG-GCP-GCE-001 | gcp | HIGH | GCE 使用了完整的 cloud-platform scope |
| CG-K8S-001 | k8s | CRITICAL | Container 以特权模式运行 |
| CG-K8S-002 | k8s | HIGH | 未强制执行 runAsNonRoot |
| CG-K8S-003 | k8s | HIGH | 启用了 hostPID/hostIPC/hostNetwork |
| CG-K8S-004 | k8s | HIGH | 添加了危险的 Linux capabilities |
| CG-K8S-005 | k8s | CRITICAL | RBAC 使用了通配符 verbs+resources |
| CG-IAM-STMT-001 | aws | HIGH | IAM 声明使用了通配符 Action |
| CG-IAM-STMT-002 | aws | HIGH | Allow + NotAction (deny-list 陷阱) |
| CG-IAM-STMT-003 | aws | CRITICAL | 缺少 Condition 的公共 Principal |
| CG-IAM-STMT-005 | aws | HIGH | 提权原语 |
运行 `cloudguardian rules` 获取完整的实时列表。
## 配置
`.cloudguardian.yml`(项目根目录,可选):
```
fail_on: HIGH
disabled_rules:
- CG-AWS-S3-004 # logging is enforced elsewhere
exclude_paths:
- .terraform/
- modules/vendor/
output_format: sarif
include_info: false
```
每个选项也支持通过环境变量覆盖:
`CLOUDGUARDIAN_FAIL_ON`、`CLOUDGUARDIAN_DISABLED_RULES`、
`CLOUDGUARDIAN_EXCLUDE_PATHS`、`CLOUDGUARDIAN_OUTPUT_FORMAT`。
## CI/CD 方案
### 仅在发现 CRITICAL 级别问题时阻止合并
```
cloudguardian scan . --fail-on CRITICAL
```
如果没有发现达到阈值的问题,退出代码为 `0`,否则为 `1` — 非常适合用于 `pre-commit`、`make check` 或任何 pipeline 门禁。
### 为 PR artifacts 选项卡生成易读的 HTML
```
cloudguardian scan . --format html --output report.html
```
### 与 `pre-commit` 结合使用
```
repos:
- repo: local
hooks:
- id: cloudguardian
name: CloudGuardian (IaC posture)
entry: cloudguardian scan . --fail-on HIGH
language: system
pass_filenames: false
```
## 安全考量
CloudGuardian 在设计上是**只读**的:
- 无网络调用(无遥测,无远程规则下载)。
- 除了您明确提供的 `--output` 外,没有任何文件写入操作。
- 在发布的 container 中以**非 root UID 10001** 身份运行。
- Container 在提供的 `docker-compose.yml` 中丢弃了所有 Linux capabilities,并以只读文件系统运行。
- 解析器具有防御性:格式错误的输入会返回 `[]` 而不会导致崩溃。
- HCL 解析器不会执行 Terraform、展开变量或获取 modules — 它纯粹是一个静态词法分析器 + 解析器。
如果您发现了安全问题,请在 GitHub 上提交私人安全建议,而不是发布公开 issue。
## 开发
```
pip install -r requirements-dev.txt
pip install -e .
black src tests
ruff check src tests
mypy src
bandit -r src -ll
pytest --cov=src/cloudguardian --cov-report=term-missing
```
目录结构:
```
src/cloudguardian/
├── cli.py # Click entry-point
├── config.py # YAML + env-var configuration
├── engine.py # discover → parse → evaluate → report
├── models.py # Severity, Resource, Finding, ScanReport
├── parsers/ # HCL, CloudFormation, K8s, IAM
├── rules/ # built-in rule pack (one module per cloud)
└── reporters/ # console, json, sarif, html, csv
```
添加一条规则大约需要 25 行代码:请查看 `src/cloudguardian/rules/` 中的任何模块以了解模式。
## 许可证
MIT — 详见 [LICENSE](LICENSE)。
标签:CSPM, DevSecOps, EC2, ECS, Homebrew安装, IaC, LNA, Python, Terraform, TinkerPop, 上游代理, 无后门, 请求拦截, 逆向工具