You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ingress NGINX ModSecurity允许text/plain规则不生效问题排查

问题:Ingress-NGINX + ModSecurity + OWASP CRS,text/plain允许规则不生效

背景

在Ingress-NGINX控制器中通过注解启用ModSecurity,集成OWASP核心规则集(OWASP-Core-Ruleset),其他自定义规则都正常运行,但添加的允许text/plain类型请求的规则始终不生效。试过调整规则空格、执行阶段等写法,都没解决问题。

相关配置

启用ModSecurity的Ingress注解

enable-modsecurity: "true"
modsecurity-snippet: |
  Include /etc/nginx/owasp-modsecurity-crs/nginx-modsecurity.conf

尝试过的自定义规则写法

  1. 初始写法:
SecAction "id:900220, phase:1, pass, t:none, nolog, \
            setvar:'tx.allowed_request_content_type=|application/x-www-form-urlencoded|multipart/form-data|multipart/related|text/xml|application/xml|application/soap+xml|application/json|application/cloudevents+json|application/cloudevents-batch+json|text/plain|'"
  1. 加空格分隔:
SecAction "id:900220, phase:1, pass, t:none, nolog, \
                setvar:'tx.allowed_request_content_type=|application/x-www-form-urlencoded| |multipart/form-data| |multipart/related| |text/xml| |application/xml| |application/soap+xml| |application/json| |application/cloudevents+json| |application/cloudevents-batch+json| |text/plain|'"
  1. 去空格+调阶段:
SecAction "id:900220,phase:1,pass,t:none,nolog,setvar:'tx.allowed_request_content_type=|application/x-www-form-urlencoded|multipart/form-data|multipart/related|text/xml|application/xml|application/soap+xml|application/json|application/cloudevents+json|application/cloudevents-batch+json|text/plain|'"

排查与解决方法

1. 确认规则加载顺序

OWASP CRS的默认配置里大概率已经定义过tx.allowed_request_content_type,如果你的自定义规则加载在CRS规则之前,设置的变量会被CRS覆盖。

检查/etc/nginx/owasp-modsecurity-crs/nginx-modsecurity.conf,看是否先包含了CRS核心规则(比如crs-setup.conf、REQUEST-*规则文件),再加载你的自定义规则。Ingress-NGINX的modsecurity-snippet是追加在ModSecurity配置末尾的,但如果nginx-modsecurity.conf里最后又重置了变量,也会覆盖你的设置。

解决思路:改用追加变量的写法,不要直接覆盖:

SecAction "id:900220, phase:1, pass, t:none, nolog, setvar:'tx.allowed_request_content_type=%{tx.allowed_request_content_type}|text/plain|'"

这样既保留CRS默认允许的类型,又追加了text/plain,避免被覆盖。

2. 开启调试日志看变量实际值

直接查看ModSecurity的调试日志,确认tx.allowed_request_content_type最终有没有包含text/plain:
在modsecurity-snippet里添加日志配置:

SecDebugLog /var/log/nginx/modsec_debug.log
SecDebugLogLevel 9

发送一个text/plain类型的请求,然后搜索日志中的tx.allowed_request_content_type,看实际值是什么。如果没找到|text/plain|,说明规则没生效或者被覆盖了。

3. 检查CRS的拦截规则

OWASP CRS里的REQUEST-920-PROTOCOL-ENFORCEMENT.conf中,规则920420负责检查内容类型是否在允许列表里。注意这个规则会把Content-Type里的参数(比如text/plain; charset=utf-8)截断成text/plain再匹配,所以如果请求带参数,是能匹配的,但如果有其他规则(比如920380)拦截了text/plain,即使允许列表加了也没用。

可以临时禁用920420规则测试:

SecRuleRemoveById 920420

如果请求能正常通过,说明是这个规则的问题,再回头调整允许列表配置。

4. 确认ModSecurity版本兼容性

不同版本的ModSecurity对语法要求可能有差异,比如某些版本对引号、空格的处理更严格。检查Ingress-NGINX使用的ModSecurity版本(可以通过nginx -V或者查看镜像标签),确保规则语法符合对应版本要求。


最可能的原因

  • 自定义规则加载顺序在CRS之前,变量被CRS默认配置覆盖;
  • 直接覆盖了tx.allowed_request_content_type,而不是追加,导致后续被CRS规则重置;
  • 未开启调试日志,无法直观看到变量实际值,难以定位问题。

内容的提问来源于stack exchange,提问作者Daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 21:20:05