排查Ingress Nginx规则拦截请求问题(基于Drupal应用)
问题
我们基于Drupal的应用在接收外部请求时被Ingress规则拦截,Ingress Nginx日志显示access forbidden by rule,被拦截的是访问example.com根路径的GET请求。需要排查是哪条Ingress规则导致的拦截,并获取相关排查或解决建议。
提供的信息
Ingress日志
2022/08/11 10:00:59 [error] 20516#20516: *159406145 access forbidden by rule, client: 2a02:9b0:3d:54a2:40bf:a951:e203:79a5, server: example.com, request: "GET / HTTP/1.1", host: "example.com" {"time": "2022-08-11T10:00:59+00:00", "remote_addr": "-", "x_forward_for": "2a02:9b0:3d:54a2:40bf:a951:e203:79a5, 172.70.156.137, 2a02:9b0:3d:54a2:40bf:a951:e203:79a5", "request_id": "d8d07bd09c84b802af91a60adbf46a73", "remote_user": "-", "bytes_sent": 583, "request_time": 0.000, "status": 403, "vhost": "example.com", "request_proto": "HTTP/1.1", "path": "/", "request_query": "-", "request_length": 647, "duration": 0.000,"method": "GET", "http_referrer": "-", "http_user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6 Mobile/15E148 Safari/604.1", "auth_apikey": "-", "auth_authorization": "-", "auth_X-Api-caps": "-", "auth_uid": "-"}
Ingress配置
apiVersion: v1 items: - apiVersion: extensions/v1beta1 kind: Ingress metadata: annotations: meta.helm.sh/release-name: example-production meta.helm.sh/release-namespace: example nginx.ingress.kubernetes.io/configuration-snippet: | more_clear_headers "Server"; more_set_headers "X-Content-Type-Options: nosniff"; more_set_headers "X-XSS-Protection: 1"; more_set_headers "X-Request-Id: $request_id"; more_set_headers "X-Router-Id: example-portal-anonymous"; more_set_headers "Strict-Transport-Security: max-age=15768000"; more_set_headers "Content-Security-Policy: frame-ancestors 'self'"; nginx.ingress.kubernetes.io/cors-allow-headers: X-Forwarded-For, Authorization nginx.ingress.kubernetes.io/cors-allow-methods: GET, POST, PUT, PATCH, DELETE, OPTIONS nginx.ingress.kubernetes.io/cors-allow-origin: example.com nginx.ingress.kubernetes.io/enable-cors: "true" nginx.ingress.kubernetes.io/enable-modsecurity: "true" nginx.ingress.kubernetes.io/enable-owasp-core-rules: "false" nginx.ingress.kubernetes.io/limit-rpm: "0" nginx.ingress.kubernetes.io/modsecurity-transaction-id: $request_id nginx.ingress.kubernetes.io/proxy-buffer-size: 20k nginx.ingress.kubernetes.io/use-regex: "true" nginx.ingress.kubernetes.io/whitelist-source-range: 0.0.0.0/0 creationTimestamp: "2022-08-10T11:19:21Z" generation: 1 labels: app.kubernetes.io/managed-by: example name: portal-anonymous namespace: example resourceVersion: "523173759" selfLink: /apis/extensions/v1beta1/namespaces/example/ingresses/portal-anonymous uid: 9cdb29b2-a463-4851-b4c4-b5a58be28580 spec: rules: - host: example.com http: paths: - backend: serviceName: portal servicePort: 80 path: / pathType: Prefix status: loadBalancer: {} kind: List metadata: resourceVersion: "" selfLink: ""
分析与解决建议
可能的拦截原因
从配置和日志来看,最可能的触发点是ModSecurity模块:
- 配置中开启了
nginx.ingress.kubernetes.io/enable-modsecurity: "true",但关闭了OWASP核心规则。这意味着存在自定义ModSecurity规则(未在当前Ingress配置中显示),或是默认基础规则触发了拦截。 - 日志中的
access forbidden by rule是ModSecurity拦截请求的典型标识。
已排除其他规则的可能性:
whitelist-source-range设置为0.0.0.0/0,允许所有IPv4地址,且该注解默认不过滤IPv6请求,不会导致拦截。- CORS配置允许GET方法,请求Host与
cors-allow-origin一致,同域请求不会被CORS规则拦截。 - 路径规则
path: /+pathType: Prefix可正常匹配根路径请求,无拦截逻辑。
排查步骤
- 检查ModSecurity规则:查看Ingress Controller的全局或Ingress级别的自定义ModSecurity规则文件,确认是否有规则匹配根路径的GET请求。
- 临时禁用ModSecurity测试:将
nginx.ingress.kubernetes.io/enable-modsecurity改为"false",重新应用Ingress配置后测试根路径请求,若能正常访问即可确认是ModSecurity规则导致拦截。 - 启用ModSecurity详细日志:添加以下注解开启日志,获取具体触发的规则ID:
进入Ingress Controller容器,查看nginx.ingress.kubernetes.io/modsecurity-snippet: | SecRuleEngine On SecAuditLog /var/log/nginx/modsecurity_audit.log SecAuditLogParts ABIJDEFHZ/var/log/nginx/modsecurity_audit.log,找到对应request_id的日志条目即可定位具体规则。
解决建议
- 误触发规则处理:修改对应的ModSecurity规则,添加根路径GET请求的例外,或调整规则匹配逻辑。
- 关闭不必要的ModSecurity:若无需该模块,直接关闭
enable-modsecurity注解。 - IPv6白名单补充:如需限制IPv6访问,在
whitelist-source-range中添加IPv6段,例如0.0.0.0/0, ::/0允许所有IPv4和IPv6地址。
内容的提问来源于stack exchange,提问作者manoj
相关产品推荐
相关产品推荐

