为什么“能扫”不等于“能用”
很多漏洞扫描脚本的实际情况是:
- 能连上机器
- 能判断有没有漏洞
- 打印一堆结果
但在内网环境里,这种脚本基本用不起来。原因很简单:
- 机器多了就跑不动
- 扫描和修复混在一起,不敢直接跑
- 执行过程不可控,卡住也不知道
- 结果没法复用,只能人工看
这个项目要解决的,不是“能不能扫”,而是:
能不能在真实环境里反复、安全地用
资产配置:把“目标机器”变成“配置”
第一步不是写逻辑,而是把机器抽出来。
用 fleet.env 管理所有设备:
DEVICE_1_HOST=192.168.1.10
DEVICE_1_USER=root
DEVICE_1_KEY=./keys/node1
再用:
FLEET_COUNT=3
控制数量。
这样做之后,脚本不再关心“要连哪台机器”,只负责:
- 读配置
- 遍历设备
- 执行动作
这一步的意义很直接:
- 可以复用
- 可以批量跑
- 不需要改代码
执行模型:必须并发 + 必须可控
单线程跑几十台机器基本不可接受。
这里做了两件事:
MAX_WORKERS=8
控制并发数。
DEVICE_MAX_DURATION_SECONDS=1800
限制单台机器最长执行时间。
结果是:
- 多台机器同时跑
- 某一台卡住不会拖死整体
这一步不复杂,但很关键。没有这个,工具在生产环境基本不可用。
执行模式:检测和修复必须分开
很多脚本的问题是:
- 一跑就改系统
这种在生产环境基本没人敢用。
这里强制分两种模式:
MODE=audit
MODE=fix
audit
- 只检测
- 不做任何修改
fix
- 先做临时缓解
- 再尝试修复
- 可选是否重启
AUTO_REBOOT=0
这样可以做到:
- 先全量扫一遍
- 再挑一部分机器修
- 最后再复检
而不是一次性全动。
修复逻辑:不是一步完成
修复分两层:
1. 临时缓解
- 禁用
algif_aead - 尝试卸载模块
优点是:
- 快
- 不依赖重启
- 可以立刻降低风险
2. 内核升级
- 按发行版升级内核
这是最终解决方案,但有几个现实问题:
- 需要维护窗口
- 可能要重启
- 不能一次性全做
所以必须把这两步拆开。
状态定义:结果要能用,不只是能看
不是简单输出“有漏洞 / 没漏洞”,而是给每台机器一个状态:
- SAFE
- MITIGATED
- NEEDS_PATCH
- UNKNOWN
- FAILED
这样做的目的很实际:
- NEEDS_PATCH → 后续重点处理
- FAILED → 单独排查
- MITIGATED → 已经降风险,但还没彻底修
这比一堆文本输出有用得多。
报告输出:不是给人看的,是给系统用的
每次执行会输出:
- JSON
- CSV
- Markdown
- 执行日志
核心信息包括:
- 主机
- 系统版本
- 模块状态
- 修复情况
关键点在于:
- JSON 可以被其他系统接入
- CSV 可以直接给运维用
- Markdown 用来查看结果
不是为了好看,是为了后续处理。
执行过程:必须能看到进度
加了两个配置:
PROGRESS_HEARTBEAT_SECONDS=5
PROGRESS_LOG_TO_FILE=1
效果是:
- 执行过程中有持续输出
- 长任务不会看起来像“卡死”
- 日志可以回看
这在批量执行时很重要。
< Back to blog list