news 2026/10/14 7:05:07

NGINX Kubernetes Ingress Controller 集成 NGINX App Protect WAF 实战:从部署到验证

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
NGINX Kubernetes Ingress Controller 集成 NGINX App Protect WAF 实战:从部署到验证
  • API网关
  • 云原生
  • 负载均衡
  • 可观测性
  • 微服务

【免费下载链接】kubernetes-ingress

NGINX and NGINX Plus Ingress Controllers for Kubernetes

项目地址:https://gitcode.com/gh_mirrors/ku/kubernetes-ingress
点击查看免费下载

本文基于 kubernetes-ingress 仓库中的 app-protect-waf 示例,完整演示如何用 NGINX Plus Ingress Controller 与 NGINX App Protect(WAF)保护一个运行在 Kubernetes 中的 Web 应用。你将掌握 App Protect 的 Policy、LogConf、User Defined Signature 三类 CRD 的创建方法,学会通过 Ingress 注解启用 WAF 防护、把安全日志转发到 syslog,并用 curl 实际验证拦截效果。

示例概览

本示例部署了以下组件:

  • NGINX Plus Ingress Controller(已启用 NGINX App Protect 模块);
  • Cafe 示例应用:coffee 与 tea 两个 Deployment 及对应 Service,镜像为nginxdemos/hello:plain-text;
  • App Protect 安全资源:一个安全策略(APPolicy)、一个日志配置(APLogConf)和一个用户自定义签名(APUserSig);
  • syslog 服务:用于接收并保存 App Protect 安全日志;
  • Ingress 资源:通过注解把上述策略与日志配置绑定到路由上。

从源码结构看,App Protect 的 CRD 属于appprotect.f5.comAPI 组,包含APPolicy(appolicies)、APLogConf(aplogconfs)、APUserSig(apusersigs)三类资源,其 CRD 定义位于 config/crd/bases/appprotect.f5.com_appolicies.yaml、config/crd/bases/appprotect.f5.com_aplogconfs.yaml 和 config/crd/bases/appprotect.f5.com_apusersigs.yaml。

第一步:部署 Ingress Controller

1. 生成示例所需 Secrets

示例需要使用自签名证书等凭据,仓库根目录的 Makefile 提供了make secrets目标,它会调用 hack/secrets-gen 中的 Go 程序动态生成“just in time”的 TLS 证书与各类示例密钥:

make secrets

执行该命令后,会在示例目录下生成cafe-secret.yaml等文件(包含证书与私钥),供后续创建 TLS Secret 使用。

2. 安装带 App Protect 的 Ingress Controller

按照官方安装说明部署启用了 NGINX App Protect 的 NGINX Plus Ingress Controller。App Protect 功能依赖 NGINX Plus 订阅与对应的 WAF 模块镜像,属于 NGINX Plus 的付费能力,OSS 版 Ingress Controller 不包含该功能。安装完成后,将 Controller 的公网 IP 和 HTTPS 端口保存到 shell 变量:

IC_IP=XXX.YYY.ZZZ.III IC_HTTPS_PORT=<port number>

第二步:部署 Cafe 示例应用

创建 coffee 和 tea 两个 Deployment 及其 Service:

kubectl create -f cafe.yaml

cafe.yaml 的定义如下:coffee 运行 2 个副本、tea 运行 3 个副本,容器监听 80 端口,并分别通过coffee-svc和tea-svc两个 Service 暴露(端口 80)。这是后续验证负载均衡与 WAF 拦截的后端目标。

第三步:配置 WAF 防护

1. 创建 syslog 服务与 Pod

App Protect 会把安全事件写入日志,示例通过 syslog.yaml 部署一个基于balabit/syslog-ng:4.12.0镜像的 syslog 收集端(暴露 514 端口):

kubectl create -f syslog.yaml

Ingress Controller 生成的 Nginx 配置会通过syslog:server=syslog-svc.default:514把安全日志转发到该 Pod,随后我们可以进入 syslog Pod 查看被拦截请求的详细记录。

2. 创建 TLS Secret

kubectl create -f cafe-secret.yaml

