# Performing Cloud Asset Inventory With Cartography

> 使用 Cartography 执行全面的云资产清单和关系映射，在 AWS、GCP 和 Azure 中构建包含基础设施资产、IAM 权限和攻击路径的 Neo4j 安全图谱。

- Skill: `killvxk/performing-cloud-asset-inventory-with-cartography` (Agent Skill, multi-file: 8 files)
- Install (CLI): `npx skillmds@latest add killvxk/performing-cloud-asset-inventory-with-cartography`
- Raw SKILL.md: https://api.skillmd.com/api/skills/killvxk/performing-cloud-asset-inventory-with-cartography/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- License: Apache-2.0
- Author: killvxk (https://skillmd.com/u/killvxk)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/killvxk/performing-cloud-asset-inventory-with-cartography

---


# 使用 Cartography 执行云资产清单

## 概述

Cartography 是一个 CNCF 沙箱项目（最初由 Lyft 创建），将基础设施资产及其关系整合到 Neo4j 图数据库中。它通过查询云 API 发现资源，映射资源间关系，使安全团队能够识别攻击路径、生成资产报告并找到安全改进点。图模型揭示了 IAM 权限链、网络路径和跨账户信任关系等隐藏连接。

## 前置条件

- Python 3.8+
- Neo4j 4.x 或 5.x 数据库
- 云提供商凭据（AWS、GCP、Azure）
- Docker（可选，用于 Neo4j 部署）
- Neo4j 最少需要 4GB RAM，大型环境需要更多

## 安装

```bash
# 安装 Cartography
pip install cartography

# 验证安装
cartography --help
```

### 使用 Docker 部署 Neo4j

```bash
docker run -d \
  --name neo4j \
  -p 7474:7474 -p 7687:7687 \
  -e NEO4J_AUTH=neo4j/changethispassword \
  -e NEO4J_PLUGINS='["apoc"]' \
  -v neo4j_data:/data \
  neo4j:5-community
```

## 运行 Cartography

### 基本 AWS 同步

```bash
# 同步 AWS 账户数据到 Neo4j
cartography \
  --neo4j-uri bolt://localhost:7687 \
  --neo4j-user neo4j \
  --neo4j-password-env-var NEO4J_PASSWORD
```

### 同步所有 AWS 配置文件

```bash
cartography \
  --neo4j-uri bolt://localhost:7687 \
  --neo4j-user neo4j \
  --neo4j-password-env-var NEO4J_PASSWORD \
  --aws-sync-all-profiles
```

### GCP 同步

```bash
cartography \
  --neo4j-uri bolt://localhost:7687 \
  --neo4j-user neo4j \
  --neo4j-password-env-var NEO4J_PASSWORD \
  --gcp-requested-syncs compute iam storage
```

## 安全导向的 Cypher 查询

### 查找所有具有公开访问权限的 S3 存储桶

```cypher
MATCH (b:S3Bucket)
WHERE b.anonymous_access = true
   OR b.anonymous_actions IS NOT NULL
RETURN b.name, b.anonymous_actions, b.region, b.arn
ORDER BY b.name
```

### 识别具有管理员策略的 IAM 用户

```cypher
MATCH (user:AWSUser)-[:POLICY]->(policy:AWSPolicy)
WHERE policy.name = 'AdministratorAccess'
   OR policy.arn CONTAINS 'AdministratorAccess'
RETURN user.name, user.arn, policy.name, user.password_last_used
```

### 查找暴露在互联网的 EC2 实例

```cypher
MATCH (instance:EC2Instance)-[:MEMBER_OF_EC2_SECURITY_GROUP]->(sg:EC2SecurityGroup)
      -[:MEMBER_OF_EC2_SECURITY_GROUP_RULE]->(rule:IpRule)
WHERE rule.fromport <= 22 AND rule.toport >= 22
  AND rule.protocol IN ['tcp', '-1']
  AND '0.0.0.0/0' IN rule.ipranges
RETURN instance.instanceid, instance.publicipaddress, sg.groupid, sg.name
```

### 发现跨账户信任关系

```cypher
MATCH (role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(principal:AWSPrincipal)
WHERE principal.arn CONTAINS ':root'
  AND NOT principal.arn CONTAINS role.accountid
RETURN role.arn, role.name, principal.arn AS trusted_account
ORDER BY role.name
```

### 查找从公开 EC2 到敏感 S3 的攻击路径

```cypher
MATCH path = (instance:EC2Instance)-[:STS_ASSUME_ROLE_ALLOWS|MEMBER_OF_EC2_SECURITY_GROUP|
  POLICY|INSTANCE_PROFILE*1..5]->(bucket:S3Bucket)
WHERE instance.publicipaddress IS NOT NULL
  AND bucket.name CONTAINS 'sensitive'
RETURN path
LIMIT 25
```

### 识别未使用的 IAM 角色

```cypher
MATCH (role:AWSRole)
WHERE role.last_used IS NULL
   OR role.last_used < datetime().epochMillis - (90 * 24 * 60 * 60 * 1000)
RETURN role.name, role.arn, role.last_used
ORDER BY role.last_used
```

### 查找具有过度授权角色的 Lambda 函数

```cypher
MATCH (func:AWSLambda)-[:STS_ASSUME_ROLE_ALLOWS]->(role:AWSRole)-[:POLICY]->(policy:AWSPolicy)
WHERE policy.name = 'AdministratorAccess'
RETURN func.name, func.arn, role.name, policy.name
```

### 网络路径分析

```cypher
MATCH (vpc:AWSVpc)-[:RESOURCE]->(subnet:EC2Subnet)-[:MEMBER_OF_SUBNET]->(instance:EC2Instance)
WHERE instance.publicipaddress IS NOT NULL
RETURN vpc.id, subnet.subnetid, subnet.cidr_block, instance.instanceid,
       instance.publicipaddress, instance.state
```

## 定期同步调度

### 基于 Cron 的同步

```bash
# 添加到 crontab - 每 6 小时同步一次
0 */6 * * * /usr/local/bin/cartography \
  --neo4j-uri bolt://localhost:7687 \
  --neo4j-user neo4j \
  --neo4j-password-env-var NEO4J_PASSWORD \
  >> /var/log/cartography/sync.log 2>&1
```

### Docker Compose 部署

```yaml
version: '3.8'
services:
  neo4j:
    image: neo4j:5-community
    ports:
      - "7474:7474"
      - "7687:7687"
    environment:
      NEO4J_AUTH: neo4j/securepwd123
      NEO4J_PLUGINS: '["apoc"]'
      NEO4J_dbms_memory_heap_max__size: 4G
    volumes:
      - neo4j_data:/data

  cartography:
    image: ghcr.io/cartography-cncf/cartography:latest
    depends_on:
      - neo4j
    environment:
      NEO4J_PASSWORD: securepwd123
      AWS_DEFAULT_REGION: us-east-1
    command: >
      --neo4j-uri bolt://neo4j:7687
      --neo4j-user neo4j
      --neo4j-password-env-var NEO4J_PASSWORD

volumes:
  neo4j_data:
```

## 数据模型概览

### 关键节点类型
- `AWSAccount`、`GCPProject`、`AzureSubscription`
- `EC2Instance`、`S3Bucket`、`RDSInstance`、`AWSLambda`
- `AWSUser`、`AWSRole`、`AWSGroup`、`AWSPolicy`
- `EC2SecurityGroup`、`EC2Subnet`、`AWSVpc`
- `GCPInstance`、`GCSBucket`、`GCPRole`

### 关键关系类型
- `RESOURCE`：账户拥有资源
- `POLICY`：主体附加了策略
- `STS_ASSUME_ROLE_ALLOWS`：主体可以担任角色
- `MEMBER_OF_EC2_SECURITY_GROUP`：实例属于安全组
- `TRUSTS_AWS_PRINCIPAL`：跨账户信任

## 参考资料

- Cartography GitHub: https://github.com/cartography-cncf/cartography
- Cartography 文档: https://cartography.dev
- CNCF 沙箱项目
- Neo4j Cypher 查询语言参考

