aws-samples/sample-aws-resource-graph-cmdb
GitHub: aws-samples/sample-aws-resource-graph-cmdb
该项目将 AWS 账户资源及其关系构建为 Neo4j 图数据库,提供可视化取证控制台,帮助运维团队查询爆炸半径、追踪网络流量并发现治理风险。
Stars: 2 | Forks: 0
# Graph CMDB — AWS 资源关系图
将你的 AWS 账户变成一个**可以查询和可视化的图**。此示例以 **AWS Config** 作为资产清单的基础,然后在其上叠加控制平面 API(IAM / EKS / ELBv2 / Bedrock / CloudFront / Bedrock AgentCore)、Kubernetes、CloudTrail 和 VPC Flow Logs,以恢复 Config 无法察觉的资源(例如 Kubernetes Pod)及其未建模的关系(Pod→role、负载均衡器→后端、观察到的 API 调用、观察到的网络流)。所有这些最终都会汇入一个**图数据库**,让运维和安全团队能够*以图的方式思考*:调查爆炸半径、追踪真实网络流量、查找权限过高的角色,并跟踪配置变更。
这是一个**动手实践的原型**:本地 Neo4j + 来自你自己 AWS 账户的数据 + 取证控制台风格的可视化。

***资源视图**:一个清晰的 `ingress → compute → data` 主干,从左到右展开,并附加了每个工作负载的关键依赖项。这是经过丰富化和治理层处理后的图——真实的 AWS 服务图标,将相同的副本折叠为 `×N` 超级节点,底部还有实时的治理统计(开放的安全组、可从互联网访问的资源、管理员角色、无主资源、高危发现)。*
## 此图可以解答什么问题
- **依赖项 / 爆炸半径** — 双击任何资源以展开其相邻节点,查看变更会波及到哪些对象。
- **观察到的网络主干** — 网络视图从 VPC Flow Logs 重建真实的 ENI 到 ENI 的流量,按字节将流量排名前 N 的路径点亮为“主干”,并将其余部分暗化,这样你就可以一目了然地看到当前实际正在进行通信的内容(分为 *hot* = 正在流动 / *recent* = 最近见过)。
- **公共暴露 / 权限提升** — 检查规则会自动标记对互联网开放的安全组和权限过高的管理员角色。
- **孤儿和闲置资源** — 治理扫描会呈现没有所有者、没有用户且有公共暴露的资源。
- **近实时变更** — 模拟配置变更,并观察它在几分钟内反映在图中。
## 为什么治理层很重要
这个原型的初版只是简单地将 AWS Config 加载到一个图中,并用力导向布局绘制出来——每个资源、每个声明的关系,没有任何解释:

***早期版本**:直接来自 Config 的原始资源关联。这是一个真实的图,但它是一个乱麻——所有东西都是同样颜色的圆点,布局是力导向的缠结,根本无法区分面向互联网的负载均衡器和闲置的安全组。这就是在任何治理层**之前**“作为图的你的账户”的样子。(此截图来自早期构建版本,其 UI 为中文。)*
在这个乱麻和本 README 顶部的资源视图之间,存在着**治理层**——这部分将原始的关联转储转化为运维人员或安全审查人员能够真正阅读的内容:
| | 早期版本(原始 Config) | 带有治理层 |
|---|---|---|
| **布局** | 力导向的乱麻 | `ingress → compute → data` 主干,按角色布局 |
| **节点** | 每个资源一个彩色圆点 | 真实的 AWS 服务图标;相同的副本折叠为 `×N` |
| **边** | 平铺所有声明的关系 | 按来源分类——声明 / 观察 / 推导——并进行去噪 |
| **额外资源** | 仅限 Config | + Kubernetes Pod、LB→backend、观察到的流、CloudTrail 调用 |
| **解读** | “这里是一切” | “这里是爆炸半径 / 暴露路径 / 权限过高的角色” |
治理层包含了 [`docs/data-sources.md`](docs/data-sources.md) 和 [`src/enrich_*.py`](src/) / [`src/rules.py`](src/rules.py) 中的所有内容:填补 Config 盲区的额外数据源,推导出的边(公共暴露、IAM 可达性),标记在每一条边上的来源,以及将孤儿、暴露路径和权限过高的角色作为一等公民 `Finding` 节点呈现的检查规则。
## 技术栈
| 层级 | 选择 | 备注 |
|-------|--------|-------|
| 数据源 | **多种**(见 [`docs/data-sources.md`](docs/data-sources.md)) | Config 基础 + IAM/EKS/ELBv2/Bedrock/CloudFront/AgentCore 控制平面 API + kubectl + CloudTrail + VPC Flow Logs |
| 提取 | Python + boto3 | Config `select-resource-config` + `get-resource-config-history` 用于获取关系/配置/历史记录;其他来源使用它们自己的 API |
| 图 | Neo4j | 本地运行;写入使用普通的 openCypher `MERGE`,可移植到 Amazon Neptune |
| 丰富化 | Python pipeline | 添加超出 Config 范围的资源/关系 + 推导出的边(暴露/权限/发现);每条边都标有其 `source` |
| 后端 | Flask | 场景 Cypher → cytoscape 图 JSON |
| 前端 | cytoscape.js | 取证控制台 UI:资源 / 网络视图 + 治理扫描 |
生产架构(Config → EventBridge → Lambda → Neptune)位于 [`docs/architecture.md`](docs/architecture.md) 中;将此原型部署到 AWS 的完整计划(如下图所示)位于 [`docs/cloud-deployment-plan.md`](docs/cloud-deployment-plan.md) 中。