该 Secret(tls-secret)由make secrets生成,包含自签名证书与私钥,用于给cafe.example.com提供 HTTPS 访问。

3. 创建 App Protect 策略、日志配置与用户自定义签名

依次创建三类 CRD:

kubectl create -f ap-dataguard-alarm-policy.yaml kubectl create -f ap-logconf.yaml kubectl create -f ap-apple-uds.yaml
APPolicy:安全策略

ap-dataguard-alarm-policy.yaml 基于POLICY_TEMPLATE_NGINX_BASE模板,关键配置项包括:

  • enforcementMode: blocking:策略整体进入“阻断”模式,命中的违规请求直接拒绝;
  • signature-requirements+signature-sets:要求签名集合按Fruits标签筛选,并启用名为apple_sigs的签名集且block: true;
  • blocking-settings.violations:对VIOL_DATA_GUARD违规仅告警(alarm: true、block: false);
  • data-guard:启用数据防泄漏,对信用卡号(creditCardNumbers)与 US 社保号(usSocialSecurityNumbers)进行掩码处理,maskData: true,仅暴露后 4 位。

从实现角度看,Controller 在接收APPolicy后调用 pkg/apis/configuration/validation/appprotect.go 中的ValidateAppProtectPolicy进行校验,要求spec.policy字段必须存在;随后在 internal/k8s/appprotect/app_protect_configuration.go 中通过verifyPolicyAgainstUserSigs检查策略的signature-requirements是否被集群内的用户自定义签名(APUserSig)满足——这正是本示例中策略要求Fruits标签、而 UDS 提供该标签的原因。若存在未满足的签名需求,策略会被标记为无效并从配置中剔除(对应错误信息policy has unsatisfied signature requirements,见 app_protect_configuration.go)。

APLogConf:日志配置

ap-logconf.yaml 定义安全日志的格式与过滤条件:

apiVersion: appprotect.f5.com/v1beta1 kind: APLogConf metadata: name: logconf spec: content: format: default # 使用默认日志格式 max_message_size: 64k max_request_size: any filter: request_type: all # 记录所有请求

Controller 会对该对象调用ValidateAppProtectLogConf(见 appprotect.go),校验spec.content与spec.filter两个必填字段是否存在。

APUserSig:用户自定义签名

ap-apple-uds.yaml 定义了一条自定义攻击签名:

  • 规则content:"apple"; nocase;:在请求内容中匹配字符串apple(不区分大小写);
  • signatureType: request:作用于请求;
  • attackType: Brute Force Attack、risk: medium、accuracy: medium;
  • tag: Fruits:打上Fruits标签,与策略中的signature-requirements对应。

UDS 会被ValidateAppProtectUserSig校验(见 appprotect.go),并且 Controller 会检测同一标签下的重复 UDS:当多个 UDS 拥有相同tag时,只保留创建时间最早的一个,其余被拒绝(错误信息duplicate tag set,逻辑见 app_protect_configuration.go)。

4. 创建 Ingress 资源

kubectl create -f cafe-ingress.yaml

cafe-ingress.yaml 是 WAF 防护的“开关”所在,注意其中的 App Protect 注解:

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: cafe-ingress annotations: appprotect.f5.com/app-protect-policy: "default/dataguard-alarm" appprotect.f5.com/app-protect-enable: "True" appprotect.f5.com/app-protect-security-log-enable: "True" appprotect.f5.com/app-protect-security-log: "default/logconf" appprotect.f5.com/app-protect-security-log-destination: "syslog:server=syslog-svc.default:514" spec: ingressClassName: nginx tls: - hosts: - cafe.example.com secretName: tls-secret rules: - host: cafe.example.com http: paths: - path: /tea pathType: Prefix backend: service: name: tea-svc port: number: 80 - path: /coffee pathType: Prefix backend: service: name: coffee-svc port: number: 80
注解详解
注解值(示例)作用
appprotect.f5.com/app-protect-enableTrue/False是否对该 Ingress 启用 App Protect WAF 防护
appprotect.f5.com/app-protect-policydefault/dataguard-alarm指定绑定的APPolicy,格式为<namespace>/<name>
appprotect.f5.com/app-protect-security-log-enableTrue/False是否启用安全日志
appprotect.f5.com/app-protect-security-logdefault/logconf指定绑定的APLogConf
appprotect.f5.com/app-protect-security-log-destinationsyslog:server=syslog-svc.default:514安全日志的转发目的地

