AI 智能检测
AI 智能检测
AI 智能检测用一个轻量机器学习模型识别异常请求,作为现有规则引擎(SQL 注入、XSS、OWASP 等)的补充层,专门补规则的盲区:变形绕过、混淆、未知 payload。
模型用你自己的日志在本地训练,训练数据不出本机,符合 SamWaf 私有化部署原则。推理在 SamWaf 内部用纯 Go 完成,不依赖 Python / GPU / 外部服务。
总体流程
积累日志 → 导出脱敏训练数据 → 本地训练打包(.swai) → 上传模型 → 观察模式核对误报 → 切拦截模式一、准备训练工具(SamWafAI)
训练在独立的 SamWafAI 工具链完成,只需安装 uv:
cd SamWafAI
uv sync # 一键建好隔离环境二、导出训练数据
⚠️ 重要:先修正规则误报,再导出 导出默认用「规则命中」当训练标签,但规则可能误报——把正常请求误拦了,导出时就会被错标成"攻击",喂给模型会把误报固化甚至放大。为此:
- 导出采用保守信任:未经人工确认时,只信任高精度检测器(SQLi/XSS 走 libinjection、OWASP、RCE、目录穿越)的命中当攻击样本;扫描器(靠 UA 判定,curl/python-requests 等合法工具也会命中)、自定义规则等易误报来源,不人工确认就不当攻击(不会进训练正样本)。
- 在防御日志里可逐条标记修正:对某条记录点操作列的「AI标记」→ 选「误报(正常)」「确认攻击」或「忽略(不参与训练)」。人工标记优先于规则弱标签,导出时按你的修正来。
- 要批量清洗时,去 AI 模型管理 → 训练标注:这是一个集中的标注工作台,可按「站点 / 时间 / 标记状态(未标记…) / 分数」过滤,勾选多条后一键批量标为「正常 / 确认攻击 / 忽略」,点行「详情」还能看完整请求(Query/Body/UA)再单条标注(详情打开时按键盘 1/2/3 快标)。建议把「标记状态」选成"未标记",逐批清理。
- 建议流程:先在训练标注工作台把明显的误报批量标成"正常"、把确认的攻击(尤其扫描器这类默认不自动信任的)标成"确认攻击",再导出。
两种方式任选其一:
- 管理端导出(推荐):进入 AI 模型管理 → 导出训练数据,选择天数与条数,点击导出。系统会把脱敏后的训练数据写到服务器
data/ai_export/train_*.jsonl。导出时自动按规则命中做弱标签,并对敏感参数二次脱敏。 - 直接读日志库:用 SamWafAI 读取 SamWaf 的 SQLite 日志库:
uv run samwafai export-data --sqlite samwaf_log.db --out build/train.jsonl
没有足够日志时,可先用公开数据集训练一个起步基线模型(见 SamWafAI 的 examples/)。
导出文件里装了什么(重要)
一次导出会生成一个 train_*.jsonl 文件,里面是两部分合并的样本,不是只用你标记的内容:
| 部分 | 来源 | 受导出条件(天数/条数)限制? | 怎么打标签 |
|---|---|---|---|
| 第 1 部分 | 你没标记过的日志 | ✅ 受限制 | 用规则弱标签 + 保守信任:规则放行→正常样本;规则判攻击但只有高置信(SQLi/XSS/OWASP/RCE/穿越)才采纳,低置信(扫描器/自定义)未确认则丢弃 |
| 第 2 部分 | 你的全部人工标记 | ❌ 不受限制 | 用标记时的请求快照产出:确认攻击→正样本(带你选的分类)、误报→负样本、忽略→丢弃。来源标 source=manual |
要点:
- 不是只用你的标记,而是「自动弱标签(你没碰过的) + 你的全部人工标记」合并成一份文件。
- 冲突时人工标记优先:凡是你标记过的记录,第 1 部分都会跳过,只走第 2 部分,所以你的修正不会被规则弱标签盖掉。
- 第 2 部分用的是标记时固化的快照,因此不受导出窗口(天数/条数)限制,哪怕原始日志已被清理、或落在导出窗口之外,你的标记照样能产出,不会漏。
三、训练并打包
💡 不想装 Python? 可在 SamWafAI Releases 下载免-Python 训练器(Windows64 / Linux64 单文件),把下面命令里的
uv run samwafai换成./samwafai(或samwafai.exe)即可,用法完全一致,数据同样不出本机。
uv run samwafai train --train build/train.jsonl --out build/model_lgbm.txt
uv run samwafai eval --model build/model_lgbm.txt --test build/train.jsonl --json-out build/eval.json
uv run samwafai package --model build/model_lgbm.txt --version myorg-v1 --eval-json build/eval.json --out build/model.swaieval 会打印不同误报率下的召回与建议阈值——WAF 最该关注误报,建议把拦截阈值定在误报率 ≤ 0.1% 处(package 会自动采用 eval 的建议阈值)。
也可一键完成:
uv run samwafai pipeline --train build/train.jsonl --test build/test.jsonl --version myorg-v1 --out build/model.swai四、上传模型并开启
- 进入 AI 模型管理,上传
model.swai。上传时会校验特征版本与文件完整性,通过后立即热加载,无需重启。 - 到 系统配置 把
ai_enable设为1,ai_mode选observe(观察)。 - 在需要防护的站点设置 → 防护配置里把「AI 智能检测」打开。
五、观察 → 拦截
- 观察模式(observe):命中只在防御日志里标注类别(
AI检测:<类别>,如AI检测:SQL注入),并把分数记到独立的 「AI得分」列,请求照常放行。建议跑 1–2 周。- 集中查看:在防御日志按「仅记录=是」筛出 AI 观察命中,点「AI得分」列排序,从高分往低核对。
- 核对 AI 命中是真攻击还是误报。误报样本可标记后导出回灌,再训练一版模型。
- 误报可接受后,把
ai_mode切到block,达到拦截阈值的请求才会被拦。
六、阈值说明(拦截阈值 / 观察阈值)
模型管理页会显示当前模型的两个阈值,例如「拦截 0.974 / 观察 0.6818」。它们来自模型包 .swai 里的 manifest.json,是 samwafai eval 在测试集上算出、samwafai package 写进去的,引擎按它们判定命中。
- 拦截阈值:对应「误报率 ≤ 0.1%」的分数线。算法是把测试集里所有正常请求按模型打分排序,取第 99.9% 分位的分数。含义:阈值定在这,只有约 0.1% 的正常请求会被误判为攻击。WAF 最怕误杀业务,所以默认把拦截线卡在这个可接受的误报率上。
- 观察阈值:默认 = 拦截阈值 × 0.7,比拦截线低,让更多「可疑但没到拦截线」的请求进观察日志,方便上线前核对。
引擎对每个请求按分数 score 判定:
| 条件 | 行为 |
|---|---|
score < 观察阈值 | 当正常放过,不记录 |
观察阈值 ≤ score < 拦截阈值 | 观察命中(记日志 + AI得分,不拦截) |
score ≥ 拦截阈值 且 ai_mode=block | 拦截(observe 模式下仍只记录) |
调整方式:
- 打包时手动指定:
uv run samwafai package --block-threshold 0.9 --observe-threshold 0.6 ...,不传则用eval的建议值。 - 想整体更严/更松:改
samwafai/train/evaluate.py里的RECOMMEND_FP_RATE(默认 0.001 即 0.1% 误报;调小更严)和观察阈值的× 0.7系数,重新eval+package。
提示:示例
demo模型用合成数据训练,阈值会偏高(合成数据太好分)。换成你自己站点的真实日志训练后,这两个值会更贴合实际、通常更分散。
失败安全
模型缺失、加载失败或推理异常时,AI 检测会自动跳过并放行,绝不影响正常业务转发。AI 只增不减——开启它不会让原有规则防护变弱。
常见问题
- 上传提示「特征版本不匹配」:模型用的 SamWafAI 版本与当前 SamWaf 引擎特征版本不一致,请用匹配版本的 SamWafAI 重新训练打包。
- 观察模式没有命中:确认全局
ai_enable=1、站点「AI 智能检测」已开、且模型已加载(AI 模型管理页状态为已就绪)。 - 担心误拦业务:始终先用 observe 跑一段时间,确认误报率后再切 block。
