ingress-nginx 集成 ModSecurity:为 Kubernetes Ingress 启用 OWASP WAF 防护
【免费下载链接】ingress-nginxIngress NGINX Controller for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/in/ingress-nginx
ModSecurity 是由 OWASP 社区开发的开源跨平台 Web 应用防火墙(WAF)引擎,支持 Apache、IIS 与 Nginx。本指南以 ingress-nginx 官方文档为骨架,结合仓库源码与 Helm Chart 配置,系统讲解如何在 Kubernetes Ingress Controller 中启用 ModSecurity 与 OWASP Core Rule Set(CRS),包括 ConfigMap 全局开关、Ingress 注解级控制、审计日志机制以及通过 Helm Chart 挂载自定义规则插件的完整实战方案。读完本文,你将掌握在 ingress-nginx 中从"仅检测"到"主动拦截"的 WAF 配置全流程。
ModSecurity 在 ingress-nginx 中的角色
ModSecurity 拥有一个健壮的基于事件的编程语言,能够为 Web 应用提供针对一系列攻击的防护能力,同时支持 HTTP 流量监控、日志记录与实时分析。在 ingress-nginx 的架构中,NGINX 本身并不直接理解 ModSecurity 规则,二者之间的连接点是 ModSecurity-nginx 连接器——它是 NGINX 与 libmodsecurity(即 ModSecurity v3 库)之间的桥梁。
从容器镜像的视角看,ModSecurity 的集成是开箱即用的:
- 默认 ModSecurity 配置文件位于容器内
/etc/nginx/modsecurity/modsecurity.conf,该目录下仅此一个文件,内容为官方推荐的默认配置; - 通过挂载 Volume 的方式,可以用自定义配置替换该文件,从而完全掌控 WAF 行为;
- OWASP Core Rule Set 规则集位于
/etc/nginx/owasp-modsecurity-crs目录,对应 coreruleset/coreruleset 仓库。
启用 ModSecurity:全局开关与注解开关
通过 ConfigMap 全局启用
在 ingress-nginx 的 ConfigMap 中设置enable-modsecurity: "true"即可全局开启 ModSecurity 特性。对应的配置项在 internal/ingress/controller/config/config.go 中定义,包括:
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enable-modsecurity | bool | "false" | 为 NGINX 启用 ModSecurity 模块 |
enable-owasp-modsecurity-crs | bool | "false" | 启用 OWASP ModSecurity Core Rule Set(CRS) |
modsecurity-snippet | string | "" | 在 ModSecurity 配置段中添加自定义规则 |
重要前提:全局启用后,ModSecurity 将对所有路径生效,如需对特定路径关闭,必须逐一通过注解显式禁用。
通过 Ingress 注解按 location 控制
除了全局开关,ingress-nginx 还提供了四个与 ModSecurity 相关的注解,可在 Ingress 资源上按 location 粒度精细控制。这些注解在 internal/ingress/annotations/modsecurity/main.go 中被定义:
nginx.ingress.kubernetes.io/enable-modsecurity: "true" nginx.ingress.kubernetes.io/enable-owasp-core-rules: "true" nginx.ingress.kubernetes.io/modsecurity-transaction-id: "$request_id" nginx.ingress.kubernetes.io/modsecurity-snippet: | SecRuleEngine On SecDebugLog /tmp/modsec_debug.log各注解的作用与风险等级(见 main.go):
| 注解 | 类型 | 风险等级 | 作用 |
|---|---|---|---|
enable-modsecurity | bool | Low | 在特定 location 启用 ModSecurity |
enable-owasp-core-rules | bool | Low | 在特定 location 启用 OWASP Core Rule Set |
modsecurity-transaction-id | string(NGINX 变量) | High | 向 ModSecurity 传递 NGINX 变量作为事务 ID,例如$request_id |
modsecurity-snippet | string | Critical | 为 ModSecurity 追加自定义配置片段 |
其中modsecurity-snippet因为允许注入任意 ModSecurity 规则而被标记为 Critical 风险,modsecurity-transaction-id为 High 风险。这些风险等级会与控制器启动参数中配置的注解风险阈值(annotations-risk-level)联动校验,具体逻辑见 main.go 的Validate方法。
模块加载决策:全局与注解的优先级
ingress-nginx 不会无条件加载 ModSecurity 模块,而是通过 shouldLoadModSecurityModule 函数动态判断:先检查 ConfigMap 中的enable-modsecurity是否为 true;若未全局启用,则遍历所有 server 与 location,只要任一 location 通过注解开启了 ModSecurity,就加载模块。
而在每个 location 的具体指令生成逻辑 buildModSecurityForLocation 中,优先级规则清晰可见:
- 若全局未启用且注解也未启用,不输出任何 ModSecurity 指令;
- 若注解显式设置过且为 false(
EnableSet=true, Enable=false),则输出modsecurity off;关闭该 location 的防护——这就是"全局开启、单路径关闭"的实现机制; - 全局开启时,location 无需重复输出
modsecurity on;; - 若 location 配置了
modsecurity-snippet,则以modsecurity_rules '...';形式内联注入规则; - 若配置了
modsecurity-transaction-id,则输出modsecurity_transaction_id "...";; - 未配置 snippet 时输出默认规则文件
modsecurity_rules_file /etc/nginx/modsecurity/modsecurity.conf;; - 当全局 CRS 未开启但该 location 通过注解开启时,额外输出
modsecurity_rules_file /etc/nginx/owasp-modsecurity-crs/nginx-modsecurity.conf;。
注解与全局 CRS 的关系:注解
enable-owasp-core-rules仅在全局enable-owasp-modsecurity-crs未开启时才会生效(见 template.go 的条件判断),避免重复加载规则文件。
上述解析与优先级行为均有单元测试覆盖,参见 internal/ingress/annotations/modsecurity/main_test.go 中 12 组用例对注解取值(true/false/空值/缺失)的逐一验证。
默认安全策略:DetectionOnly 与审计日志
默认仅检测模式
出于"最小化安装后干扰"的考量,默认的 ModSecurity 配置使用仅检测(Detection Only)模式——即只记录威胁而不拦截请求。这意味着即使不修改任何规则,启用后 WAF 也会先"观察"流量,为你评估规则误报率提供依据,之后再通过SecRuleEngine On切换到主动拦截。
审计日志的存储与性能
由于默认配置中SecAuditLogType取值为Concurrent,ModSecurity 的审计日志会被写入/var/log/audit目录下的多个文件中(并发模式按事务切分)。需要注意:SecAuditLogType默认的Serial值会对性能产生负面影响,而Concurrent模式正是为了规避该问题而设。这也是在生产环境中评估审计日志磁盘消耗与 I/O 开销时需要重点关注的配置点。
引入 OWASP Core Rule Set(CRS)
OWASP ModSecurity Core Rule Set 是一套通用的攻击检测规则集,适用于 ModSecurity 及其他兼容的 WAF。它的设计目标是:以尽可能少的误报,保护 Web 应用免受包括 OWASP Top Ten 在内的广泛攻击类型。
在 ingress-nginx 中使用 CRS 的方式有两种:
- 全局开启:ConfigMap 中设置
enable-owasp-modsecurity-crs: "true",规则文件路径为/etc/nginx/owasp-modsecurity-crs/nginx-modsecurity.conf; - 按 location 开启:在 Ingress 注解中设置
nginx.ingress.kubernetes.io/enable-owasp-core-rules: "true"。
关键约束:如果在同一个 location 上同时使用enable-owasp-core-rules与modsecurity-snippet注解,只有modsecurity-snippet会生效。此时若仍想引入 CRS 或推荐的默认配置,必须改用Include语句手动加载,例如:
nginx.ingress.kubernetes.io/modsecurity-snippet: | Include /etc/nginx/owasp-modsecurity-crs/nginx-modsecurity.conf Include /etc/nginx/modsecurity/modsecurity.conf实战:通过 Helm Chart 挂载 ModSecurity 插件
下面以 coreruleset 生态中的 nextcloud-rule-exclusions 插件为例,演示完整的 Helm Chart 集成流程。
第一步:准备插件 ConfigMap
将插件规则(示例为精简片段)放入一个 ConfigMap 中,其 data 键名与 CRS 插件目录约定的文件名对应:
apiVersion: v1 kind: ConfigMap metadata: name: modsecurity-plugins data: empty-after.conf: | # no data empty-before.conf: | # no data empty-config.conf: | # no data nextcloud-rule-exclusions-before.conf: # 完整文件请参考 coreruleset 官方 nextcloud-rule-exclusions-plugin 仓库 # # [ File Manager ] # The web interface uploads files, and interacts with the user. SecRule REQUEST_FILENAME "@contains /remote.php/webdav" \ "id:9508102,\ phase:1,\ pass,\ t:none,\ nolog,\ ver:'nextcloud-rule-exclusions-plugin/1.2.0',\ ctl:ruleRemoveById=920420,\ ctl:ruleRemoveById=920440,\ ctl:ruleRemoveById=941000-942999,\ ctl:ruleRemoveById=951000-951999,\ ctl:ruleRemoveById=953100-953130,\ ctl:ruleRemoveByTag=attack-injection-php"该规则的含义是:对匹配/remote.php/webdav的 Nextcloud WebDAV 请求,按规则 ID 区间与标签批量移除特定攻击检测规则,从而避免对正常文件上传/下载操作的误报。
第二步:在 values.yaml 中启用并挂载
在 Helm Chart 的values.yaml中通过controller.config开启 WAF 并注入规则,同时用extraVolumes/extraVolumeMounts将插件 ConfigMap 挂载到 CRS 插件目录:
controller: config: # Enables Modsecurity enable-modsecurity: "true" # Update ModSecurity config and rules modsecurity-snippet: | # this enables the mod security nextcloud plugin Include /etc/nginx/owasp-modsecurity-crs/plugins/nextcloud-rule-exclusions-before.conf # this enables the default OWASP Core Rule Set Include /etc/nginx/owasp-modsecurity-crs/nginx-modsecurity.conf # Enable prevention mode. Options: DetectionOnly,On,Off (default is DetectionOnly) SecRuleEngine On # Enable scanning of the request body SecRequestBodyAccess On # Enable XML and JSON parsing SecRule REQUEST_HEADERS:Content-Type "(?:text|application(?:/soap\+|/)|application/xml)/" \ "id:200000,phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML" SecRule REQUEST_HEADERS:Content-Type "application/json" \ "id:200001,phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON" # Reject if larger (we could also let it pass with ProcessPartial) SecRequestBodyLimitAction Reject # Send ModSecurity audit logs to the stdout (only for rejected requests) SecAuditLog /dev/stdout # format the logs in JSON SecAuditLogFormat JSON # could be On/Off/RelevantOnly SecAuditEngine RelevantOnly # Add a volume for the plugins directory extraVolumes: - name: plugins configMap: name: modsecurity-plugins # override the /etc/nginx/enable-owasp-modsecurity-crs/plugins with your ConfigMap extraVolumeMounts: - name: plugins mountPath: /etc/nginx/owasp-modsecurity-crs/plugins这段配置中的关键指令含义如下:
Include /etc/nginx/owasp-modsecurity-crs/plugins/nextcloud-rule-exclusions-before.conf:加载挂载进来的 Nextcloud 规则排除插件(-before后缀表示在 CRS 主规则之前执行);Include /etc/nginx/owasp-modsecurity-crs/nginx-modsecurity.conf:加载 OWASP CRS 主规则文件;SecRuleEngine On:从默认的DetectionOnly切换到阻断模式(可选值为DetectionOnly、On、Off);SecRequestBodyAccess On:开启请求体扫描,使 WAF 能检测 POST 请求中的攻击载荷;- 两条
SecRule ... ctl:requestBodyProcessor=规则:根据Content-Type请求头自动选择 XML 或 JSON 解析器,确保结构化请求体被正确解析后再执行规则匹配; SecRequestBodyLimitAction Reject:当请求体超过大小限制时直接拒绝(也可选择ProcessPartial放行部分内容);SecAuditLog /dev/stdout:将审计日志输出到标准输出,方便在 Kubernetes 中通过容器日志收集(仅记录被拒绝的请求);SecAuditLogFormat JSON:审计日志以 JSON 格式输出,便于日志平台解析;SecAuditEngine RelevantOnly:审计引擎仅在相关(如被拦截、发生异常)时记录,可选值包括On/Off/RelevantOnly。
第三步:应用到集群
将上述 ConfigMap 与values.yaml准备好后,即可通过标准的 Helm 流程安装或升级 ingress-nginx:
helm upgrade --install ingress-nginx ingress-nginx/ingress-nginx \ -f values.yaml \ --namespace ingress-nginx部署完成后,Nextcloud 相关流量将先经过 WAF 过滤,由 CRS 进行攻击检测,同时 Nextcloud 特有的 WebDAV 文件操作规则被豁免,避免误伤正常使用。
推荐实践与注意事项
- 先检测后拦截:新接入 ModSecurity 时,保持默认的
SecRuleEngine DetectionOnly运行一段时间,结合审计日志评估误报,再逐步切换为SecRuleEngine On; - 审计日志格式:生产环境建议参考上文方案,将
SecAuditLog指向/dev/stdout并启用SecAuditLogFormat JSON,依托容器运行时与日志采集栈统一汇聚分析; - 请求体解析:对依赖 JSON/XML API 的服务,务必配置对应的
requestBodyProcessor规则,否则基于请求体内容的攻击特征可能无法被检出; - 插件目录挂载:使用
extraVolumeMounts覆盖/etc/nginx/owasp-modsecurity-crs/plugins时,请确认插件文件名与 CRS 插件加载约定一致(-before/-after/-config后缀),避免规则加载顺序错乱; - 风险意识:
modsecurity-snippet属于 Critical 风险注解,可注入任意 ModSecurity 指令,在多团队共享集群中应通过annotations-risk-level等机制限制其使用范围; - 持续演进:CRS 与 ModSecurity 生态更新频繁,建议在升级 ingress-nginx 镜像版本时同步核对 CRS 规则目录与插件兼容性,相关变更可留意仓库的 Changelog.md 与 charts/ingress-nginx/changelog 目录下的版本说明。
延伸阅读
- 注解完整参考:docs/user-guide/nginx-configuration/annotations.md 的 ModSecurity 小节
- ConfigMap 配置项说明:docs/user-guide/nginx-configuration/configmap.md
- 注解风险等级说明:docs/user-guide/nginx-configuration/annotations-risk.md
- ModSecurity 注解解析源码:internal/ingress/annotations/modsecurity/main.go
- 注解解析单元测试:internal/ingress/annotations/modsecurity/main_test.go
- NGINX 模板生成逻辑:internal/ingress/controller/template/template.go
【免费下载链接】ingress-nginxIngress NGINX Controller for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/in/ingress-nginx
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考