s0rg/decompose

GitHub: s0rg/decompose

用于 Docker 环境的逆向工程工具,提取容器网络连接并导出为多种可视化格式。

Stars: 126 | Forks: 6

[![CI](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/4ce1acb55c072522.svg)](https://github.com/s0rg/decompose/actions?query=workflow%3Aci) ![coverage](https://img.shields.io/badge/coverage-84.9%25-brightgreen) [![Go Report Card](https://goreportcard.com/badge/github.com/s0rg/decompose)](https://goreportcard.com/report/github.com/s0rg/decompose) ![Issues](https://img.shields.io/github/issues/s0rg/decompose) [![License](https://img.shields.io/badge/license-MIT%20License-blue.svg)](https://github.com/s0rg/decompose/blob/master/LICENSE) [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fs0rg%2Fdecompose.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fs0rg%2Fdecompose?ref=badge_shield) [![Go Version](https://img.shields.io/github/go-mod/go-version/s0rg/decompose)](go.mod) [![Release](https://img.shields.io/github/v/release/s0rg/decompose)](https://github.com/s0rg/decompose/releases/latest) [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go) ![Downloads](https://img.shields.io/github/downloads/s0rg/decompose/total.svg) # 分解 用于 Docker 环境的逆向工程工具。 提取 Docker 容器中的所有网络连接并将其导出为: - [graphviz dot](https://www.graphviz.org/doc/info/lang.html) - [structurizr dsl](https://github.com/structurizr/dsl) - [compose yaml](https://github.com/compose-spec/compose-spec/blob/master/spec.md) - [plant uml](https://github.com/plantuml/plantuml) - 伪图形树 - json 流 - 统计信息 - 节点、连接和监听端口计数 - 包含列的 CSV:`name`、`listen` 和 `outbounds` ## 缘由 我需要一个工具来可视化和检查庞大(超过 470 个容器)且没有任何方案和文档极其匮乏的 Docker 化遗留系统 ## 同类工具 我能找到的最接近的同类工具,但不太符合我的需求: - [Red5d/docker-autocompose](https://github.com/Red5d/docker-autocompose) - 仅生成 `compose yaml` - [justone/dockviz](https://github.com/justone/dockviz) - 仅生成 `dot`,链接和端口直接取自 compose 配置(`links` 和 `ports` 部分),因此可能会遗漏部分信息 - [LeoVerto/docker-network-graph](https://github.com/LeoVerto/docker-network-graph) - 与上述非常相似,用 Python 编写 - [weaveworks/scope](https://github.com/weaveworks/scope) - 已弃用,无 CLI ## 特性 - 跨操作系统,它使用不同的策略来获取容器连接: - 在 **Linux 上以 root 身份运行**是最快的方式,并且适用于所有类型的容器(甚至是基于 `scratch` 的),因为它使用 `nsenter` - 以非 root 身份或在非 Linux 操作系统上运行时,将尝试在容器内运行 `netstat`,如果失败(例如缺少 `netstat` 二进制文件),则不会收集此类容器的连接 - 单一二进制文件,静态编译的 Unix 风格 `cli`(所有输出转到 stdout,进度信息转到 stderr) - 生成带有端口的详细连接图 - 保存 `json` 流一次,之后可以任何你想要的方式处理它 - 所有输出格式都经过排序,因此可以放入任何 `vcs` 中以观察变化 - 快速,在大约 5 秒内扫描约 470 个容器和约 4000 个连接 - 基于图拓扑的自动聚类 - 深度检查模式,该模式下容器内进程之间的连接也会被收集和显示 - Unix 套接字连接 - 超过 95% 的测试覆盖率 ## 已知限制 - 仅列出已建立和监听的连接(但像 [snapshots.sh](examples/snapshots.sh) 这样的脚本可以解决这个问题) - `composer-yaml` 并不旨在开箱即用,它可能缺少一些关键信息(即使在 `-full` 模式下),或者可能包含节点之间的循环(删除服务中的 `links` 部分可能有帮助),其主要目的是用于系统概览 - [gephi](https://github.com/gephi/gephi) 无法从生成的 graphviz 加载边,这可以通过任何自动替换工具修复:`sed -i 's/->/ -> /g' myfile.dot` - Unix 套接字仅在 Linux 的 root 模式下工作,此过程涉及 inode 匹配以查找正确的连接 ## 安装 - 适用于 Linux、FreeBSD、macOS 和 Windows 的 [二进制文件 / deb / rpm](https://github.com/s0rg/decompose/releases) - [Docker 镜像](https://hub.docker.com/r/s0rg/decompose) ## 用法 ``` decompose [flags] -cluster string json file with clusterization rules, or auto: for auto-clustering, similarity is float in (0.0, 1.0] range -compress compress graph -deep process-based introspection -follow string follow only this container by name(s), comma-separated or from @file -format string output format: csv, dot, json, puml, sdsl, stat, tree, yaml (default "json") -help show this help -load value load json stream, can be used multiple times -local skip external hosts -meta string json file with metadata for enrichment -no-loops remove connection loops (node to itself) from output -no-orphans remove orphaned (not connected) nodes from output -out string output: filename or "-" for stdout (default "-") -proto string protocol to scan: tcp,udp,unix or all (default "all") -silent suppress progress messages in stderr -skip-env string environment variables name(s) to skip from output, case-independent, comma-separated -version show version ``` ### 环境变量: - `DOCKER_HOST` - 连接 URI - `DOCKER_CERT_PATH` - 包含 key.pem、cert.pm 和 ca.pem 的目录路径 - `DOCKER_TLS_VERIFY` - 启用客户端 TLS 验证 - `IN_DOCKER_PROC_ROOT` - 用于 in-docker 场景 - 主机挂载的 /proc 的根目录 ## json 流格式 ``` type Item struct { Name string `json:"name"` // container name IsExternal bool `json:"is_external"` // this host is external Image *string `json:"image,omitempty"` // docker image (if any) Container struct{ Cmd []string `json:"cmd"` Env []string `json:"env"` Labels map[string]string `json:"labels"` } `json:"container"` // container info Listen map[string][]{ Kind string `json:"kind"` // tcp / udp / unix Value string `json:"value"` Local bool `json:"local"` // bound to loopback } `json:"listen"` // ports with process names Networks []string `json:"networks"` // network names Tags []string `json:"tags"` // tags, if meta presents Volumes []*struct{ Type string `json:"type"` Src string `json:"src"` Dst string `json:"dst"` } `json:"volumes"` // volumes info, only when '-full' Connected map[string][]string `json:"connected"` // name -> ports slice } ``` 包含完整信息和已填充元数据的单节点示例: ``` { "name": "foo-1", "is_external": false, "image": "repo/foo:latest", "container": { "cmd": [ "foo", "-foo-arg" ], "env": [ "FOO=1" ], "labels": {} }, "listen": {"foo": [ {"kind": "tcp", "value": "80"} ]}, "networks": ["test-net"], "tags": ["some"], "volumes": [ { "type": "volume", "src": "/var/lib/docker/volumes/foo_1/_data", "dst": "/data" }, { "type": "bind", "src": "/path/to/foo.conf", "dst": "/etc/foo.conf" } ], "connected": { "bar-1": [ {"src": "foo", "dst": "[remote]", "port": {"kind": "tcp", "value": "443"}} ] } } ``` 有关简单的流示例,请参见 [stream.json](examples/stream.json)。 ## 元数据格式 要使用详细描述丰富输出,你可以提供额外的 `json` 文件,其中包含元数据,例如: ``` { "foo": { "info": "info for foo", "docs": "https://acme.corp/docs/foo", "repo": "https://git.acme.corp/foo", "tags": ["some"] }, "bar": { "info": "info for bar", "tags": ["other", "not-foo"] } } ``` 使用此文件,`decompose` 可以为每个名称与提供的键之一(如本例中的 `foo-1` 或 `bar1`)匹配的容器丰富输出信息和附加标签。 有关如何从 CSV 创建此类 `json` 的示例,请参见 [csv2meta.py](examples/csv2meta.py);有关元数据样本,请参见 [meta.json](examples/meta.json)。 ## 聚类 ### 基于规则 你可以通过灵活的规则在 `dot`、`structurizr` 和 `stat` 输出格式中将服务加入到 `clusters` 中。 示例 `json`(顺序很重要): ``` [ { "name": "cluster-name", "weight": 1, "if": "" }, ... ] ``` 权重可以省略,如果未指定则等于 `1`。 其中 `` 是 [expr dsl](https://expr-lang.org/docs/Language-Definition),具有包含以下字段的环境对象 `node`: ``` type Node struct { Listen PortMatcher // port matcher with two methods: `HasAny(...string) bool` and `Has(...string) bool` Name string // container name Image string // container image Cmd string // container cmd Args []string // container args Tags []string // tags, if meta present IsExternal bool // external flag } ``` 参见:[cluster.json](examples/cluster.json) 以获取详细示例。 ### 自动 Decompose 提供自动聚类选项,使用 `-cluster auto:` 进行尝试,`similarity` 是 `(0.0, 1.0]` 范围内的浮点数,表示节点必须具有多大的相似端口才能被放入同一个集群(`1.0` - 必须具有所有相等的端口)。 ## 示例 保存完整的 json 流: ``` sudo decompose > nodes-1.json ``` 获取 `dot` 文件: ``` decompose -format dot > connections.dot ``` 获取 tcp 和 udp 连接作为 `dot`: ``` decompose -proto tcp,udp -format dot > tcp.dot ``` 合并来自 json 流的图,按协议过滤,跳过远程主机并保存为 `dot`: ``` decompose -local -proto tcp -load "nodes-*.json" -format dot > graph-merged.dot ``` 加载 json 流,丰富并保存为 `structurizr dsl`: ``` decompose -load nodes-1.json -meta metadata.json -format sdsl > workspace.dsl ``` 保存自动聚类的图,相似度因子为 `0.6`,作为 `structurizr dsl`: ``` decompose -cluster auto:0.6 -format sdsl > workspace.dsl ``` ## 结果示例 取自 [redis-cluster](https://github.com/s0rg/redis-cluster-compose) 的方案: ![svg](https://github.com/s0rg/redis-cluster-compose/blob/main/redis-cluster.svg) *它可能太重而无法在浏览器中显示,请使用 `save image as` 并在本地打开* 重现步骤: ``` git clone https://github.com/s0rg/redis-cluster-compose.git cd redis-cluster-compose docker compose up -d ``` 然后: ``` decompose -format dot | dot -Tsvg > redis-cluster.svg ``` ## 许可证 [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fs0rg%2Fdecompose.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fs0rg%2Fdecompose?ref=badge_large)
标签:CSV, DevSecOps, Docker, Docker Compose, EVTX分析, Go, Graphviz, JSON, PlantUML, Ruby工具, Structurizr, Web截图, 上游代理, 云资产清单, 依赖关系, 安全防御评估, 实时处理, 容器安全, 容器监控, 文档结构分析, 日志审计, 架构分析, 端口监听, 网络拓扑可视化, 网络连接, 规避防御, 请求拦截, 逆向工程, 配置审计