跳转至

编辑自定义限速规则

1. 接口描述

接口请求路径:POST /prod-api/waf/wafv3/limit/rules/modifyLimitRule

modifyLimitRule 同时用于创建与编辑。创建时省略 limitRuleId(或不传 / 为 null),服务端将新增规则并自动排到末尾后返回新规则 ID;编辑时必传已有 limitRuleId。匹配条件、相同特征与运算符见 查询条件参数

与自定义控制规则的主要区别:conditions 为一维数组(全部为与);须配置 characteristics(计数维度,1–10 项);命中动作仅支持 DENY / LOG,且须配置 limitAccesslimitTimeparameters.behaviorbehavior=all 时另需 duration)。

Token 获取方式见 密钥鉴权

2. 输入参数

以下请求参数列表仅列出了接口请求参数和部分公共参数,完整公共参数列表见 公共请求参数

参数名称 必选 类型 描述
wafId Long 所属策略组 ID。示例值:22
ruleMessage String 规则名称,最长 30 字符。示例值:单IP访问限速
status String 启用状态。取值:enable(启用)、disable(关闭)。示例值:enable
rules LimitRule 规则内容
limitRuleId Long 创建时省略或为 null;传入已有 ID 则为编辑。示例值:15
sort Integer 排序权重;新建时由服务端自动排到末尾

3. 输出参数

参数名称 类型 描述
code Integer 状态码。示例值:200
msg String 提示信息。示例值:成功
data Long 保存后的 limitRuleId(新建为新 ID,编辑为原 ID)。示例值:15

4. 示例

示例1 创建限速规则(behavior=all)

输入示例

{
  "ruleMessage": "单IP访问限速",
  "status": "enable",
  "wafId": 22,
  "rules": {
    "characteristics": [
      { "target": "IP_SRC", "name": "IP_SRC" }
    ],
    "conditions": [
      {
        "target": "IP_SRC",
        "operator": "IP_IN_LIST",
        "name": "IP_SRC",
        "values": ["52"]
      }
    ],
    "action": {
      "action": "DENY",
      "limitAccess": 12,
      "limitTime": 10,
      "parameters": {
        "behavior": "all",
        "duration": 10
      }
    }
  }
}

上例含义:源 IP 在数据集合 52 内时参与统计;按 IP 聚合计数;10 秒内超过 12 次触发;触发后在 10 秒内对全部匹配请求执行动作。

代码调用

请将 {登录域名}token 替换为实际值。

curl -X POST 'https://{登录域名}/prod-api/waf/wafv3/limit/rules/modifyLimitRule' \
  -H 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.xxxxxx' \
  -H 'Content-Type: application/json' \
  -d '{
  "ruleMessage": "单IP访问限速",
  "status": "enable",
  "wafId": 22,
  "rules": {
    "characteristics": [
      {"target": "IP_SRC", "name": "IP_SRC"}
    ],
    "conditions": [{
      "target": "IP_SRC",
      "operator": "IP_IN_LIST",
      "name": "IP_SRC",
      "values": ["52"]
    }],
    "action": {
      "action": "DENY",
      "limitAccess": 12,
      "limitTime": 10,
      "parameters": {"behavior": "all", "duration": 10}
    }
  }
}'
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class ModifyLimitRuleTest {

    public static void main(String[] args) throws Exception {
        String url = "https://{登录域名}/prod-api/waf/wafv3/limit/rules/modifyLimitRule";
        String token = "eyJhbGciOiJIUzUxMiJ9.xxxxxx";

        String requestBody = "{"
                + "\"ruleMessage\":\"单IP访问限速\","
                + "\"status\":\"enable\","
                + "\"wafId\":22,"
                + "\"rules\":{"
                + "\"characteristics\":[{\"target\":\"IP_SRC\",\"name\":\"IP_SRC\"}],"
                + "\"conditions\":[{"
                + "\"target\":\"IP_SRC\",\"operator\":\"IP_IN_LIST\","
                + "\"name\":\"IP_SRC\",\"values\":[\"52\"]"
                + "}],"
                + "\"action\":{"
                + "\"action\":\"DENY\",\"limitAccess\":12,\"limitTime\":10,"
                + "\"parameters\":{\"behavior\":\"all\",\"duration\":10}"
                + "}"
                + "}"
                + "}";

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Authorization", "Bearer " + token);
            httpPost.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));

            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                int statusCode = response.getStatusLine().getStatusCode();
                String body = EntityUtils.toString(response.getEntity(), "UTF-8");
                System.out.println("Status Code: " + statusCode);
                System.out.println("Body: " + body);
            }
        }
    }
}
package main

import (
    "bytes"
    "fmt"
    "io"
    "net/http"
)

