跳转到内容

WAF 自动 IP 组规则语法

自动 IP 组用于从请求日志中按单个客户端 IP 聚合指标,再用 Expr 表达式判断是否把该 IP 加入组内名单。自动 IP 组可以被 WAF 规则组的 IP 黑名单或白名单引用;发布配置时,Server 只把 IP 组引用 ID 写入 waf_config.json,IP 组成员由 Agent 独立同步到本地运行时文件。

配置结构

自动 IP 组的配置是一个 JSON 对象:

json
{
  "lookback_minutes": 60,
  "rules": [
    {
      "name": "单 IP 404 高频扫描",
      "expr": "request_count > 100 && StatusRatio(404) >= 0.8"
    }
  ]
}

字段说明:

字段类型作用
lookback_minutesnumber每次执行时回看多少分钟内的请求日志。未填写时默认 60 分钟,最小 5 分钟,最大 43200 分钟。
rulesarray自动规则列表。任意一条规则命中时,该 IP 会进入自动 IP 组名单。
rules[].namestring规则名称,只用于界面展示和错误提示。
rules[].exprstringExpr 表达式,必须返回布尔值。

执行口径

自动规则不是逐条请求判断,而是先按单个客户端 IP 聚合:

  1. Server 读取最近 lookback_minutes 分钟内的请求日志。
  2. remote_addr 归一化后的 IP 分组。
  3. 为每个 IP 计算请求数、404 数、直连 IP Host 次数等指标。
  4. 逐个 IP 执行 rules[].expr
  5. 只要某个 IP 命中任意规则,就写入该自动 IP 组的 IP / IP 段 列表。

Host 是否为“通过 IP 访问”按请求日志中的 Host 字段判断:如果 Host 是 IPv4 或 IPv6 字面量,例如 203.0.113.10[2001:db8::10]203.0.113.10:443,就计入 ip_host_count

可用关键字

表达式中可以直接使用以下字段:

关键字类型作用
ipstring当前正在判断的客户端 IP。
request_countnumber当前 IP 在回看窗口内的总请求数。
status_404_countnumber当前 IP 在回看窗口内返回 404 的请求数。
status_404_rationumber404 请求占比,计算方式为 status_404_count / request_count
ip_host_countnumber当前 IP 通过 IP 地址作为 Host 访问的请求数。
ip_host_rationumber通过 IP 地址访问的占比,计算方式为 ip_host_count / request_count
client_error_countnumber当前 IP 返回 4xx 状态码的请求数。
server_error_countnumber当前 IP 返回 5xx 状态码的请求数。
last_seen_unixnumber当前 IP 在回看窗口内最后一次请求的 Unix 秒级时间戳。

比例字段都是 01 之间的小数。80% 应写成 0.8,50% 应写成 0.5

自定义状态码匹配方法

如果内置的 status_404_countstatus_404_ratio 不能满足您的需求,您可以使用以下内置方法来匹配任意状态码的请求数与占比:

  • StatusCount(code): 获取当前 IP 在回看窗口内返回指定状态码的请求数(如 StatusCount(403) > 10
  • StatusRatio(code): 获取当前 IP 在回看窗口内返回指定状态码的请求数占该 IP 总请求数的比例(如 StatusRatio(502) >= 0.5

Expr 常用写法

自动 IP 组使用 Expr 语法,当前表达式必须返回布尔值。

常用运算符:

写法作用示例
>>=<<=数值比较request_count > 100
==!=相等或不相等ip != "127.0.0.1"
&&并且request_count > 100 && StatusRatio(404) >= 0.8
``
!取反!(ip == "127.0.0.1")
in判断值是否在列表中ip in ["203.0.113.10", "198.51.100.20"]
not in判断值是否不在列表中ip not in ["127.0.0.1"]
()分组控制优先级`(request_count > 100 && StatusRatio(404) >= 0.8)

内置预设

管理端内置两个预设规则,可以直接添加后再按需调整:

json
{
  "name": "单 IP 404 高频扫描",
  "expr": "request_count > 100 && StatusRatio(404) >= 0.8"
}

含义:单个 IP 在回看窗口内请求数大于 100,并且 404 状态码占比不低于 80%。

json
{
  "name": "单 IP 直连访问异常",
  "expr": "ip_host_count > 50 && ip_host_ratio > 0.5"
}

含义:单个 IP 通过 IP 地址作为 Host 访问的次数大于 50,并且这种访问占比大于 50%。

示例

高频 404 扫描:

json
{
  "lookback_minutes": 60,
  "rules": [
    {
      "name": "高频 404 扫描",
      "expr": "request_count > 100 && StatusRatio(404) >= 0.8"
    }
  ]
}

IP 直连访问异常:

json
{
  "lookback_minutes": 30,
  "rules": [
    {
      "name": "IP 直连访问异常",
      "expr": "ip_host_count > 50 && ip_host_ratio > 0.5"
    }
  ]
}

同时捕获高 4xx 与高 5xx:

json
{
  "lookback_minutes": 120,
  "rules": [
    {
      "name": "异常错误率",
      "expr": "(client_error_count > 80 && request_count > 100) || server_error_count > 30"
    }
  ]
}

排除可信 IP:

json
{
  "lookback_minutes": 60,
  "rules": [
    {
      "name": "排除可信 IP 的 404 扫描",
      "expr": "ip not in [\"203.0.113.10\", \"198.51.100.20\"] && request_count > 100 && StatusRatio(404) >= 0.8"
    }
  ]
}

使用建议

先用较短的回看窗口和较高阈值观察命中结果,再逐步调整阈值。管理端 IP 组页面支持在保存前点击 测试规则,直接查看当前回看窗口内命中的 IP;自动 IP 组真正执行后会覆盖该组的 IP 列表。如果要长期保留某些地址,建议放入手动 IP 组,并在 WAF 规则组中同时引用手动组和自动组。

自动 IP 组更新后不需要重新发布配置版本。在线 Agent 会通过 WebSocket 收到变更 IP 组并更新本地 waf_ip_groups.json;WebSocket 不可用时,Agent 会在下一次心跳中上报本地 IP 组 checksum,Server 只返回 checksum 不一致的 IP 组。

基于 Apache License 2.0 发布