从源码层面印证:这些注解的常量定义位于 internal/configs/annotations.go,并汇总在ingressWAFAnnotations列表中(见 internal/configs/ingress.go)。在 annotations.go 中,Controller 会把app-protect-enable与app-protect-security-log-enable解析为布尔值,并映射为 Nginx 配置中的app_protect_enable(on/off)与app_protect_log_enable参数。

另外,日志目的地有严格的格式校验:ValidateAppProtectLogDestination(见 pkg/apis/configuration/validation/appprotect_common.go)要求目标必须是syslog:server=<IP|localhost|FQDN>:<port>、stderr或绝对文件路径,且拒绝包含危险字符、相对路径或空白字符的写法。

第四步:验证 WAF 拦截效果

1. 正常访问 coffee 与 tea

使用curl的--insecure关闭自签名证书校验,--resolve把cafe.example.com解析到 IC 的 IP:

curl --resolve cafe.example.com:$IC_HTTPS_PORT:$IC_IP https://cafe.example.com:$IC_HTTPS_PORT/coffee --insecure
Server address: 10.12.0.18:80 Server name: coffee-7586895968-r26zn ...
curl --resolve cafe.example.com:$IC_HTTPS_PORT:$IC_IP https://cafe.example.com:$IC_HTTPS_PORT/tea --insecure
Server address: 10.12.0.19:80 Server name: tea-7cd44fcb4d-xfw2x ...

可以看到请求分别被负载均衡到 coffee 与 tea 的后端 Pod,说明正常流量可以顺利通过。

2. 触发攻击签名拦截

发送一个带有<script>标签的可疑 URL:

curl --resolve cafe.example.com:$IC_HTTPS_PORT:$IC_IP "https://cafe.example.com:$IC_HTTPS_PORT/tea/<script>" --insecure
<html><head><title>Request Rejected</title></head><body> ...

请求被 App Protect 内置的注入攻击签名拦截,返回Request Rejected页面。

3. 触发用户自定义签名拦截

用 POST 发送匹配 UDS 规则的apple数据:

curl --resolve cafe.example.com:$IC_HTTPS_PORT:$IC_IP -X POST -d "apple" "https://cafe.example.com:$IC_HTTPS_PORT/tea/" --insecure
<html><head><title>Request Rejected</title></head><body> ...

这条请求命中了我们在ap-apple-uds.yaml中定义的content:"apple"; nocase;规则,同样被 App Protect 拦截。这正是用户自定义签名(UDS)的价值:除了内置签名库,WAF 还能按业务场景定制识别与拦截规则。

4. 查看安全日志

进入 syslog Pod,检查被拦截请求的详细日志:

kubectl exec -it <SYSLOG_POD> -- cat /var/log/messages

日志中会记录被拦截请求的请求行、触发签名、违规类型与策略名称等信息,可用于后续安全分析与告警。

底层原理小结