func main() {
    url := "https://{登录域名}/prod-api/waf/wafv3/limit/rules/modifyLimitRule"
    token := "eyJhbGciOiJIUzUxMiJ9.xxxxxx"

    requestBody := []byte(`{
  "ruleMessage": "单IP访问限速",
  "status": "enable",
  "wafId": 22,
  "rules": {
    "characteristics": [
      {"target": "IP_SRC", "name": "IP_SRC"}
    ],
    "conditions": [{
      "target": "IP_SRC",
      "operator": "IP_IN_LIST",
      "name": "IP_SRC",
      "values": ["52"]
    }],
    "action": {
      "action": "DENY",
      "limitAccess": 12,
      "limitTime": 10,
      "parameters": {"behavior": "all", "duration": 10}
    }
  }
}`)

    req, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(requestBody))
    if err != nil {
        panic(err)
    }
    req.Header.Set("Authorization", "Bearer "+token)
    req.Header.Set("Content-Type", "application/json")

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }
    fmt.Println("Status Code:", resp.StatusCode)
    fmt.Println("Body:", string(body))
}

输出示例

{
  "msg": "成功",
  "code": 200,
  "data": 15
}

示例2 编辑已有规则(behavior=excess)

输入示例

{
  "limitRuleId": 15,
  "ruleMessage": "单IP超限仅拦超出部分",
  "status": "enable",
  "wafId": 22,
  "rules": {
    "characteristics": [
      { "target": "IP_SRC", "name": "IP_SRC" }
    ],
    "conditions": [
      {
        "conditionId": 120000501,
        "target": "IP_SRC",
        "operator": "IP_IN_LIST",
        "name": "IP_SRC",
        "values": ["52"]
      }
    ],
    "action": {
      "action": "DENY",
      "limitAccess": 12,
      "limitTime": 10,
      "parameters": {
        "behavior": "excess"
      }
    }
  }
}

代码调用

请将 {登录域名}token 替换为实际值。

curl -X POST 'https://{登录域名}/prod-api/waf/wafv3/limit/rules/modifyLimitRule' \
  -H 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.xxxxxx' \
  -H 'Content-Type: application/json' \
  -d '{
  "limitRuleId": 15,
  "ruleMessage": "单IP超限仅拦超出部分",
  "status": "enable",
  "wafId": 22,
  "rules": {
    "characteristics": [
      {"target": "IP_SRC", "name": "IP_SRC"}
    ],
    "conditions": [{
      "conditionId": 120000501,
      "target": "IP_SRC",
      "operator": "IP_IN_LIST",
      "name": "IP_SRC",
      "values": ["52"]
    }],
    "action": {
      "action": "DENY",
      "limitAccess": 12,
      "limitTime": 10,
      "parameters": {"behavior": "excess"}
    }
  }
}'
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class ModifyLimitRuleEditTest {

    public static void main(String[] args) throws Exception {
        String url = "https://{登录域名}/prod-api/waf/wafv3/limit/rules/modifyLimitRule";
        String token = "eyJhbGciOiJIUzUxMiJ9.xxxxxx";

        String requestBody = "{"
                + "\"limitRuleId\":15,"
                + "\"ruleMessage\":\"单IP超限仅拦超出部分\","
                + "\"status\":\"enable\","
                + "\"wafId\":22,"
                + "\"rules\":{"
                + "\"characteristics\":[{\"target\":\"IP_SRC\",\"name\":\"IP_SRC\"}],"
                + "\"conditions\":[{"
                + "\"conditionId\":120000501,"
                + "\"target\":\"IP_SRC\",\"operator\":\"IP_IN_LIST\","
                + "\"name\":\"IP_SRC\",\"values\":[\"52\"]"
                + "}],"
                + "\"action\":{"
                + "\"action\":\"DENY\",\"limitAccess\":12,\"limitTime\":10,"
                + "\"parameters\":{\"behavior\":\"excess\"}"
                + "}"
                + "}"
                + "}";

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Authorization", "Bearer " + token);
            httpPost.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));

            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                int statusCode = response.getStatusLine().getStatusCode();
                String body = EntityUtils.toString(response.getEntity(), "UTF-8");
                System.out.println("Status Code: " + statusCode);
                System.out.println("Body: " + body);
            }
        }
    }
}
package main

import (
    "bytes"
    "fmt"
    "io"
    "net/http"
)

func main() {
    url := "https://{登录域名}/prod-api/waf/wafv3/limit/rules/modifyLimitRule"
    token := "eyJhbGciOiJIUzUxMiJ9.xxxxxx"

    requestBody := []byte(`{
  "limitRuleId": 15,
  "ruleMessage": "单IP超限仅拦超出部分",
  "status": "enable",
  "wafId": 22,
  "rules": {
    "characteristics": [
      {"target": "IP_SRC", "name": "IP_SRC"}
    ],
    "conditions": [{
      "conditionId": 120000501,
      "target": "IP_SRC",
      "operator": "IP_IN_LIST",
      "name": "IP_SRC",
      "values": ["52"]
    }],
    "action": {
      "action": "DENY",
      "limitAccess": 12,
      "limitTime": 10,
      "parameters": {"behavior": "excess"}
    }
  }
}`)

    req, err := http.NewRequest(http.MethodPost, url, bytes.NewReader(requestBody))
    if err != nil {
        panic(err)
    }
    req.Header.Set("Authorization", "Bearer "+token)
    req.Header.Set("Content-Type", "application/json")

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }
    fmt.Println("Status Code:", resp.StatusCode)
    fmt.Println("Body:", string(body))
}

