- API网关
- 云原生
- 负载均衡
- 可观测性
- 微服务
【免费下载链接】kubernetes-ingress
NGINX and NGINX Plus Ingress Controllers for Kubernetes
本文基于 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.yamlcafe.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.yamlIngress 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.yamlAPPolicy:安全策略
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.yamlcafe-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-enable | True/False | 是否对该 Ingress 启用 App Protect WAF 防护 |
appprotect.f5.com/app-protect-policy | default/dataguard-alarm | 指定绑定的APPolicy,格式为<namespace>/<name> |
appprotect.f5.com/app-protect-security-log-enable | True/False | 是否启用安全日志 |
appprotect.f5.com/app-protect-security-log | default/logconf | 指定绑定的APLogConf |
appprotect.f5.com/app-protect-security-log-destination | syslog: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 --insecureServer 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 --insecureServer 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 资源的完整处理链路:
- CRD 监听与校验:Controller 监听
appprotect.f5.com组的APPolicy、APLogConf、APUserSig资源,通过 pkg/apis/configuration/validation 中的校验函数检查必填字段与非法引用(如被弃用的外部引用字段会打印告警); - UDS 与策略的绑定解析:在 internal/k8s/appprotect/app_protect_configuration.go 中解析策略的
signature-requirements(含可选的minRevisionDatetime/maxRevisionDatetime时间约束),再通过verifyPolicyAgainstUserSigs确认集群内存在满足标签与版本要求的 UDS,否则策略不生效并产生Rejected事件; - 注解驱动的配置生成: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
相关推荐
NGINX Plus Ingress Controller 集成 App Protect WAF v5 实战:从策略 Bundle 部署到 VirtualServer 防护配置
NGINX Plus Ingress Controller 集成 App Protect WAF v5 实战:从策略 Bundle 部署到 VirtualSer
API网关云原生负载均衡可观测性微服务kubernetes-ingress 实战:使用 NGINX Plus 与 NGINX App Protect 为 VirtualServer 配置 WAF 防护
kubernetes ingress 实战:使用 NGINX Plus 与 NGINX App Protect 为 VirtualServer 配置 WAF 防
API网关云原生负载均衡可观测性微服务10分钟快速部署NGINX Ingress Controller到Kubernetes集群
10分钟快速部署NGINX Ingress Controller到Kubernetes集群 想要在Kubernetes集群中高效管理外部流量吗?NGINX In
API网关云原生负载均衡可观测性微服务
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考