从仓库源码可以梳理出 App Protect 资源的完整处理链路:

  1. CRD 监听与校验:Controller 监听appprotect.f5.com组的APPolicy、APLogConf、APUserSig资源,通过 pkg/apis/configuration/validation 中的校验函数检查必填字段与非法引用(如被弃用的外部引用字段会打印告警);
  2. UDS 与策略的绑定解析:在 internal/k8s/appprotect/app_protect_configuration.go 中解析策略的signature-requirements(含可选的minRevisionDatetime/maxRevisionDatetime时间约束),再通过verifyPolicyAgainstUserSigs确认集群内存在满足标签与版本要求的 UDS,否则策略不生效并产生Rejected事件;
  3. 注解驱动的配置生成:Ingress 上的appprotect.f5.com/*注解被解析后,连同策略、日志配置一起写入 Nginx 配置,最终由 App Protect 模块(NGINX Plus 内嵌)执行实时拦截与日志转发。

整体架构可以概括为:CRD 定义“防护规则” → Ingress 注解完成“规则绑定” → App Protect 模块执行“实时拦截” → syslog 承载“日志审计”。

延伸阅读

  • 使用 VirtualServer 而不是 Ingress 启用 App Protect:参考 app-protect-waf 自定义资源示例 及 app-protect-waf-v5;
  • App Protect 与 Ingress 结合的更多场景:见 examples/ingress-resources/app-protect-waf-policy 与 app-protect-waf-policy-v5;
  • App Protect 的 DoS 防护能力:参考 examples/custom-resources/app-protect-dos;
  • CRD 的完整字段说明:见 docs/crd/appprotect.f5.com_appolicies.md、docs/crd/appprotect.f5.com_aplogconfs.md 与 docs/crd/appprotect.f5.com_apusersigs.md。
  • API网关
  • 云原生
  • 负载均衡
  • 可观测性
  • 微服务

【免费下载链接】kubernetes-ingress

NGINX and NGINX Plus Ingress Controllers for Kubernetes

项目地址:https://gitcode.com/gh_mirrors/ku/kubernetes-ingress
点击查看免费下载
上一篇:euler-copilot-rag架构设计:如何构建企业级数据管理与检索增强服务
下一篇:大模型参数精度格式全解析:从 FP32、BF16 到 FP8、INT4 与 1-bit 量化

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/14 7:04:59

Django+Celery任务进度可视化:celery-progress实战指南

简介&#xff1a;这是一份专为Django开发者设计的Celery异步任务进度可视化轻量级解决方案&#xff0c;面向中初级Web后端工程师&#xff0c;解决Celery任务执行过程缺乏实时进度反馈的常见痛点。资源包共17个文件&#xff0c;含11个Python核心模块&#xff08;如tasks.py、vie…

作者头像 李华
网站建设 2026/10/14 7:04:56

PS5串流实战:从局域网到远程,解锁任意屏幕玩游戏的完整指南

把PS5的游戏画面从客厅电视搬到卧室平板、办公室笔记本&#xff0c;甚至出差时随身携带的掌机上——这件事我断断续续折腾了大半年。“AnyPS5”这个标题&#xff0c;字面上看像是“任意一台PS5”&#xff0c;但真正落到玩法里&#xff0c;它至少包含两条线&#xff1a;一条是让…

作者头像 李华
网站建设 2026/10/14 7:04:35

无人机航拍目标检测数据集总结:小目标、格式转换与训练实战

搞目标检测的人&#xff0c;一开始都是拿经典目标检测数据集练手&#xff0c;可一旦转到无人机、航拍场景&#xff0c;很多人会直接傻眼&#xff1a;同一套模型&#xff0c;在航拍数据集上的表现往往明显缩水。这不是模型变懒了&#xff0c;而是数据分布完全不同。这篇目标检测…

作者头像 李华
网站建设 2026/10/14 7:03:59

【单片机毕设案例分享】基于4G的老人跌倒检测与生理参数远程监护系统设计 基于物联网的老人跌倒报警4G定位与健康管理系统设计(032604)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于单片机&#xff0c;STM32单片机&#xff0c;51单片机&#xff0c;J…

作者头像 李华
网站建设 2026/10/14 7:03:48

Structured Streaming实战:从Kafka实时数据处理到底层机制

说实话&#xff0c;我第一次用Structured Streaming的时候&#xff0c;也以为它只是把老版Spark Streaming改了个名字&#xff0c;结果真上手之后才发现&#xff0c;这套API背后的设计思路完全换了套玩法。做实时数据处理这几年&#xff0c;从最早的DStream到现在的Structured …

作者头像 李华
网站建设 2026/10/14 7:03:35

前缀和算法详解:从一维到二维,掌握区间求和与差分优化

1. 从一个笔误开始&#xff1a;前缀和到底解决什么问题拿到这个标题的时候我愣了一下&#xff0c;“二位前缀和”明显是“二维前缀和”的笔误。但这个笔误其实挺常见&#xff0c;搜索平台上每天都有不少人带着这个错别字来查资料。既然题目给的是“一维和二位前缀和算法”&…

作者头像 李华