*AWS 上的原型:CloudFront (VPC origin) → 内部 ALB → Fargate 上的 Web → EC2 上的 Neo4j,pipeline 通过 EventBridge 每小时运行一次,并使用应用层的 Cognito 身份验证。(该图是一个动画 SVG——在 GitHub 或浏览器中查看时,它会显示请求流的移动。)*
## 前提条件
- **Python 3.9+**
- 在本地运行的 **Neo4j**(`brew install neo4j`,或使用附带的 `docker compose up -d`)
- 指向你想要绘制成图的账户的 **AWS 凭证**,并且对 AWS Config 和你启用的服务具有**只读**访问权限(请参阅 [`docs/cloud-deployment-plan.md`](docs/cloud-deployment-plan.md) §5 中的最低权限策略)。你所指向的账户必须**启用 AWS Config 记录**。没有硬编码的账户 ID:账户是从你的凭证 (STS) 中读取的,并且每个特定于环境的值都是通过 `CMDB_*` 环境变量设置的。
## 快速开始
```
cd sample-aws-resource-graph-cmdb
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
# 设置 Neo4j 密码并启动(首次运行)
neo4j-admin dbms set-initial-password cmdb-prototype
neo4j start
# 指向你的账户/区域,然后运行整个 pipeline
export CMDB_AWS_REGION=us-east-1 # or your region
bash run.sh # extract → load → enrich → inspect
# 启动可视化
.venv/bin/python web/server.py
# 打开 http://127.0.0.1:8000
```
你也可以使用 Docker 而不是 brew 来启动 Neo4j:`docker compose up -d`。
### 配置(环境变量)
一切都是可覆盖的;基本运行只需要 `CMDB_AWS_REGION`。
| 变量 | 默认值 | 用途 |
|----------|---------|---------|
| `CMDB_AWS_REGION` | `us-east-1` | 主要 / 主区域 |
| `CMDB_AWS_REGIONS` | = `CMDB_AWS_REGION` | 从 Config 提取的以逗号分隔的区域 |
| `CMDB_ENRICH_REGIONS` | = `CMDB_AWS_REGIONS` | 丰富化步骤扫描的区域 |
| `CMDB_AWS_ACCOUNT` | 自动 (STS) | 覆盖 ARN/标签中使用的账户 ID |
| `CMDB_NEO4J_URI` / `_USER` / `_PASSWORD` | `bolt://localhost:7687` / `neo4j` / `cmdb-prototype` | Neo4j 连接 |
| `CMDB_EKS_CLUSTER` / `CMDB_EKS_REGION` | *(未设置 → 步骤跳过)* | 用于 kubectl Pod / Pod-Identity 步骤的 EKS 集群 |
| `CMDB_FLOW_LOG_GROUP` / `CMDB_FLOW_LOG_REGION` | *(未设置 → 步骤跳过)* | 用于观察流的 VPC Flow Logs CloudWatch Logs 组 |
| `CMDB_APP_PROJECTS` | *(未设置 → 步骤跳过)* | 以逗号分隔的 `Project` 标签值,将拉取这些标签对应的角色 |
未配置输入的步骤会优雅地跳过,因此仅使用 `CMDB_AWS_REGION` 的首次运行就会生成一个完整的基于 Config 的图;随着你的环境提供相关信息,你可以通过设置上述变量来添加更丰富的层。
### 多个区域
每个区域都被提取到 `data/region_.json` 中;`load.py` / `enrich.py` 默认合并所有区域文件。要添加一个区域(其 Config 记录器必须已开启):
```
CMDB_AWS_REGION=us-west-2 .venv/bin/python src/extract.py # extract another region
.venv/bin/python src/load.py --reset # merge all region_*.json and rebuild
```
### 近实时变更演示
```
.venv/bin/python src/simulate_change.py # simulate "a security group opened to the internet"
.venv/bin/python src/simulate_change.py --revert # undo
```
## 项目布局
```
config/settings.py region/account/connection/tuning (all CMDB_* overridable)
src/extract.py full AWS Config extract → snapshot JSON (base)
src/load.py snapshot → Neo4j (nodes + edges, openCypher)
src/enrich_reconcile.py reconcile stub nodes with real nodes
src/enrich.py derived edges: public exposure / public subnet / Internet sentinel / change events
src/enrich_iam.py IAM API: Role→Policy + admin/over-privilege flags
src/enrich_iam_tagged.py IAM tags → application roles + EKS ground-truth
src/enrich_bedrock.py Bedrock API: inference profile → model
src/enrich_pods.py kubectl: K8s Pod nodes + Pod→node/cluster
src/enrich_pod_identity.py EKS Pod Identity API: Pod → IAM role
src/enrich_workload_deps.py kubectl configmap: Pod→Endpoint / cross-account AssumeRole
src/enrich_flowlog_deps.py VPC Flow Logs: Pod↔DB observed flow + network backbone (7-day ledger)
src/enrich_elb.py ELBv2 API: LB → real backend targets
src/enrich_cloudfront.py CloudFront control-plane API: distributions/origins/certs (Config blind spot)
src/enrich_agentcore.py Bedrock AgentCore control-plane API: runtimes/roles/images
src/enrich_cloudtrail_bedrock.py CloudTrail: roles that actually invoked Bedrock
src/rules.py inspection rules → Finding nodes
src/simulate_change.py near-real-time change demo (upsert + who/when)
queries/scenarios.cypher investigation queries (also paste into Neo4j Browser)
web/server.py Flask visualization backend
web/index.html cytoscape.js forensic-console UI
web/about.html "how it works" page (/about)
docs/data-sources.md ★ data sources: Config gaps + extra sources + per-edge provenance/confidence
docs/architecture.md local prototype + production architecture + Neptune migration
docs/cloud-deployment-plan.md complete plan to deploy on AWS (CDK, 6 stacks)
docs/demo-script.md step-by-step demo walkthrough
infra/ CDK (Network/Auth/Data/App/Pipeline/Edge stacks)
```
## 供想要探索的工程师使用
Neo4j 浏览器:`http://localhost:7474` (neo4j / cmdb-prototype)。粘贴来自 [`queries/scenarios.cypher`](queries/scenarios.cypher) 的查询。
## 安全
此示例仅从 AWS 读取数据(Config、控制平面 describe/list、CloudTrail lookup、Logs Insights)。有关最低权限任务角色策略,请参见 [`docs/cloud-deployment-plan.md`](docs/cloud-deployment-plan.md) §5。要报告安全问题,请参见 [CONTRIBUTING.md](CONTRIBUTING.md#security-issue-notifications)。
## 许可证
本库基于 MIT-0 许可证授权。请参阅 [LICENSE](LICENSE) 文件。
标签:AWS, DPI, Neo4j, 多云安全, 攻击面分析, 请求拦截, 运维可视化, 逆向工具, 配置管理数据库