NGINX Ingress Controller的ModSecurity拦截规则未生效问题排查
问题分析与修复方案
配置中的核心问题
SecRuleEngine被OWASP CRS覆盖
启用enable-owasp-modsecurity-crs: "true"后,OWASP CRS默认会将SecRuleEngine设置为DetectionOnly(仅检测不拦截)。由于modsecurity-snippet的内容在CRS规则之前加载,CRS的配置会覆盖你设置的SecRuleEngine On,导致规则仅记录攻击但不阻断请求。规则阶段选择错误
你在phase:1(请求头处理阶段)检查ARGS变量,但ARGS是解析后的请求参数,该变量要到phase:2(请求体处理阶段)才会初始化。因此针对ARGS的检查在phase:1完全不会生效。
修复方案
方案一:保留OWASP CRS并确保自定义规则生效
修改ConfigMap,将自定义规则放在CRS之后加载(使用modsecurity-custom-rules),同时调整规则阶段到phase:2:
apiVersion: v1 data: allow-snippet-annotations: "true" enable-modsecurity: "true" enable-owasp-modsecurity-crs: "true" # 全局基础配置,在CRS规则前加载 modsecurity-snippet: |- SecRequestBodyAccess On SecAuditLog /dev/stdout SecAuditLogFormat JSON SecAuditEngine RelevantOnly # 自定义规则在CRS后加载,确保SecRuleEngine不被覆盖 modsecurity-custom-rules: |- SecRuleEngine On # 调整到phase:2,支持检测REQUEST_URI、原始查询串和解析后的参数 SecRule REQUEST_URI|QUERY_STRING|ARGS "@contains attack" "id:100001,phase:2,t:lowercase,deny,status:403,msg:'Attack Detected'" kind: ConfigMap metadata: annotations: meta.helm.sh/release-name: nginx-ingress meta.helm.sh/release-namespace: ingress-basic creationTimestamp: "2023-01-20T11:31:53Z" labels: app.kubernetes.io/component: controller app.kubernetes.io/instance: nginx-ingress app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 1.5.1 helm.sh/chart: ingress-nginx-4.4.2 name: nginx-ingress-ingress-nginx-controller namespace: ingress-basic resourceVersion: "200257665" uid: e6ab9121-9a73-47e3-83ec-6c1fa19072ee
方案二:禁用OWASP CRS(仅使用自定义规则)
如果不需要CRS的默认规则集,直接关闭CRS并调整规则阶段:
apiVersion: v1 data: allow-snippet-annotations: "true" enable-modsecurity: "true" enable-owasp-modsecurity-crs: "false" modsecurity-snippet: |- SecRuleEngine On SecRequestBodyAccess On SecAuditLog /dev/stdout SecAuditLogFormat JSON SecAuditEngine RelevantOnly SecRule REQUEST_URI|QUERY_STRING|ARGS "@contains attack" "id:100001,phase:2,t:lowercase,deny,status:403,msg:'Attack Detected'" kind: ConfigMap metadata: annotations: meta.helm.sh/release-name: nginx-ingress meta.helm.sh/release-namespace: ingress-basic creationTimestamp: "2023-01-20T11:31:53Z" labels: app.kubernetes.io/component: controller app.kubernetes.io/instance: nginx-ingress app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx app.kubernetes.io/version: 1.5.1 helm.sh/chart: ingress-nginx-4.4.2 name: nginx-ingress-ingress-nginx-controller namespace: ingress-basic resourceVersion: "200257665" uid: e6ab9121-9a73-47e3-83ec-6c1fa19072ee
验证步骤
- 更新ConfigMap:
kubectl apply -f <你的ConfigMap文件名>.yaml - 重启Ingress Controller Pod以加载新配置:
kubectl rollout restart deployment nginx-ingress-ingress-nginx-controller -n ingress-basic - 发送测试请求验证拦截效果:
正常情况下会返回curl -v "https://secrule.sample.com/api?task=attack"403 Forbidden。 - 查看控制器日志确认拦截记录:
kubectl logs -l app.kubernetes.io/component=controller -n ingress-basic | grep "Attack Detected"
内容的提问来源于stack exchange,提问作者Paolo Salvatori
相关产品推荐
相关产品推荐

