告别Excel台账:PLFM_RADAR内网资产测绘与变更追踪实践
发布时间:2026/10/2 11:57:47来源:尧图网络
做 PLFM_RADAR 这个项目起因特别朴素我被一套已经过时的 Excel 资产台账坑过一次。当时线上环境悄悄加了一批服务只有发起人自己知道几个月后做隐患梳理时谁都不清楚那批服务到底暴露了哪些端口、跑的是什么组件最后只能靠一台台机器手动问效率低到让人怀疑人生。PLFM_RADAR 就是针对资产不清、变化不知、台账失联这类问题做的一套轻量级资产雷达平台它会周期性扫描定义好的目标网段自动识别存活主机、开放端口、服务指纹把每一次变化记录成资产变更事件再推送到告警渠道。适合运维、安全巡检、基础架构的同事当内部资产梳理工具用也适合想了解资产测绘、指纹识别怎么落地的人做参考。先画个边界所有扫描目标都必须在授权范围内建议只在公司自有内网或已签署测试授权的环境中运行。这不是一个以绕过限制为目的的工具而是帮你把家底管清楚的平台。1. 为什么会有 PLFM_RADAR被一张 Excel 台账坑过之后1.1 真正的痛点不是没有资产清单而是清单会过时大多数公司不是没有资产记录而是记录活在某个人的电脑里或者活在维护人的脑子里。我接手的时候项目组给了一张所谓的全网资产清单里面有 IP、负责人、用途看起来挺全。结果我随手抽查了 40 个 IP有 9 个已经迁移走了还有 7 个新服务完全不在表里存量设备的端口变动更是没有任何记录。那一刻我意识到手工维护的台账有一个天然的致命伤它是静态的而网络环境是动态的。只要有人部署一个新服务、改一个端口、下线一台机器台账就立刻失真而你根本不知道它从哪一刻开始错的。PLFM_RADAR 的出发点就是把这个未知变成已知。它不需要人肉去更新而是自己定期把目标网段扫一遍谁活着、谁挂了、谁开了新端口、谁换了服务全部自动落到数据库里。相比传统盘点完就结束的扫描任务我更愿意把它理解成一套持续运行的资产监控探头。1.2 谁需要这个东西运维团队梳理网络资产、清理僵尸主机、确认勒索病毒排查时有没有漏网之鱼。安全团队做暴露面梳理、基线合规检查知道哪些服务不该对外开放。基础架构 / 网管机房或云上资源一多想快速确认某个网段的实际占用情况。DevOps发布系统对接 CMDB 前需要一份自动更新的服务清单作参照。它不追求像商业攻击面管理平台那样覆盖全球测绘能力核心解决的是一个组织内部如何持续掌握自己的资产状态。你如果刚开始做资产梳理完全可以从这个小平台起步。1.3 和传统扫描器定位的差异传统扫描器解决的是这个 IP 有哪些漏洞而 PLFM_RADAR 更关注这个网段现在有什么、和上次比变了什么。前者是单次深度检查后者是持续基线跟踪。所以我的设计重点不是堆漏洞库而是把发现的准确性、变化的可追踪性、告警的低噪音做好。定位想清楚之后后面的架构选择就顺了很多。2. 整体设计与核心模块拆解2.1 PLFM_RADAR 的命名逻辑和定位名字一开始就定了两个词PLFM 代表 PlatformRADAR 代表雷达。我要的是一个平台化的资产雷达而不是一次性的扫描脚本。雷达这个意象其实特别准雷达不停发射波束、接收回波、识别目标、跟踪航迹PLFM_RADAR 做的事情在逻辑上完全一致——周期性发射探测包、接收响应、识别服务特征、持续跟踪资产变化。只要目标网段被纳入扫描范围它就会像雷达扫描空域一样一遍一遍地刷新你对整个网络的认知。平台化的意思是不是一个人手动敲命令而是提供配置、调度、存储、告警、查询一整套闭环。你只需要在配置里声明我要看哪些网段、多久看一次剩下的都交给平台自动执行。2.2 为什么没有直接拿现成扫描器凑合用第一个想到的方案肯定是 Nmap说实话它的端口扫描能力非常强。但直接套 Nmap 会碰到几个实际问题第一资产识别只是第一步我更需要变化追踪Nmap 本身不存历史状态你得额外写一堆脚本去维护基线第二对内网几千台设备来说全量扫描产生的任务管理、并发控制、结果入库靠 shell 脚本会很快失控第三指纹识别需要跟自家业务组件做适配通用指纹库对内部系统的识别率不够理想。与其在外围打补丁不如把核心链路自己搭一遍。技术选型上我用了 Go 做探测引擎纯粹是看中它的并发模型和单二进制部署特性任务调度和扩展逻辑用 Python 写库生态丰富改起来快Redis 当中转队列PostgreSQL 存资产和变更记录。这套组合不是唯一解但对我来说是最快能跑起来、又能顶住几千资产规模的方案。2.3 数据模型把资产当对象建模资产表是核心中的核心字段设计直接决定后面能不能做变化追踪。我的核心表结构大概是这样的assets资产表id、ip、hostname、os_hint、scan_source、first_seen、last_seen、is_alive、tagsasset_ports端口/服务表asset_id、port、protocol、service_name、banner、fingerprint_id、first_seen、last_seenchanges变更记录表asset_id、field_name、old_value、new_value、change_time、change_typescan_tasks任务表id、target、scan_type、cron_expr、enabled、last_run_at关键点在于把资产和资产上的服务拆成两张表。一开始我图省事把端口直接拼成 JSON 塞进 assets 表结果想查哪些资产开了 3389时写出来的 SQL 又丑又慢。拆开后一切清晰资产是主体端口和服务是挂在资产上的属性集合每一次扫描只是更新这些属性同时把差异写入 changes 表。这套模型跑了大半年没做过结构性调整。3. 核心实现要点与踩坑调优3.1 探测引擎并发、超时、端口范围探测引擎主要负责三层事主机存活探测、端口可达探测、服务信息抓取。主机存活这块内网环境我优先用 ICMP ping 和 ARP 探测的组合。ARP 在二层环境下非常快但碰到三层路由隔离就失效ICMP 大多数内网设备都会响应但不排除有人为禁 ping 的设备。所以我的策略是ICMP 为主发现不响应但端口有回包的设备照样标记为存活。实际操作中这条规则极大地减少了漏报。端口探测我直接做了 TCP Connect 扫描虽然比 SYN 扫描多一些连接开销但在内网环境里胜在稳定不需要特殊权限。真正要调的是超时和并发。很多人一上来就开 1000 并发结果网关直接被连接风暴打满线上业务跟着抖。我最终把并发控制在 200300单端口超时设 800ms 到 1.5s整个扫描耗时和稳定性是能接受的。端口范围分两级默认先扫常见 Top 端口然后再按需做全端口。常见端口列表我用的是 20/21/22/23/53/80/443/445/3389/3306/6379/8080/8443/9200 这一档基本覆盖了内网大部分服务。对那些需要做全端口深扫的资产通过任务配置单独指定避免每轮都全量打一遍。probe: concurrency: 256 tcp_connect_timeout_ms: 1000 host_discovery: enabled: true use_icmp: true use_arp: true port_strategy: common_ports: [21,22,23,53,80,443,445,3389,3306,6379,8080,8443,9200] full_scan: false3.2 指纹识别从误报率 28% 调到 6% 的实操记录指纹识别是 PLFM_RADAR 里最磨人的模块没有之一。它的目标是识别出端口后面跑的是什么服务比如这是一个 Nginx 1.20 还是 Apache 2.4、这是个 Redis 还是 Memcached。第一版我贪快直接靠 banner 里的版本字符串做关键字匹配结果现实非常打脸。很多服务的 banner 极其相似或者干脆不输出 banner。比如企业内部的一堆 HTTP 服务响应头都长一个样靠 Server 头去区分误报率能到 28%。后来我加了四层特征联合判断端口默认服务 连接 banner HTTP 响应头/标题 应用层协议行为。比如判断 Redis除了看端口是 6379还要实际发一条 PING 命令看返回是不是PONG。判断 Web 服务除了看 Server 头还要抓首页标题、favicon.ico 的哈希、TLS 证书的 CN 字段。指纹库的格式我定为一条规则一个 JSON 块匹配项支持多种运算符{ name: redis, priority: 80, conditions: [ {layer: port, op: eq, value: 6379}, {layer: banner, op: contains, value: redis_version}, {layer: protocol, op: redis_ping, value: PONG} ] }匹配顺序按 priority 从高到低命中即停。这个设计解决了很大一类问题有些服务端口是 8080但实际跑的却是自定义二进制协议如果只按端口猜永远猜不对。另外我强制要求一条规则至少要两个条件同时命中才算成立单条件命中只输出疑似级别。这样做之后误报率从 28% 降到 6% 左右代价是有的服务不再精确到版本只输出到服务类别但对资产梳理这个场景来说准确率远比猜得很细重要。3.3 任务调度全量、增量与扫描耗时估算调度模块绕不开一个问题多长时间扫一次我的方案是分层调度。核心资产网段每天全量扫一次边缘网段每三天扫一次重点端口比如对外业务端口单独做增量快速探测每 15 分钟一轮专门盯变化。全量扫描负责把账对平增量扫描负责快速感知变化两条腿走路比只做一种要实用得多。耗时估算有个简单公式可以提前算单 IP 并发扫描耗时 ≈端口数 × 平均超时时间÷ 并发数。举个例子一个 /24 网段有 254 个 IP扫 100 个端口平均超时 1s并发 256理论耗时约 100 秒。但实际还要加主机发现和指纹抓取的时间保守按三倍算300 秒左右能完成一轮。如果你用这个公式估出来一轮要跑几小时那就该拆网段并行或者降低频次了不要硬撑。任务积压是我踩过的一个坑。有一段时间扫描任务发到 Redis 里worker 消费不过来积压了上千个任务后面轮次的扫描全堵在一起告警也一起延迟触发。后来我在任务表里加了last_run_at和状态锁同一个目标同一时刻只允许一个任务在跑新的任务发现旧任务未结束就自动跳过保证数据不会乱掉。# 伪代码防止同一目标重复扫描 def acquire_task_lock(target): lock_key fscan_lock:{target} if redis.set(lock_key, 1, nxTrue, ex3600): return True return False3.4 告警与降噪别让自己被消息淹死告警做不好再好的扫描平台也会被拉黑。我刚开始是一变就告警结果一个服务升级引发的端口变化能把告警群刷屏第二天就被同事投诉了。后来我加了三条降噪规则归类合并、时间窗收敛、时段静默。同一资产在一小时内的所有变更合并成一条告警同一类型变更每天只推一次摘要非工作时间只发紧急变更普通入库不推送。告警内容我直接推 Webhook 到内部协作平台每一条带资产 IP、变更类型、旧值和新值、发现时间。这样谁看了都能直接判断是新服务上线是配置变更还是有人在偷偷开高危端口有一次新增了一个 6379 端口告警 15 分钟内就到群里排查后发现是一台测试机被人装了 Redis 且没有认证顺手就处理了。这种接地气的效果是我做这个项目最有成就感的时刻。4. 实操过程把一条 /24 网段完整跑一遍4.1 部署环境与容器化配置PLFM_RADAR 我打包成了 Compose 项目三个容器scannerGo 探测引擎、serverPython 调度与 API、redis postgres基础依赖。部署本身不复杂但有几个配置要说一下。scanner 容器需要NET_ADMIN或透传某些系统的能力才能用到 SYN 扫描我为了降低部署门槛直接用 TCP Connect这样普通容器权限就够了生产环境也没那么多限制。version: 3 services: redis: image: redis:7-alpine db: image: postgres:15-alpine environment: POSTGRES_DB: plfm POSTGRES_USER: plfm POSTGRES_PASSWORD: change_me scanner: image: plfm-radar-scanner:latest depends_on: [redis, db] server: image: plfm-radar-server:latest ports: [8000:8000] depends_on: [redis, db, scanner]提醒一句默认账号密码一定要改资产数据本身也是敏感信息数据库不要用默认端口暴露到公网或者大内网。4.2 初始化配置目标、频次、指纹库部署起来之后先配置扫描目标。我把目标定义做成 YAML支持网段、单 IP、端口模板三种粒度。这样既能扫整个 /24也能单独指定某台机器做全端口深扫。第一次配置我只放了一个 /24 网段进去包含办公网的一部分和测试机区域。频次设置了全量每日一次、增量每 15 分钟一次确保改动能被快速捕捉。指纹库这边除了内置的常见服务规则我额外加了几个公司内部系统的规则。比如内部的统一认证系统特征是某个特定 URL 返回固定标题端口经常是 8081把它加进指纹库之后后续扫到就能直接打上内部门户标签不用每次靠人看。关键的配置段长这样targets: - name: 办公网-测试段 cidr: 192.168.50.0/24 full_scan_ports: false scan_freq_cron: 0 2 * * * alert_group: it-assets - name: 认证服务专扫 cidr: 192.168.50.18/32 full_scan_ports: true scan_freq_cron: 0 */6 * * * alert_group: it-assets4.3 执行扫描与结果验证配置完成后触发首轮全量扫描。我一路盯着日志最开始非常顺利主机发现阶段就发现了一个问题办公网段比 Excel 台账多出来了 5 台未知设备。逐一查了下有两台是某部门临时拉的测试服务器设计文档里没有登记还有两台是已经下线但没断电的老机器。这就是资产台账失真的最典型表现不是你找得不够细而是根本没有人在维护。首轮扫描完成后我把结果和手工核查做了一个对比验证。随机抽了 20 台存活设备逐台登录确认端口和服务结果有 18 台完全一致1 台漏报了某个 UDP 服务因为默认不扫 UDP1 台指纹识别归错了类。这个准确率我已经可以接受毕竟资产梳理要的是知道有什么不是证明什么都没有。UDP 服务我后来在配置里单独加了几个常见端口补充扫描指纹误判也通过调整规则优先级修复了。5. 常见问题与排查实录问题现象可能原因解决办法某台主机明明在线扫描结果里却没有主机存活探测被 ICMP 规则拦截且该机没有常见端口开放开启 ARP 探测或把该 IP 加入强制存活检查列表指纹识别错误率高指纹规则优先级冲突或单条件误匹配每条规则至少双条件命中关键服务增加协议层验证扫描期间线上业务告警并发数过大触发网络设备限流调低并发到 200 左右按网段错峰扫描任务堆积告警延迟Redis 队列消费慢或同一目标重复入队加任务锁同一时间只允许一个扫描任务运行数据库占用增长过快每次扫描全量写资产快照只写变更记录资产表只更新last_seen重复告警刷屏缺少告警收敛机制同资产变更 1 小时合并同类型每天只推摘要上面表格里最值得展开的是扫描期间线上业务告警。我一开始觉得并发调高一点没关系结果 500 并发打到办公网核心交换机上某台网络设备 CPU 直接飙到 80%线上呼叫系统跟着抖动。这个教训告诉我扫描不是压测目标是要拿到准确信息而不是把业务扫挂了。后来我把扫描时间统一安排到凌晨两点并发降到 256才彻底平息了运维同事的怒火。另外一个隐蔽问题是资产表里first_seen和last_seen的语义。早期我每次扫描都把新发现直接写进资产表端口变化也直接更新结果想回答这台机器第一次出现是什么时候就非常困难。后来我改成资产存在性不变时只更新last_seen只有新 IP 才写first_seen端口变化一律走 changes 表。这样既保留了历史又不会让资产表无限膨胀。6. 后续扩展与个人体会6.1 从资产清单走向 CMDB 联动PLFM_RADAR 跑稳之后最自然的扩展方向就是对接 CMDB 或云资产 API。目前我们把它当成 CMDB 的校正数据源CMDB 里定义业务归属和负责人PLFM_RADAR 负责确认这些资产是否真实存在、状态是否一致。两边数据不一致时以扫描结果为准发起复核效果比两边各说各话好得多。对接云平台 API 也是一样把云上资产清单导入作为预期值再和扫描结果比对能发现很多被遗忘的按量计费机器成本上也划得来。6.2 把看到变化升级为看懂变化再往后走我觉得这个项目还能长成一个更完整的平台可观测底座。不光记录端口变化还能追踪域名解析变化、证书到期时间、Web 框架版本变更把这些信息和告警系统、报表系统串起来。相当于从资产雷达升级成风险雷达。不过这些是后话基础还是先把自己家里有什么搞明白别台账里的那点东西都靠猜。跑了大半年之后我的一个直观体会是资产梳理项目不怕技术难最怕的是方向没定清楚。你把持续发现变化这个核心目标抓住了后面每一步都会自然长出来。PLFM_RADAR 这个名字起得比较工程化但它解决的问题特别接地气别再让团队把时间浪费在一份永远不准的清单上。如果你也被过时台账坑过照着这个思路从一条 /24 网段开始扫起来一定会有收获。
网站建设高端定制企业官网