网络拓扑图这东西,几乎每个甲方安全岗都被要求过,但真正能用的极少。常见情况是:机房里翻出一张 2019 年画的 Visio,图上还是那台早下线的旧防火墙,新上的两台超融合、一条专线、一个云上 VPC 都没画;出了故障,运维拿着图对不上现实,最后还是靠 SSH 一台台查。
拓扑图的价值不在"有",在"准"和"能自动更新"。这篇讲三件事:一张拓扑图该画什么、用什么工具画、怎么让它自己跟着网络变化走——最后给一段能直接跑的设备邻居自动发现脚本,把"手工画图"变成"生成图"。
一、先想清楚这张图要给谁看:三种拓扑,别混成一张
最常见的失败,是把物理位置、逻辑连接、数据流向全塞进一张图,结果谁都看不懂。企业里实际需要的是三张分离的图:
| 图类型 | 回答什么问题 | 使用场景 | 粒度 |
|---|---|---|---|
| 物理拓扑 | 设备在哪、怎么连、走哪条线 | 机房施工、故障定位、链路割接 | 到设备端口和链路 |
| 逻辑拓扑 | 业务怎么走、安全域怎么划 | 安全评估、等保测评、应急响应 | 到安全域和关键节点 |
| 数据流图 | 数据从哪来、经过谁、到哪去 | 数据安全、隐私合规、出境评估 | 到系统和数据流向 |
三张图各有各的读者:物理拓扑给运维和施工方,逻辑拓扑给安全团队和测评机构,数据流图给合规和审计。试图一张图讲完三件事,是拓扑图项目最常见的死法。
给安全岗的建议是:先把逻辑拓扑做扎实。因为等保测评要它(网络架构、边界防护、区域划分都靠它取证)、应急响应要它(判断攻击者横向移动路径)、风险评估要它(找单点、找旁路)。物理拓扑可以由运维侧提供,数据流图在数据分类分级项目里单独做。
二、逻辑拓扑图必须画出来的七样东西
一张合格的逻辑拓扑,缺任何一样都会在实战里失效:
- 互联网出口与运营商线路——几条线、什么带宽、是否双线、BGP 还是静态。
- 边界安全设备及其串接关系——防火墙、IPS、WAF、抗 DDoS、上网行为管理,谁在谁前面。这个顺序在应急时决定你能不能封、封在哪。
- 安全域划分——互联网区、DMZ、办公区、生产区、运维管理区、测试区。区域之间的隔离设备必须画出来,只画区域不画隔离,等于没画。
- 核心层设备与冗余关系——核心交换机是不是堆叠、上联是不是双链路。这是判断单点的唯一依据。
- 远程接入路径——VPN、堡垒机、零信任网关,从哪个入口进、进到哪个区。
- 云上部分——VPC、子网、安全组、专线/VPN 打通方式。云上不画,等于把一半资产排除在外。
- 管理面——堡垒机放在哪、日志往哪送、监控从哪采集。这一块最常被漏,但它是"出事之后能不能查"的关键。
对应的原则是三条:分级分层(核心/汇聚/接入)、区域闭合(每个区有明确边界)、标注连接属性(链路带宽、是否加密、是否跨区)。
三、工具怎么选:先分类,再选型
拓扑图工具分四类,用途完全不同,别指望一个工具全包:
| 类别 | 代表工具 | 适合做什么 | 短板 |
|---|---|---|---|
| 手绘 | Visio、draw.io、亿图 | 汇报用图、示意图、方案配图 | 手动维护,必然过期 |
| 文档型 CMDB | NetBox、iTop | 设备/机柜/IP 台账,导出拓扑 | 需要录入,无自动发现 |
| 自动发现 | LibreNMS、Zabbix、Observium | 基于 SNMP/LLDP 自动发现和监控 | 出图样式固定,不适合汇报 |
| 代码化出图 | Graphviz、D2、Mermaid | 用文本描述拓扑,版本可管理 | 需要写 DSL,不适合精细排版 |
实际项目里最好用的是组合:NetBox 存资产与连接关系(唯一真源),LibreNMS 做自动发现补充,Graphviz 从台账生成图,draw.io 手工美化后用于汇报。
如果预算为零,最小可用组合是:draw.io 画正式图 + 一段脚本自动发现邻居关系做校验。脚本不需要多高级,能回答"图上画的和实际连的不一样"就够了。
一个容易忽略的点:图要进版本管理。把 draw.io 的.drawio(本质是 XML)或 Graphviz 的.dot放进 Git,每次变更留一次提交,就能回答"3 月份那次割接到底改了哪条线"。这个能力在做事故复盘时非常值钱。
四、画图规范:命名、图例、连线的硬规则
图混乱的根源不是工具,是缺少约定。建议直接定死这几条:
命名规则(举例,按自己环境调整):
| 对象类型 | 规则 | 示例 |
|---|---|---|
| 防火墙 | FW-位置-序号 | FW-DMZ-01 |
| 核心交换机 | CSW-机房-序号 | CSW-A-01 |
| 接入交换机 | ASW-楼层-序号 | ASW-3F-02 |
| 服务器 | 业务-角色-序号 | ERP-APP-01 |
| 云上资源 | 云-VPC-类型-序号 | ALI-PROD-VPC-01 |
| 安全域 | 域-名称 | ZONE-DMZ |
图例要固定,至少区分这几种:安全设备(实心方框红边)、网络设备(方框蓝边)、服务器(矩形)、云资源(虚线框)、外部单位(灰色)、加密链路(虚线)、跨区链路(粗线)、单点风险(红色三角标记)。
连线必须带属性,至少标带宽和用途。图上写"1000M 上联-办公"比只画一条线有用十倍——故障时第一句问的就是"这条线多大、走什么业务"。
别在图上画超过 80 个节点。超过就该拆成"总览图 + 分区详图",总览只画区域和设备组,详图按区画。一张图上挤 300 个节点,谁也看不清。
五、自动发现:让网络拓扑图由机器生成
手工画图必然过期,唯一解是让设备自己告诉你它连了谁。原理很简单:开启 LLDP,读邻居表,把邻居关系拼成图。
思科/华为/H3C 都支持show lldp neighbors detail,Linux 服务器侧可以用lldpctl。思路是:登录每台设备,抓邻居关系,输出成"边"的列表,再渲染成图。
# -*- coding: utf-8 -*- """从网络设备采集 LLDP 邻居,生成 Graphviz DOT 拓扑图。 依赖: pip install netmiko 用法: 把设备清单填进 DEVICES,运行后得到 topo.dot, 再执行 dot -Tpng topo.dot -o topo.png """ from netmiko import ConnectHandler DEVICES = [ {"device_type": "huawei", "host": "10.0.0.1", "username": "ro", "password": "***"}, {"device_type": "huawei", "host": "10.0.0.2", "username": "ro", "password": "***"}, {"device_type": "cisco_ios", "host": "10.0.0.3", "username": "ro", "password": "***"}, ] # 按设备类型选 LLDP 命令 LLDP_CMD = { "huawei": "display lldp neighbor brief", "cisco_ios": "show lldp neighbors", } def fetch_neighbors(dev): """返回 [(本端设备, 本端口, 对端设备, 对端端口)]""" cmd = LLDP_CMD.get(dev["device_type"]) if not cmd: return [] edges = [] with ConnectHandler(**dev) as conn: out = conn.send_command(cmd, read_timeout=30) for line in out.splitlines(): # 常见输出形如: GE0/0/1 SW-CORE-01 GE0/0/1 120 parts = line.split() if len(parts) < 3: continue local, remote = parts[0], parts[1] if not local or local.lower().startswith(("interface", "port", "---")): continue remote_port = parts[2] if len(parts) > 2 else "" edges.append((dev["host"], local, remote, remote_port)) return edges def to_dot(edges, path="topo.dot"): nodes, lines = {}, [] for src, sport, dst, dport in edges: # 双向去重:A-B 与 B-A 只保留一条 key = tuple(sorted([src + ":" + sport, dst + ":" + dport])) if key in nodes: continue nodes[key] = True lines.append(' "%s" -- "%s";' % (key[0], key[1])) dot = ["graph topology {", " graph [overlap=false, splines=true];", ' node [shape=box, style=rounded, fontname="Microsoft YaHei"];'] dot += lines dot.append("}") with open(path, "w", encoding="utf-8") as f: f.write("\n".join(dot)) return path if __name__ == "__main__": all_edges = [] for d in DEVICES: try: all_edges += fetch_neighbors(d) except Exception as e: print("skip %s: %s" % (d["host"], e)) print("edges:", len(all_edges)) print("dot ->", to_dot(all_edges))跑完得到topo.dot,用 Graphviz 渲染成 PNG,就能看到设备之间的实际连接关系。这套东西的好处是:图是现场生成的,不存在过期。它不如手工图好看,但能用来校验手工图——两边对不上,说明图错了或者有设备没纳管,两种情况都值得追。
自动化落地要过三道坎,提前知道能省很多时间:
- 权限:需要一个只读账号,能执行
display lldp neighbor和show lldp neighbors,不要用管理员账号。 - LLDP 没开:很多环境默认关闭,或者只在一个方向开。先在核心和汇聚上开,接入交换机视情况。
- 跨厂商命名不一致:华为输出的对端名字可能是系统名(sysname),思科是 hostname,云上设备干脆没有。要在脚本里做名称归一化,否则图上会出现同一个设备两个名字。
还有一个实际问题:图应该存在哪、谁能改。建议放在团队共享的知识库里(Confluence、语雀、内部 Wiki),设两个人有编辑权、全员可读。不要只存在某个人电脑上——那个人一休假,图就没人能更新,三个月后就变成"历史文件"。同一个目录里放三个东西就够了:图源文件(.drawio/.dot)、导出的 PNG、一份 CHANGELOG 记录每次改了什么。
六、维护机制:让图不烂掉的三个动作
图画好那天是最准的一天,之后就开始腐烂。要有机制对抗这件事:
- 变更触发——把"更新拓扑图"写进变更流程的检查项。割接、上新设备、换防火墙、开新专线,变更单里必须包含"拓扑图已更新"这一条,否则不予关闭。
- 季度核对——每季度用自动发现脚本跑一遍,和图上对 diff。差异分两类:图漏画的(补图)、设备没纳管的(补台账)。
- 应急反查——每次应急结束后回看图,检查"这次为什么没在图上快速定位"。如果是因为图不准,就把这条写进复盘,作为改进项。
配套一个很小但很有用的动作:给图加版本号和日期,在标题下标明"v2026.10 / 更新人 / 数据来源:NetBox 导出 + LLDP 核验"。这样任何人拿到图都知道它有多新。
七、混合云环境怎么画:把 VPC 当成一个"安全域"
现在几乎没有纯本地的网络了,拓扑图不画云上部分,等于把一半资产藏起来。云上部分的画法有一个简化技巧:把每个 VPC 当成一个安全域来画,不画到具体实例。
一张 VPC 内部图需要标清楚的只有六样:
| 要素 | 画什么 | 为什么重要 |
|---|---|---|
| VPC 与网段 | VPC 名称 + CIDR | 判断和其他 VPC/IDC 是否地址冲突 |
| 子网划分 | 公有子网 / 私有子网 | 决定谁能直接暴露在互联网 |
| 安全组与 ACL | 关键规则摘要(放通哪些端口给谁) | 90% 的云上事故出在这里 |
| 出网方式 | NAT 网关 / EIP / 代理 | 决定能不能被外联,也决定出事后怎么封 |
| 与本地打通 | 专线 / VPN / SD-WAN + 对端网段 | 这是横向移动的主通道 |
| 云上安全能力 | 云防火墙、WAF、日志审计、态势感知 | 决定取证数据从哪拿 |
画的时候最容易犯两个错。一是把 VPC 画成一个整体、不标子网,结果"这个系统在公有子网还是私有子网"这个问题永远答不上来——而这个判断直接决定它是不是暴露面。二是不画安全组的放通规则摘要,图上只写"安全组已配置",出事时还得登控制台一条条翻。
还有一个更隐蔽的问题:云上资源的命名和本地不一致。本地叫FW-DMZ-01,云上叫sg-wz9xxxx、vpc-bp1yyyy,图上一半中文一半随机串,看起来像两张不相干的图。解决办法是给云上资源建一层"业务别名"映射表,图上只写别名,随机 ID 放在备注或台账里。
如果你同时有多个云和自建机房,建议在最高层画一张"云与 IDC 关系图":左边画自建机房,右边画各个云,中间用粗线标出专线/VPN 及带宽,线上标注"哪些业务走这条"。这张图不需要多细,但它能回答一个高层问题:一次专线中断,会影响哪些系统。这个问题在被领导和业务追问时,几乎每次都会出现。
八、几个具体场景怎么用这张图
拓扑图不是挂在墙上的装饰,它应该在具体场景里被翻出来:
- 应急响应:判断攻击者从哪个区进来、能不能横向到生产区、封哪个边界设备最有效。这时候图上"区域之间的隔离设备"那一层就是决策依据。相关处置顺序见应急响应复盘。
- 漏洞整改:一个高危漏洞出现在边界防火墙上,判断影响面要看图——它串在谁前面、后面有几个区。方法在漏洞整改推动。
- 等保测评:网络架构、边界防护、区域划分这三项全部靠图取证。对应条款的写法见等保2.0定级备案与差距分析。
- 变更评审:新增一条专线、打通两个区,图上看一眼就知道会不会绕开边界设备形成旁路。
九、写在最后
拓扑图这件事,判断标准只有一条:出了问题,能不能在五分钟内靠它定位到设备或链路。能的图就是好图,画得再漂亮但对不上现实的,等于没有。
所以优先级是:先保证"准"(自动发现 + 变更触发),再保证"全"(三张图分清楚),最后才是"好看"。很多人顺序做反了,花两周做了一张漂亮的汇报图,三个月后彻底过期。
配套的工具清单:LLDP 采集 + Graphviz 出图的脚本在上面的第五节,资产台账可以复用安全基线那套分层思路做设备分级,数据侧的资产梳理看数据分类分级落地。
你们环境里拓扑图是哪个部门维护的?如果是运维维护、安全用,中间这道交接最容易出问题,评论区说说你们怎么分工的。