输出示例

{
  "msg": "成功",
  "code": 200,
  "data": 15
}

5. 错误码

HTTP 状态码 / 业务提示 描述
200 成功
401 未鉴权或 Token 无效
403 无权限
规则描述不能为空 Controller 校验:ruleMessage 为空
规则名称[ruleName]不能为空 校验注解:ruleMessage 为空
规则名称[ruleMessage]不能超过30位 名称超长
执行动作不能为空 rules.action 为空
无效的wafId 策略组不存在或不属于当前用户
[wafId]不能为空 未传 wafId
规则状态[status]不能为空 未传 status
状态[status]只能为disable或enable status 取值非法
请输入至少一个条件 conditions 为空
请输入至少指定一个相同特征 characteristics 为空
至多只能指定10个特征 特征超过 10 项
访问频次不能为空 未传 limitAccess
时间周期不能为空,并且需大于0 limitTime 非法
执行动作只能为LOG、DENY action 取值非法
执行动作参数列表不能为空 parameters 为空
执行动作参数不能为空 parameters 为空
执行动作参数[behavior]不能为空,且只能为excess、all behavior 为空或非法
执行动作参数[behavior]只能为excess、all behaviorexcess/all
执行动作参数[duration]不能为空,且范围在1-86400 behavior=allduration 非法
无效的target target 非法
无效的target:{0} target 不在枚举中
无效的Operator:{0} operator 非法
值不能为空 条件 values 为空
规则ID不能为空 条件持久化 ID 无效
更新失败,请确认提交信息是否正确 持久化失败
未定义相关数据列表,请先创建相关数据列表后再操作 数据集合 ID 无效
name的格式只能包含字母、数字、下划线、点和减号 name 格式非法
字段{0}的匹配内容只能有一个值 单值运算符传入多个值
字段{0}的匹配内容,暂时不支持 运算符暂不支持
字段{0}的name参数错误 nametarget 不一致
字段{0}的名称不能为空 需自定义字段名时 name 为空
字段{0}的运算符[{1}]是无效的 运算符不适用于该 target
字段{0}的匹配内容不能为空 匹配值为空
字段{0}的匹配内容个数不能大于300 匹配值超过 300 个
字段{0}的匹配内容,请勿输入重复的值 匹配值重复
字段{0}的匹配内容,最大输入长度不能大于1000 单值长度超过 1000
字段{0}的匹配内容,存在无效的国家地区编码 国家/地区编码无效
字段{0}的匹配内容{1}存在无效的值 枚举值无效

6. 数据模型

LimitRule

限速规则的相同特征、匹配条件与限速动作。

参数名称 必选 类型 描述
characteristics [Characteristics] 相同特征(计数维度),1–10 项
conditions [LimitRuleCondition] 匹配条件一维数组,全部为与;至少 1 条
action LimitRuleAction 限速动作

Characteristics

计数维度项。

参数名称 必选 类型 描述
target String 特征编码,与 查询条件参数target 一致。示例值:IP_SRC
name String 子字段名;多数与 target 相同;仅允许 [a-zA-Z0-9_.-]+。示例值:IP_SRC

LimitRuleCondition

单条匹配条件。

参数名称 必选 类型 描述
target String 匹配维度,与 查询条件参数 一致。示例值:IP_SRC
operator String 运算符,如 IP_IN_LISTEQ。示例值:IP_IN_LIST
name String 维度名或子字段名;为空时服务端按 target 填充。示例值:IP_SRC
values Array of String 比较取值;数据集合填 dataListId 字符串。示例值:["52"]
conditionId Long 已有条件的持久化 ID;新建条件可省略

LimitRuleAction

限速命中后执行动作。

参数名称 必选 类型 描述
action String 动作编码。取值:DENY(拦截)、LOG(仅记录不拦截)。示例值:DENY
limitAccess Integer 统计时间窗内允许的最大请求次数。示例值:12
limitTime Integer 统计时间窗长度,单位秒,须大于 0。示例值:10
parameters LimitRuleActionParameters 行为参数

LimitRuleActionParameters

限速行为参数。

参数名称 必选 类型 描述
behavior String 取值:excess(仅对超出 limitAccess 的请求执行动作)、all(达到阈值后在 duration 秒内对全部匹配请求执行动作)。示例值:all
duration Integer 仅当 behavior=all 时必填;持续阻断秒数,范围 186400。示例值:10

说明limitTime 是计数窗口;durationbehavior=all 时的惩罚窗口,二者单位均为秒,含义不同。