ModSecurity的chain规则通过条件串联实现多上下文联合判断,仅当所有子规则匹配时主规则才触发;如拦截非管理员修改配置需依次匹配URI、POST方法及X-Admin-Flag为0。

ModSecurity 的自定义防护链(chain)不是简单叠加多条规则,而是构建一个**条件串联的逻辑流**,只有所有子规则全部匹配,主规则才触发动作。这对精准拦截绕过常规检测的业务逻辑攻击(比如“重置密码时绕过邮箱校验”“越权访问带签名的订单ID”)非常关键。
明确 chain 的作用与适用场景
普通规则是单点匹配,而 chain 适合需要**多个上下文同时成立**的判断。例如:
- 用户请求
/api/v2/order/status(路径匹配) - 且携带了参数
order_id=ORD-2026-xxxx(参数存在且格式合规) - 但请求头中
X-Auth-Token值不在白名单内(权限校验失败)
这三个条件缺一不可,单独看都正常,合起来就是越权行为——这正是 chain 的用武之地。
写一个可用的 chain 规则(含注释)
以下规则用于拦截“非管理员却尝试修改系统配置接口”的行为:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
SecRule REQUEST_URI "@streq /admin/config/update" \
"id:1005,phase:1,chain,deny,status:403,msg:'Admin-only config update blocked'"<br>SecRule REQUEST_METHOD "@streq POST" "chain"<br>SecRule &REQUEST_HEADERS:X-Admin-Flag "@eq 0" "t:none"
说明:
- 第一行是主规则:匹配 URI,启用
chain模式,并定义拦截动作和返回码 - 第二行是第一个子条件:必须是 POST 方法(
chain关键字表示继续下一级判断) - 第三行是第二个子条件:请求头中
X-Admin-Flag不存在或值为 0(&表示检查变量是否存在,@eq 0判断数值等于 0) -
t:none避免对 header 值做默认转义,确保原始字符串比对准确
配合业务逻辑的关键细节
真实业务中,chain 往往要结合动态数据或外部校验:
- 用
ctl:requestBodyAccess=on确保能读取 POST body,否则无法检查 JSON 字段 - 若需校验签名参数(如
sign=sha256(...)),可调用 Lua 脚本:SecRule ARGS:sign "@inspectFile /etc/modsecurity/check_sign.lua",再在 chain 中引用该结果 - 避免在 chain 中使用耗时操作(如远程 DNS 查询),会拖慢所有请求;高频业务建议预计算并存入
TX变量复用 - 测试时务必开启审计日志:
SecAuditLog /var/log/apache2/modsec_audit.log,查看每条 chain 子规则的匹配结果,确认是哪一环未命中
调试与上线前必须验证的三件事
chain 容易因顺序、变量作用域或隐式转换出错:
- 用
SecRule REQUEST_URI "@streq /test" "id:999,phase:1,log,pass"单独测试路径是否能捕获,排除路由层面拦截 - 在 chain 各子规则末尾加
,logdata:'DEBUG: step X',通过日志确认执行到哪一步中断 - 用
curl -H "X-Admin-Flag: 0" -X POST http://yoursite/admin/config/update模拟真实请求,观察返回状态和日志输出是否符合预期










