自动处置离线干跑矩阵(ar-local-matrix.py)¶
位置:
deploy/nfos/tools/ar-local-matrix.py| 语言:python3 | 是否需要 root:否
工具性质:离线干跑矩阵(纯评估不动系统;子进程一律 --dry-run;会写自己的临时目录)
运行前提:仓库检出必须在场 —— 把 deploy/nfos/monitoring/auto-respond.py 当子进程跑。可从任意位置运行(工具自动向上找到含 deploy/nfos 的祖先目录)
部署状态:随仓库检出运行,不部署到 /opt/Cy/services/system.d/nfos/
用途¶
对 deploy/nfos/monitoring/auto-respond.py 做本地干跑矩阵:把一批构造好的告警条目逐条喂给它,核对“该封禁的封禁、该拒绝的拒绝、该转人工的转人工”。
源码 docstring(逐字引用):
矩阵共 17 个用例,覆盖:
| 类别 | 用例(标签逐字来自源码 CASES) |
|---|---|
| 应动作 | WA-002 公网 IP(应自动封禁)、RS-002 普通反弹 shell 进程(应取证+杀+封对端)、MW-002 解释器执行 /tmp 脚本(应取证+杀+隔离)、AU-001 SSH 爆破公网源(应 nft drop) |
| 应拒绝 | WA-001 私网 IP(应拒绝)、WA-002 运维出口白名单 IP(应拒绝)、WA-002 回环(应拒绝)、WA-002 邮件中继(应拒绝,防自断告警邮件)、MW-001 关键路径载荷(应拒绝隔离)、AU-001 来源是运维白名单网段(应拒绝) |
| 应抑制/不动作 | RS-001 平台告警通道 ticket-notify.py(应 suppress 不动作)、RS-003 sshd 派生 shell(受保护/不动作) |
| 不处置、转人工开单 | PS-001 计划任务新增(不处置,转人工开单)、IN-001 信任根被修改(不处置,转人工开单)、EG-001 异常外联(不处置,转人工开单)、SL-001 日志异常(不处置,转人工开单) |
| 输入健壮性 | 输入非法 JSON(应 INTERNAL 且退出码 0) |
每个用例的调用方式(源码):subprocess.run([PY, AR, "--dry-run"], input=<JSON>, capture_output=True, env=env, timeout=120),其中 PY = sys.executable or "python3";随后解析最后一行 stdout 为 JSON,并打印 exit / handled / suppress / escalate / reason_code / would_handle、action、targets、planned_steps、detail。
末尾固定打印 非零退出数: <N>(必须为 0)、三个“应为 False”的落盘状态、以及 MATRIX_DONE。
典型场景¶
- 改动
auto-respond.py(--dry-run分支、白名单判定、suppress 规则、planned_steps文案)之后的提交前回归; - 白名单/防自断逻辑出问题时(例如把邮件中继
122.14.236.108或平台告警通道的ticket-notify.py误封)在本地复现; - 新加特征签名时,用矩阵确认它在
auto-respond里的处置分类(动作 / 拒绝 / 抑制 / 转人工)符合预期。
用法与参数¶
源码 docstring 给出的用法(逐字引用,.scratch/ 为升级前旧路径,本页按新位置书写为 python deploy/nfos/tools/ar-local-matrix.py):
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| (无命令行参数) | — | — | 不读 sys.argv、无 argparse |
AR_VERBOSE |
环境变量(可选开关) | 未设置(假) | 非空时额外打印每例的 commands 与子进程 stderr(截断 300 字符) |
无参数时的默认行为:跑完 17 个用例,打印汇总与 MATRIX_DONE。
示例¶
从仓库根目录执行:
需要看每例的 commands 时:
期望输出(实测:退出码 0,末行 MATRIX_DONE):
非零退出数: 0(必须为 0)
工作目录(tmp): ...\deploy\nfos\tools\ar-tmp
状态文件是否被写(应为 False): False
审计日志是否被写(应为 False): False
封禁清单是否被创建(应为 False): False
MATRIX_DONE
| 情形 | 期望退出码 |
|---|---|
正常跑完(末行 MATRIX_DONE) |
0 |
| 某个用例子进程非 0 | 仍是 0(只把 非零退出数 累加并打印 !! 退出码非 0) |
脚本自身崩掉(如 deploy/nfos/monitoring/auto-respond.py 路径不存在、临时目录不可建) |
1(Python traceback) |
重要:本脚本没有
sys.exit,退出码不代表矩阵结论。判定必须看非零退出数: 0(必须为 0)这一行以及上方逐例的handled / suppress / escalate / action是否与用例标签相符。
依赖与权限¶
- 语言/版本:Python 3(
#!/usr/bin/env python3)。 - 第三方依赖:无,标准库
json/os/shutil/subprocess/sys。 - 仓库依赖:必需 —— 子进程执行
<repo>/deploy/nfos/monitoring/auto-respond.py;_nf_repo_root()向上找第一个含deploy/nfos的祖先目录。 - 权限:不需要 root;需要工作区写权限(建
ar-tmp)。矩阵会写一份临时特征库与一组环境变量,全部指向临时目录。
风险与注意事项¶
- 不在真机上执行系统动作:子进程固定带
--dry-run;env把NFOS_AR_ROOT/NFOS_AR_NGINX_D/NFOS_AR_NFOS_DIR/NFOS_AR_LIBOPS/NFOS_AR_GUARD全部重定向到临时目录,NFARMSD_API指向http://127.0.0.1:19990(不会打到真实平台),并设NFOS_AR_MAX_ACTIONS=3。因此不会封 IP、不会执行 nft/nginx 变更、不会写线上状态。 - 会写文件(自己的临时目录):
<工具所在目录>/ar-tmp/—— 源码写作tmp = os.path.join(HERE, "ar-tmp"),而HERE = os.path.dirname(os.path.abspath(__file__)),即产物落在工具旁边:deploy/nfos/tools/ar-tmp/。该目录在每次启动时先shutil.rmtree再重建,内含: ar-tmp/nfos/signature-library.yml(矩阵自带的临时特征库,含白名单网段)ar-tmp/nfos/lib-ops.sh、ar-tmp/nfos/security-guard.sh(路径占位,指向临时目录)ar-tmp/logs/、ar-tmp/nginx.d/(运行期目录)- 末尾三项自证:脚本会打印
logs/auto-respond.state.json、logs/auto-respond.log、nginx.d/10-nfos-blocklist.conf是否存在,期望全为False—— 若出现True,说明--dry-run语义被破坏,属于需要立刻排查的回归。 - 用工作区内的临时目录是有意设计(源码注释:Windows 上
%TEMP%在沙箱里可能不可写),所以别指望它落在系统临时目录。 - 环境变量是传给子进程的,不修改当前 shell;但
HERE依赖脚本自身位置 —— 若把本工具挪出deploy/nfos/tools/,ar-tmp会跟着挪到新位置。
回滚¶
本工具不部署到线上、不改线上系统;不产出交付物。
- 产出/改动位置:
deploy/nfos/tools/ar-tmp/(每次运行自动清空重建)。 - 清理方式:
- 不写
auto-respond.state.json/auto-respond.log/ 封禁清单到线上路径(末尾三项自证应全为False);因此无需回滚线上自动处置状态。