From 55e7f1671423d36859d14d5ec8048ff0be57d133 Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Wed, 5 Jun 2024 14:05:59 +0100 Subject: [PATCH 01/34] Add build stages for WAF v5 --- Makefile | 32 +++++++++++++++++ build/Dockerfile | 94 ++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 112 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index 94468a59ab..9319673298 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,7 @@ override DOCKER_BUILD_OPTIONS += --build-arg IC_VERSION=$(VERSION) ## The option ARCH ?= amd64 ## The architecture of the image or binary. For example: amd64, arm64, ppc64le, s390x. Not all architectures are supported for all targets GOOS ?= linux ## The OS of the binary. For example linux, darwin NGINX_AGENT ?= true +WAF_VERSION ?= v5 TELEMETRY_ENDPOINT ?= oss.edge.df.f5.com:443 # Additional flags added here can be accessed in main.go. @@ -141,6 +142,13 @@ alpine-image-plus-fips: build ## Create Docker image for Ingress Controller (Alp alpine-image-nap-plus-fips: build ## Create Docker image for Ingress Controller (Alpine with NGINX Plus, NGINX App Protect WAF and FIPS) $(DOCKER_CMD) $(PLUS_ARGS) --build-arg BUILD_OS=alpine-plus-nap-fips --build-arg NGINX_AGENT=$(NGINX_AGENT) +.PHONY: alpine-image-nap-v5-plus-fips +alpine-image-nap-v5-plus-fips: build ## Create Docker image for Ingress Controller (Alpine with NGINX Plus, NGINX App Protect WAFv5 and FIPS) + $(DOCKER_CMD) $(PLUS_ARGS) \ + --build-arg BUILD_OS=alpine-plus-nap-v5-fips \ + --build-arg NGINX_AGENT=$(NGINX_AGENT) \ + --build-arg WAF_VERSION=$(WAF_VERSION) + .PHONY: debian-image-plus debian-image-plus: build ## Create Docker image for Ingress Controller (Debian with NGINX Plus) $(DOCKER_CMD) $(PLUS_ARGS) --build-arg BUILD_OS=debian-plus @@ -149,6 +157,14 @@ debian-image-plus: build ## Create Docker image for Ingress Controller (Debian w debian-image-nap-plus: build ## Create Docker image for Ingress Controller (Debian with NGINX Plus and NGINX App Protect WAF) $(DOCKER_CMD) $(PLUS_ARGS) --build-arg BUILD_OS=debian-plus-nap --build-arg NAP_MODULES=waf --build-arg NGINX_AGENT=$(NGINX_AGENT) +.PHONY: debian-image-nap-v5-plus +debian-image-nap-v5-plus: build ## Create Docker image for Ingress Controller (Debian with NGINX Plus and NGINX App Protect WAFv5) + $(DOCKER_CMD) $(PLUS_ARGS) \ + --build-arg BUILD_OS=debian-plus-nap-v5 \ + --build-arg NAP_MODULES=waf \ + --build-arg NGINX_AGENT=$(NGINX_AGENT) \ + --build-arg WAF_VERSION=$(WAF_VERSION) + .PHONY: debian-image-dos-plus debian-image-dos-plus: build ## Create Docker image for Ingress Controller (Debian with NGINX Plus and NGINX App Protect DoS) $(DOCKER_CMD) $(PLUS_ARGS) --build-arg BUILD_OS=debian-plus-nap --build-arg NAP_MODULES=dos @@ -169,6 +185,14 @@ ubi-image-plus: build ## Create Docker image for Ingress Controller (UBI with NG ubi-image-nap-plus: build ## Create Docker image for Ingress Controller (UBI with NGINX Plus and NGINX App Protect WAF) $(DOCKER_CMD) $(PLUS_ARGS) --secret id=rhel_license,src=rhel_license --build-arg BUILD_OS=ubi-9-plus-nap --build-arg NAP_MODULES=waf --build-arg NGINX_AGENT=$(NGINX_AGENT) +.PHONY: ubi-image-nap-v5-plus +ubi-image-nap-v5-plus: build ## Create Docker image for Ingress Controller (UBI with NGINX Plus and NGINX App Protect WAFv5) + $(DOCKER_CMD) $(PLUS_ARGS) q--secret id=rhel_license,src=rhel_license \ + --build-arg BUILD_OS=ubi-9-plus-nap-v5 \ + --build-arg NAP_MODULES=waf \ + --build-arg NGINX_AGENT=$(NGINX_AGENT) \ + --build-arg WAF_VERSION=$(WAF_VERSION) + .PHONY: ubi-image-dos-plus ubi-image-dos-plus: build ## Create Docker image for Ingress Controller (UBI with NGINX Plus and NGINX App Protect DoS) $(DOCKER_CMD) $(PLUS_ARGS) --secret id=rhel_license,src=rhel_license --build-arg BUILD_OS=ubi-8-plus-nap --build-arg NAP_MODULES=dos @@ -177,6 +201,14 @@ ubi-image-dos-plus: build ## Create Docker image for Ingress Controller (UBI wit ubi-image-nap-dos-plus: build ## Create Docker image for Ingress Controller (UBI with NGINX Plus, NGINX App Protect WAF and DoS) $(DOCKER_CMD) $(PLUS_ARGS) --secret id=rhel_license,src=rhel_license --build-arg BUILD_OS=ubi-8-plus-nap --build-arg NAP_MODULES=waf,dos --build-arg NGINX_AGENT=$(NGINX_AGENT) +.PHONY: ubi-image-nap-dos-v5-plus +ubi-image-nap-dos-v5-plus: build ## Create Docker image for Ingress Controller (UBI with NGINX Plus, NGINX App Protect WAFv5 and DoS) + $(DOCKER_CMD) $(PLUS_ARGS) --secret id=rhel_license,src=rhel_license \ + --build-arg BUILD_OS=ubi-8-plus-nap-v5 \ + --build-arg NAP_MODULES=waf,dos \ + --build-arg NGINX_AGENT=$(NGINX_AGENT) \ + --build-arg WAF_VERSION=$(WAF_VERSION) + .PHONY: all-images ## Create all the Docker images for Ingress Controller all-images: alpine-image alpine-image-plus alpine-image-plus-fips alpine-image-nap-plus-fips debian-image debian-image-plus debian-image-nap-plus debian-image-dos-plus debian-image-nap-dos-plus ubi-image ubi-image-plus ubi-image-nap-plus ubi-image-dos-plus ubi-image-nap-dos-plus diff --git a/build/Dockerfile b/build/Dockerfile index 26cfa088eb..1ecaf19e53 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -13,7 +13,7 @@ FROM ghcr.io/nginxinc/k8s-common:nginx-opentracing-1.27.0@sha256:d9f6f930b7bfcc0 FROM ghcr.io/nginxinc/k8s-common:nginx-opentracing-1.27.0-alpine@sha256:5dc5c76384a775316c541995b145d4cef86d529934951319fd127f4d4fdb9ef7 as alpine-opentracing-lib FROM ghcr.io/nginxinc/alpine-fips:0.1.0-alpine3.17@sha256:f00b3f266422feaaac7b733b46903bd19eb1cd1caa6991131576f5f767db76f8 as alpine-fips-3.17 FROM ghcr.io/nginxinc/alpine-fips:0.2.0-alpine3.19@sha256:1744ae3a8e795daf771f3f7df33b83160981545abb1f1597338e2769d06aa1cc as alpine-fips-3.19 -FROM redhat/ubi9-minimal@sha256:0d6b09f233745d2fcf892cebcf1c18bbfed497f116bc8357e9db4b724d76c5a9 AS ubi-minimal +FROM redhat/ubi9-minimal@sha256:2636170dc55a0931d013014a72ae26c0c2521d4b61a28354b3e2e5369fa335a3 AS ubi-minimal FROM golang:1.22-alpine@sha256:9bdd5692d39acc3f8d0ea6f81327f87ac6b473dd29a2b6006df362bff48dd1f8 as golang-builder @@ -71,17 +71,21 @@ ADD --link --chown=101:0 https://cs.nginx.com/static/files/nginx-plus-8.repo ngi ADD --link --chown=101:0 https://cs.nginx.com/static/files/plus-9.repo nginx-plus-9.repo ADD --link --chown=101:0 https://cs.nginx.com/static/files/app-protect-8.repo app-protect-8.repo ADD --link --chown=101:0 https://cs.nginx.com/static/files/app-protect-9.repo app-protect-9.repo +ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/main/files/nap-waf-v5-ubi-8.repo app-protect-v5-8.repo +ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/main/files/nap-waf-v5-ubi-9.repo app-protect-v5-9.repo ADD --link --chown=101:0 https://cs.nginx.com/static/files/app-protect-dos-8.repo app-protect-dos-8.repo ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/main/files/plus-debian-11.repo debian-plus-11.sources ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/main/files/plus-debian-12.repo debian-plus-12.sources ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/main/files/nap-waf-debian-11.repo nap-waf-11.sources ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/main/files/nap-dos-debian-11.repo nap-dos-11.sources +ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/main/files/nap-waf-v5-debian-12.repo nap-waf-v5-12.sources ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/main/files/agent-debian-11.repo debian-agent-11.sources RUN --mount=from=busybox:musl,src=/bin/,dst=/bin/ printf "%s\n" "Acquire::https::pkgs.nginx.com::User-Agent k8s-ic-$IC_VERSION${BUILD_OS##debian-plus}-apt;" >> 90pkgs-nginx \ && printf "%s\n" "user_agent=k8s-ic-$IC_VERSION${BUILD_OS##ubi*plus}-dnf" | tee -a nginx-plus-*.repo \ && sed -i -e "s;%VERSION%;${NGINX_PLUS_VERSION};g" *.sources \ - && sed -i -e "y/0/1/" -e "1,8s;/centos;/${NGINX_PLUS_VERSION}/centos;" *.repo \ + && sed -i -e "y/0/1/" app-protect-v5-*.repo \ + && sed -i -e "y/0/1/" -e "1,8s;/centos;/${NGINX_PLUS_VERSION}/centos;" nginx-plus-*.repo app-protect-?.repo app-protect-dos-8.repo \ && echo HTTP_USER_AGENT="k8s-ic-$IC_VERSION${BUILD_OS##alpine-plus}-apk" > user_agent ADD --link --chown=101:0 https://cs.nginx.com/static/files/nginx-agent.repo nginx-agent.repo @@ -106,6 +110,7 @@ RUN --mount=type=bind,from=nginx-files,src=patch-os.sh,target=/usr/local/bin/pat && patch-os.sh USER 101 + ############################################# Base image for Alpine with NGINX Plus ############################################# FROM alpine:3.19@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b as alpine-plus ARG NGINX_PLUS_VERSION @@ -165,6 +170,35 @@ RUN --mount=type=bind,from=alpine-fips-3.17,target=/tmp/fips/ \ ; fi +############################################# Base image for Alpine with NGINX Plus, App Protect WAFv5 and FIPS ############################################# +FROM alpine:3.17@sha256:53cf9478b76f4c8fae126acbdfb79bed6e69e628faff572ebe4a029d3d247d98 as alpine-plus-nap-v5-fips +ARG NGINX_PLUS_VERSION + +RUN --mount=type=bind,from=alpine-fips-3.17,target=/tmp/fips/ \ + --mount=type=secret,id=nginx-repo.crt,dst=/etc/apk/cert.pem,mode=0644 \ + --mount=type=secret,id=nginx-repo.key,dst=/etc/apk/cert.key,mode=0644 \ + --mount=type=bind,from=alpine-opentracing-lib,target=/tmp/ot/ \ + --mount=type=bind,from=nginx-files,src=nginx_signing.rsa.pub,target=/etc/apk/keys/nginx_signing.rsa.pub \ + --mount=type=bind,from=nginx-files,src=agent.sh,target=/usr/local/bin/agent.sh \ + --mount=type=bind,from=nginx-files,src=nap-waf.sh,target=/usr/local/bin/nap-waf.sh \ + printf "%s\n" "https://pkgs.nginx.com/plus/${NGINX_PLUS_VERSION}/alpine/v$(grep -E -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ + && printf "%s\n" "https://pkgs.nginx.com/app-protect-x-plus/alpine/v$(grep -E -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ + && printf "%s\n" "https://pkgs.nginx.com/nginx-agent/alpine/v$(grep -E -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ + && apk add --no-cache libcap-utils libcurl nginx-plus nginx-plus-module-njs nginx-plus-module-opentracing nginx-plus-module-fips-check \ + && if [ -z "${NGINX_AGENT##true}" ]; then apk add --no-cache nginx-agent; fi \ + && mkdir -p /usr/ssl \ + && cp -av /tmp/fips/usr/lib/ossl-modules/fips.so /usr/lib/ossl-modules/fips.so \ + && cp -av /tmp/fips/usr/ssl/fipsmodule.cnf /usr/ssl/fipsmodule.cnf \ + && cp -av /tmp/fips/etc/ssl/openssl.cnf /etc/ssl/openssl.cnf \ + && cp -av /tmp/ot/usr/local/lib/libjaegertracing*so* /tmp/ot/usr/local/lib/libzipkin*so* /tmp/ot/usr/local/lib/libdd*so* /tmp/ot/usr/local/lib/libyaml*so* /usr/local/lib/ \ + && ldconfig /usr/local/lib/ \ + && apk add --no-cache app-protect-module-plus \ + && sed -i -e '/nginx.com/d' /etc/apk/repositories \ + && nap-waf.sh \ + && if [ -z "${NGINX_AGENT##true}" ]; then \ + agent.sh \ + ; fi + ############################################# Base image for Debian with NGINX Plus ############################################# FROM debian:12-slim@sha256:804194b909ef23fb995d9412c9378fb3505fe2427b70f3cc425339e48a828fca AS debian-plus @@ -251,10 +285,6 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode nap-dos.sh \ ; fi -# Uncomment the lines below if you want to install a custom CA certificate -# COPY build/*.crt /usr/local/share/ca-certificates/ -# RUN update-ca-certificates - ############################################# Base image for UBI with NGINX Plus ############################################# FROM ubi-minimal AS ubi-plus @@ -313,6 +343,48 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode agent.sh \ ; fi + +############################################# Base image for UBI with NGINX Plus and App Protect WAFv5 ############################################# +FROM ubi-minimal as ubi-9-plus-nap-v5 +ARG NAP_MODULES + +RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \ + --mount=type=secret,id=nginx-repo.key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \ + --mount=type=secret,id=rhel_license,dst=/tmp/rhel_license,mode=0644 \ + --mount=type=bind,from=nginx-files,src=nginx_signing.key,target=/tmp/nginx_signing.key \ + --mount=type=bind,from=nginx-files,src=nginx-plus-9.repo,target=/etc/yum.repos.d/nginx-plus.repo,rw \ + --mount=type=bind,from=nginx-files,src=nginx-agent.repo,target=/etc/yum.repos.d/nginx-agent.repo,rw \ + --mount=type=bind,from=nginx-files,src=app-protect-v5-9.repo,target=/tmp/app-protect-9.repo \ + --mount=type=bind,from=nginx-files,src=agent.sh,target=/usr/local/bin/agent.sh \ + --mount=type=bind,from=nginx-files,src=nap-waf.sh,target=/usr/local/bin/nap-waf.sh \ + source /tmp/rhel_license \ + && rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm \ + && microdnf --nodocs install -y shadow-utils ca-certificates subscription-manager \ + && groupadd --system --gid 101 nginx \ + && useradd --system --gid nginx --no-create-home --home-dir /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \ + && rpm --import /tmp/nginx_signing.key \ + && microdnf --nodocs install -y nginx-plus nginx-plus-module-njs nginx-plus-module-fips-check \ + && if [ -z "${NGINX_AGENT##true}" ]; then microdnf --nodocs install -y nginx-agent; fi \ + && subscription-manager register --org=${RHEL_ORGANIZATION} --activationkey=${RHEL_ACTIVATION_KEY} || true \ + && subscription-manager attach \ + && if [ -z "${NAP_MODULES##*waf*}" ]; then \ + cp /tmp/app-protect-9.repo /etc/yum.repos.d/app-protect-9.repo; \ + fi \ + && if [ -z "${NAP_MODULES##*waf*}" ]; then \ + cp /tmp/app-protect-9.repo /etc/yum.repos.d/app-protect-9.repo \ + && microdnf --enablerepo=codeready-builder-for-rhel-9-x86_64-rpms --nodocs install -y app-protect-module-plus \ + && rm -f /etc/yum.repos.d/app-protect-9.repo \ + && nap-waf.sh \ + && rm -f /etc/yum.repos.d/app-protect-9.repo; \ + ; fi \ + && subscription-manager unregister \ + && microdnf remove -y shadow-utils subscription-manager \ + && microdnf clean all && rm -rf /var/cache/dnf \ + && if [ -z "${NGINX_AGENT##true}" ]; then \ + agent.sh; \ + fi + + ############################################# Base image for UBI with NGINX Plus and App Protect WAF & DoS ############################################# FROM redhat/ubi8@sha256:2a5d23450fb9b0cb266b4d465b36f1d1bc7c9b5a9b785528215b470b44f04209 as ubi-8-plus-nap ARG NAP_MODULES @@ -368,10 +440,6 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode fi \ && dnf clean all -# Uncomment the lines below if you want to install a custom CA certificate -# COPY build/*.crt /etc/pki/ca-trust/source/anchors/ -# RUN update-ca-trust extract - ############################################# Create common files, permissions and setcap ############################################# FROM ${BUILD_OS} as common @@ -387,10 +455,6 @@ RUN --mount=type=bind,target=/tmp \ patch-os.sh \ && common.sh -# Uncomment the line below if you would like to add the default.pem to the image -# and use it as a certificate and key for the default server -# ADD default.pem /etc/nginx/secrets/default - EXPOSE 80 443 STOPSIGNAL SIGTERM @@ -420,6 +484,7 @@ RUN --mount=type=bind,target=/go/src/github.com/nginxinc/kubernetes-ingress/ --m -o /nginx-ingress github.com/nginxinc/kubernetes-ingress/cmd/nginx-ingress \ && setcap 'cap_net_bind_service=+ep' /nginx-ingress && setcap -v 'cap_net_bind_service=+ep' /nginx-ingress + ############################################# Download delve ############################################# FROM golang-builder AS debug-builder ARG TARGETARCH @@ -560,6 +625,7 @@ COPY --link --chown=101:0 dist/aws*${NAP_MODULES_AWS}_linux_${TARGETARCH}*/nginx USER 0 RUN setcap 'cap_net_bind_service=+ep' /nginx-ingress && setcap -v 'cap_net_bind_service=+ep' /nginx-ingress + ############################################# Create image with nginx-ingress built by GoReleaser for AWS Marketplace ############################################# FROM common AS aws ARG TARGETARCH From 207d4d8b44c2cb35d7094cce67bb725046f531d3 Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Wed, 5 Jun 2024 17:08:34 +0100 Subject: [PATCH 02/34] Add Helm value to enable WAF v5 --- charts/nginx-ingress/templates/_helpers.tpl | 17 +++++++++++ .../templates/controller-deployment.yaml | 30 +++++++++++++++++++ charts/nginx-ingress/values.schema.json | 9 ++++++ charts/nginx-ingress/values.yaml | 2 ++ cmd/nginx-ingress/main.go | 15 ++++++++-- internal/configs/config_params.go | 1 + internal/configs/configmaps.go | 1 + internal/configs/configurator.go | 2 +- internal/configs/version1/config.go | 1 + internal/configs/version1/nginx-plus.tmpl | 4 +++ 10 files changed, 78 insertions(+), 4 deletions(-) diff --git a/charts/nginx-ingress/templates/_helpers.tpl b/charts/nginx-ingress/templates/_helpers.tpl index 497e1f6cdb..02f172eb41 100644 --- a/charts/nginx-ingress/templates/_helpers.tpl +++ b/charts/nginx-ingress/templates/_helpers.tpl @@ -312,6 +312,13 @@ List of volumes for controller. - name: nginx-log emptyDir: {} {{- end }} +{{- if .Values.controller.appprotect.v5 }} +- name: app-protect-bd-config + emptyDir: {} +- name: app-protect-config + emptyDir: {} +- name: app-protect-bundles +{{- end }} {{- if .Values.controller.volumes }} {{ toYaml .Values.controller.volumes }} {{- end }} @@ -360,6 +367,16 @@ volumeMounts: name: nginx-lib - mountPath: /var/log/nginx name: nginx-log +{{- if .Values.controller.appprotect.v5 }} +- name: app-protect-bd-config + mountPath: /opt/app_protect/bd_config +- name: app-protect-config + mountPath: /opt/app_protect/config + # Normally, only the waf-config-mgr should access this dir. + # This is here for testing. +- name: app-protect-bundles + mountPath: /etc/app_protect/bundles +{{- end }} {{- end }} {{- if .Values.controller.volumeMounts }} {{ toYaml .Values.controller.volumeMounts }} diff --git a/charts/nginx-ingress/templates/controller-deployment.yaml b/charts/nginx-ingress/templates/controller-deployment.yaml index c8bc8f833c..bb42321a80 100644 --- a/charts/nginx-ingress/templates/controller-deployment.yaml +++ b/charts/nginx-ingress/templates/controller-deployment.yaml @@ -141,6 +141,36 @@ spec: {{- if .Values.controller.extraContainers }} {{ toYaml .Values.controller.extraContainers | nindent 6 }} {{- end }} + +{{- if .Values.controller.appprotect.v5}} + - name: waf-enforcer + image: private-registry.nginx.com/nap/waf-enforcer:5.2.0 + imagePullPolicy: Always + env: + - name: ENFORCER_PORT + value: "50000" + volumeMounts: + - name: app-protect-bd-config + mountPath: /opt/app_protect/bd_config + - name: waf-config-mgr + image: private-registry.nginx.com/nap/waf-config-mgr:5.2.0 + imagePullPolicy: Always + securityContext: + allowPrivilegeEscalation: false + runAsUser: 101 #nginx + runAsNonRoot: true + capabilities: + drop: + - all + volumeMounts: + - name: app-protect-bd-config + mountPath: /opt/app_protect/bd_config + - name: app-protect-config + mountPath: /opt/app_protect/config + - name: app-protect-bundles + mountPath: /etc/app_protect/bundles +{{- end}} + {{- if or ( eq (include "nginx-ingress.readOnlyRootFilesystem" .) "true" ) .Values.controller.initContainers }} initContainers: {{- end }} diff --git a/charts/nginx-ingress/values.schema.json b/charts/nginx-ingress/values.schema.json index 4d8f0400c7..991c345476 100644 --- a/charts/nginx-ingress/values.schema.json +++ b/charts/nginx-ingress/values.schema.json @@ -119,6 +119,15 @@ true ] }, + "v5": { + "type": "boolean", + "default": false, + "title": "Enables App Protect WAF v5.", + "examples": [ + false, + true + ] + }, "logLevel": { "type": "string", "default": "", diff --git a/charts/nginx-ingress/values.yaml b/charts/nginx-ingress/values.yaml index 3e10e200c7..5c54bdf959 100644 --- a/charts/nginx-ingress/values.yaml +++ b/charts/nginx-ingress/values.yaml @@ -21,6 +21,8 @@ controller: appprotect: ## Enable the App Protect WAF module in the Ingress Controller. enable: false + ## Enables App Protect WAF v5. + v5: true ## Sets log level for App Protect WAF. Allowed values: fatal, error, warn, info, debug, trace # logLevel: fatal diff --git a/cmd/nginx-ingress/main.go b/cmd/nginx-ingress/main.go index db38de9bd5..28129af1f0 100644 --- a/cmd/nginx-ingress/main.go +++ b/cmd/nginx-ingress/main.go @@ -7,6 +7,7 @@ import ( "net/http" "os" "os/signal" + "regexp" "runtime" "strings" "syscall" @@ -80,8 +81,14 @@ func main() { nginxVersion := getNginxVersionInfo(nginxManager) var appProtectVersion string + var appProtectV5 bool if *appProtect { appProtectVersion = getAppProtectVersionInfo() + + r := regexp.MustCompile("^5.*") + if r.MatchString(appProtectVersion) { + appProtectV5 = true + } } var agentVersion string @@ -119,6 +126,7 @@ func main() { EnableSnippets: *enableSnippets, NginxServiceMesh: *spireAgentAddress != "", MainAppProtectLoadModule: *appProtect, + MainAppProtectV5LoadModule: appProtectV5, MainAppProtectDosLoadModule: *appProtectDos, EnableLatencyMetrics: *enableLatencyMetrics, EnableOIDC: *enableOIDC, @@ -137,7 +145,7 @@ func main() { nginxManager.CreateTLSPassthroughHostsConfig(emptyFile) } - process := startChildProcesses(nginxManager) + process := startChildProcesses(nginxManager, appProtectV5) plusClient := createPlusClient(*nginxPlus, useFakeNginxManager, nginxManager) @@ -456,10 +464,11 @@ type childProcesses struct { // newChildProcesses starts the several child processes based on flags set. // AppProtect. AppProtectDos, Agent. -func startChildProcesses(nginxManager nginx.Manager) childProcesses { +func startChildProcesses(nginxManager nginx.Manager, appProtectV5 bool) childProcesses { var aPPluginDone chan error - if *appProtect { + // Do not start AppProtect Plugins when using v5. + if *appProtect && !appProtectV5 { aPPluginDone = make(chan error, 1) nginxManager.AppProtectPluginStart(aPPluginDone, *appProtectLogLevel) } diff --git a/internal/configs/config_params.go b/internal/configs/config_params.go index ce011400bc..d7080e281b 100644 --- a/internal/configs/config_params.go +++ b/internal/configs/config_params.go @@ -145,6 +145,7 @@ type StaticConfigParams struct { NginxServiceMesh bool EnableInternalRoutes bool MainAppProtectLoadModule bool + MainAppProtectV5LoadModule bool MainAppProtectDosLoadModule bool InternalRouteServerName string EnableLatencyMetrics bool diff --git a/internal/configs/configmaps.go b/internal/configs/configmaps.go index fbcd63b68d..5bf00d4437 100644 --- a/internal/configs/configmaps.go +++ b/internal/configs/configmaps.go @@ -565,6 +565,7 @@ func GenerateNginxMainConfig(staticCfgParams *StaticConfigParams, config *Config VariablesHashBucketSize: config.VariablesHashBucketSize, VariablesHashMaxSize: config.VariablesHashMaxSize, AppProtectLoadModule: staticCfgParams.MainAppProtectLoadModule, + AppProtectV5LoadModule: staticCfgParams.MainAppProtectV5LoadModule, AppProtectDosLoadModule: staticCfgParams.MainAppProtectDosLoadModule, AppProtectFailureModeAction: config.MainAppProtectFailureModeAction, AppProtectCompressedRequestsAction: config.MainAppProtectCompressedRequestsAction, diff --git a/internal/configs/configurator.go b/internal/configs/configurator.go index 080f597ceb..eeb7230c38 100644 --- a/internal/configs/configurator.go +++ b/internal/configs/configurator.go @@ -31,7 +31,7 @@ import ( const ( pemFileNameForWildcardTLSSecret = "/etc/nginx/secrets/wildcard" // #nosec G101 - appProtectBundleFolder = "/etc/nginx/waf/bundles/" + appProtectBundleFolder = "/etc/app_protect/bundles/" appProtectPolicyFolder = "/etc/nginx/waf/nac-policies/" appProtectLogConfFolder = "/etc/nginx/waf/nac-logconfs/" appProtectUserSigFolder = "/etc/nginx/waf/nac-usersigs/" diff --git a/internal/configs/version1/config.go b/internal/configs/version1/config.go index c05edceb55..dc066244a9 100644 --- a/internal/configs/version1/config.go +++ b/internal/configs/version1/config.go @@ -245,6 +245,7 @@ type MainConfig struct { WorkerRlimitNofile string WorkerShutdownTimeout string AppProtectLoadModule bool + AppProtectV5LoadModule bool AppProtectFailureModeAction string AppProtectCompressedRequestsAction string AppProtectCookieSeed string diff --git a/internal/configs/version1/nginx-plus.tmpl b/internal/configs/version1/nginx-plus.tmpl index e525a533c6..0a450d574b 100644 --- a/internal/configs/version1/nginx-plus.tmpl +++ b/internal/configs/version1/nginx-plus.tmpl @@ -85,6 +85,10 @@ http { {{- end}} {{- end}} + {{- if .AppProtectV5LoadModule}} + app_protect_enforcer_address 127.0.0.1:50000; + {{- end}} + {{- if .AccessLogOff}} access_log off; {{- else}} From b4785b2aac163711dea8ab352c6ea8b7938f8c73 Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Thu, 6 Jun 2024 09:39:31 +0100 Subject: [PATCH 03/34] Use repo files from main branch --- build/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Dockerfile b/build/Dockerfile index 1ecaf19e53..f66153ddd4 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -78,7 +78,7 @@ ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/m ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/main/files/plus-debian-12.repo debian-plus-12.sources ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/main/files/nap-waf-debian-11.repo nap-waf-11.sources ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/main/files/nap-dos-debian-11.repo nap-dos-11.sources -ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/main/files/nap-waf-v5-debian-12.repo nap-waf-v5-12.sources +ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/main/files/nap-waf-v5-debian-11.repo nap-waf-v5-11.sources ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/main/files/agent-debian-11.repo debian-agent-11.sources RUN --mount=from=busybox:musl,src=/bin/,dst=/bin/ printf "%s\n" "Acquire::https::pkgs.nginx.com::User-Agent k8s-ic-$IC_VERSION${BUILD_OS##debian-plus}-apt;" >> 90pkgs-nginx \ From 7f9f2228e9d27e82810be27cd4ac87e66862e187 Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Thu, 6 Jun 2024 11:51:51 +0100 Subject: [PATCH 04/34] Add emptyDir for bundles volumes --- Makefile | 2 +- charts/nginx-ingress/templates/_helpers.tpl | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9319673298..e6f5c53771 100644 --- a/Makefile +++ b/Makefile @@ -187,7 +187,7 @@ ubi-image-nap-plus: build ## Create Docker image for Ingress Controller (UBI wit .PHONY: ubi-image-nap-v5-plus ubi-image-nap-v5-plus: build ## Create Docker image for Ingress Controller (UBI with NGINX Plus and NGINX App Protect WAFv5) - $(DOCKER_CMD) $(PLUS_ARGS) q--secret id=rhel_license,src=rhel_license \ + $(DOCKER_CMD) $(PLUS_ARGS) --secret id=rhel_license,src=rhel_license \ --build-arg BUILD_OS=ubi-9-plus-nap-v5 \ --build-arg NAP_MODULES=waf \ --build-arg NGINX_AGENT=$(NGINX_AGENT) \ diff --git a/charts/nginx-ingress/templates/_helpers.tpl b/charts/nginx-ingress/templates/_helpers.tpl index 02f172eb41..1055907888 100644 --- a/charts/nginx-ingress/templates/_helpers.tpl +++ b/charts/nginx-ingress/templates/_helpers.tpl @@ -318,6 +318,7 @@ List of volumes for controller. - name: app-protect-config emptyDir: {} - name: app-protect-bundles + emptyDir: {} {{- end }} {{- if .Values.controller.volumes }} {{ toYaml .Values.controller.volumes }} From a889556037e31e178f7100eda950f5849f8d5707 Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Thu, 6 Jun 2024 14:32:09 +0100 Subject: [PATCH 05/34] Fix template helper to add volumes required for WAF v5 --- charts/nginx-ingress/templates/_helpers.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/nginx-ingress/templates/_helpers.tpl b/charts/nginx-ingress/templates/_helpers.tpl index 1055907888..92c4aa6606 100644 --- a/charts/nginx-ingress/templates/_helpers.tpl +++ b/charts/nginx-ingress/templates/_helpers.tpl @@ -368,6 +368,7 @@ volumeMounts: name: nginx-lib - mountPath: /var/log/nginx name: nginx-log +{{- end }} {{- if .Values.controller.appprotect.v5 }} - name: app-protect-bd-config mountPath: /opt/app_protect/bd_config @@ -378,7 +379,6 @@ volumeMounts: - name: app-protect-bundles mountPath: /etc/app_protect/bundles {{- end }} -{{- end }} {{- if .Values.controller.volumeMounts }} {{ toYaml .Values.controller.volumeMounts }} {{- end }} From cb9901121417c514468657d26dd2a60efa9f9889 Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Thu, 6 Jun 2024 14:33:15 +0100 Subject: [PATCH 06/34] Update `help` make command to allow digits --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index e6f5c53771..9df0b44aab 100644 --- a/Makefile +++ b/Makefile @@ -32,8 +32,8 @@ export DOCKER_BUILDKIT = 1 .PHONY: help help: Makefile ## Display this help - @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "; printf "Usage:\n\n make \033[36m\033[0m [VARIABLE=value...]\n\nTargets:\n\n"}; {printf " \033[36m%-30s\033[0m %s\n", $$1, $$2}' - @grep -E '^(override )?[a-zA-Z_-]+ \??\+?= .*? ## .*$$' $< | sort | awk 'BEGIN {FS = " \\??\\+?= .*? ## "; printf "\nVariables:\n\n"}; {gsub(/override /, "", $$1); printf " \033[36m%-30s\033[0m %s\n", $$1, $$2}' + @grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "; printf "Usage:\n\n make \033[36m\033[0m [VARIABLE=value...]\n\nTargets:\n\n"}; {printf " \033[36m%-30s\033[0m %s\n", $$1, $$2}' + @grep -E '^(override )?[a-zA-Z0-9_-]+ \??\+?= .*? ## .*$$' $< | sort | awk 'BEGIN {FS = " \\??\\+?= .*? ## "; printf "\nVariables:\n\n"}; {gsub(/override /, "", $$1); printf " \033[36m%-30s\033[0m %s\n", $$1, $$2}' .PHONY: all all: test lint verify-codegen update-crds debian-image From da4d982c531ec4d5e5211678b0478e896a87ac8b Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Thu, 6 Jun 2024 16:38:19 +0100 Subject: [PATCH 07/34] Add waf-enforcer and waf-config-mgr containers to daemonset template --- .../templates/controller-daemonset.yaml | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/charts/nginx-ingress/templates/controller-daemonset.yaml b/charts/nginx-ingress/templates/controller-daemonset.yaml index 8da65c4683..b8bd8ba63c 100644 --- a/charts/nginx-ingress/templates/controller-daemonset.yaml +++ b/charts/nginx-ingress/templates/controller-daemonset.yaml @@ -134,6 +134,36 @@ spec: {{- if .Values.controller.extraContainers }} {{ toYaml .Values.controller.extraContainers | nindent 6 }} {{- end }} + +{{- if .Values.controller.appprotect.v5}} + - name: waf-enforcer + image: private-registry.nginx.com/nap/waf-enforcer:5.2.0 + imagePullPolicy: Always + env: + - name: ENFORCER_PORT + value: "50000" + volumeMounts: + - name: app-protect-bd-config + mountPath: /opt/app_protect/bd_config + - name: waf-config-mgr + image: private-registry.nginx.com/nap/waf-config-mgr:5.2.0 + imagePullPolicy: Always + securityContext: + allowPrivilegeEscalation: false + runAsUser: 101 #nginx + runAsNonRoot: true + capabilities: + drop: + - all + volumeMounts: + - name: app-protect-bd-config + mountPath: /opt/app_protect/bd_config + - name: app-protect-config + mountPath: /opt/app_protect/config + - name: app-protect-bundles + mountPath: /etc/app_protect/bundles +{{- end}} + {{- if or (eq (include "nginx-ingress.readOnlyRootFilesystem" .) "true" ) .Values.controller.initContainers }} initContainers: {{- end }} From 78f3e8ad18910fcd7a92c22d668b007a575f6fee Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Thu, 6 Jun 2024 16:59:07 +0100 Subject: [PATCH 08/34] Move waf enforcer and config mgr to template helper --- charts/nginx-ingress/templates/_helpers.tpl | 31 +++++++++++++++++++ .../templates/controller-daemonset.yaml | 29 +---------------- .../templates/controller-deployment.yaml | 29 +---------------- 3 files changed, 33 insertions(+), 56 deletions(-) diff --git a/charts/nginx-ingress/templates/_helpers.tpl b/charts/nginx-ingress/templates/_helpers.tpl index 92c4aa6606..d2033df055 100644 --- a/charts/nginx-ingress/templates/_helpers.tpl +++ b/charts/nginx-ingress/templates/_helpers.tpl @@ -396,6 +396,37 @@ volumeMounts: {{- end -}} {{- end -}} +{{- define "nginx-ingress.appprotect.v5" -}} +{{- if .Values.controller.appprotect.v5}} +- name: waf-enforcer + image: private-registry.nginx.com/nap/waf-enforcer:5.2.0 + imagePullPolicy: Always + env: + - name: ENFORCER_PORT + value: "50000" + volumeMounts: + - name: app-protect-bd-config + mountPath: /opt/app_protect/bd_config +- name: waf-config-mgr + image: private-registry.nginx.com/nap/waf-config-mgr:5.2.0 + imagePullPolicy: Always + securityContext: + allowPrivilegeEscalation: false + runAsUser: 101 #nginx + runAsNonRoot: true + capabilities: + drop: + - all + volumeMounts: + - name: app-protect-bd-config + mountPath: /opt/app_protect/bd_config + - name: app-protect-config + mountPath: /opt/app_protect/config + - name: app-protect-bundles + mountPath: /etc/app_protect/bundles +{{- end}} +{{- end -}} + {{- define "nginx-ingress.agentConfiguration" -}} log: level: {{ .Values.nginxAgent.logLevel }} diff --git a/charts/nginx-ingress/templates/controller-daemonset.yaml b/charts/nginx-ingress/templates/controller-daemonset.yaml index b8bd8ba63c..268f127f85 100644 --- a/charts/nginx-ingress/templates/controller-daemonset.yaml +++ b/charts/nginx-ingress/templates/controller-daemonset.yaml @@ -135,34 +135,7 @@ spec: {{ toYaml .Values.controller.extraContainers | nindent 6 }} {{- end }} -{{- if .Values.controller.appprotect.v5}} - - name: waf-enforcer - image: private-registry.nginx.com/nap/waf-enforcer:5.2.0 - imagePullPolicy: Always - env: - - name: ENFORCER_PORT - value: "50000" - volumeMounts: - - name: app-protect-bd-config - mountPath: /opt/app_protect/bd_config - - name: waf-config-mgr - image: private-registry.nginx.com/nap/waf-config-mgr:5.2.0 - imagePullPolicy: Always - securityContext: - allowPrivilegeEscalation: false - runAsUser: 101 #nginx - runAsNonRoot: true - capabilities: - drop: - - all - volumeMounts: - - name: app-protect-bd-config - mountPath: /opt/app_protect/bd_config - - name: app-protect-config - mountPath: /opt/app_protect/config - - name: app-protect-bundles - mountPath: /etc/app_protect/bundles -{{- end}} +{{- include "nginx-ingress.appprotect.v5" . | nindent 6 }} {{- if or (eq (include "nginx-ingress.readOnlyRootFilesystem" .) "true" ) .Values.controller.initContainers }} initContainers: diff --git a/charts/nginx-ingress/templates/controller-deployment.yaml b/charts/nginx-ingress/templates/controller-deployment.yaml index bb42321a80..95bf3bb165 100644 --- a/charts/nginx-ingress/templates/controller-deployment.yaml +++ b/charts/nginx-ingress/templates/controller-deployment.yaml @@ -142,34 +142,7 @@ spec: {{ toYaml .Values.controller.extraContainers | nindent 6 }} {{- end }} -{{- if .Values.controller.appprotect.v5}} - - name: waf-enforcer - image: private-registry.nginx.com/nap/waf-enforcer:5.2.0 - imagePullPolicy: Always - env: - - name: ENFORCER_PORT - value: "50000" - volumeMounts: - - name: app-protect-bd-config - mountPath: /opt/app_protect/bd_config - - name: waf-config-mgr - image: private-registry.nginx.com/nap/waf-config-mgr:5.2.0 - imagePullPolicy: Always - securityContext: - allowPrivilegeEscalation: false - runAsUser: 101 #nginx - runAsNonRoot: true - capabilities: - drop: - - all - volumeMounts: - - name: app-protect-bd-config - mountPath: /opt/app_protect/bd_config - - name: app-protect-config - mountPath: /opt/app_protect/config - - name: app-protect-bundles - mountPath: /etc/app_protect/bundles -{{- end}} +{{- include "nginx-ingress.appprotect.v5" . | nindent 6 }} {{- if or ( eq (include "nginx-ingress.readOnlyRootFilesystem" .) "true" ) .Values.controller.initContainers }} initContainers: From 7ea2f6de2f8a8a9396036f702f2b2a820e87a9b1 Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Fri, 7 Jun 2024 09:48:13 +0100 Subject: [PATCH 09/34] Used `debian-plus` build stage as base for `debian-plus-nap-v5` --- build/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Dockerfile b/build/Dockerfile index f66153ddd4..1ecaf19e53 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -78,7 +78,7 @@ ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/m ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/main/files/plus-debian-12.repo debian-plus-12.sources ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/main/files/nap-waf-debian-11.repo nap-waf-11.sources ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/main/files/nap-dos-debian-11.repo nap-dos-11.sources -ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/main/files/nap-waf-v5-debian-11.repo nap-waf-v5-11.sources +ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/main/files/nap-waf-v5-debian-12.repo nap-waf-v5-12.sources ADD --link --chown=101:0 https://raw.githubusercontent.com/nginxinc/k8s-common/main/files/agent-debian-11.repo debian-agent-11.sources RUN --mount=from=busybox:musl,src=/bin/,dst=/bin/ printf "%s\n" "Acquire::https::pkgs.nginx.com::User-Agent k8s-ic-$IC_VERSION${BUILD_OS##debian-plus}-apt;" >> 90pkgs-nginx \ From 1b8ffe51e30e082b87eeece9b6725740b09ccce9 Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Fri, 7 Jun 2024 15:11:37 +0100 Subject: [PATCH 10/34] Set v5 to false by default --- Makefile | 9 ++++----- charts/nginx-ingress/values.yaml | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 9df0b44aab..486634438d 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,6 @@ override DOCKER_BUILD_OPTIONS += --build-arg IC_VERSION=$(VERSION) ## The option ARCH ?= amd64 ## The architecture of the image or binary. For example: amd64, arm64, ppc64le, s390x. Not all architectures are supported for all targets GOOS ?= linux ## The OS of the binary. For example linux, darwin NGINX_AGENT ?= true -WAF_VERSION ?= v5 TELEMETRY_ENDPOINT ?= oss.edge.df.f5.com:443 # Additional flags added here can be accessed in main.go. @@ -147,7 +146,7 @@ alpine-image-nap-v5-plus-fips: build ## Create Docker image for Ingress Controll $(DOCKER_CMD) $(PLUS_ARGS) \ --build-arg BUILD_OS=alpine-plus-nap-v5-fips \ --build-arg NGINX_AGENT=$(NGINX_AGENT) \ - --build-arg WAF_VERSION=$(WAF_VERSION) + --build-arg WAF_VERSION=v5 .PHONY: debian-image-plus debian-image-plus: build ## Create Docker image for Ingress Controller (Debian with NGINX Plus) @@ -163,7 +162,7 @@ debian-image-nap-v5-plus: build ## Create Docker image for Ingress Controller (D --build-arg BUILD_OS=debian-plus-nap-v5 \ --build-arg NAP_MODULES=waf \ --build-arg NGINX_AGENT=$(NGINX_AGENT) \ - --build-arg WAF_VERSION=$(WAF_VERSION) + --build-arg WAF_VERSION=v5 .PHONY: debian-image-dos-plus debian-image-dos-plus: build ## Create Docker image for Ingress Controller (Debian with NGINX Plus and NGINX App Protect DoS) @@ -191,7 +190,7 @@ ubi-image-nap-v5-plus: build ## Create Docker image for Ingress Controller (UBI --build-arg BUILD_OS=ubi-9-plus-nap-v5 \ --build-arg NAP_MODULES=waf \ --build-arg NGINX_AGENT=$(NGINX_AGENT) \ - --build-arg WAF_VERSION=$(WAF_VERSION) + --build-arg WAF_VERSION=v5 .PHONY: ubi-image-dos-plus ubi-image-dos-plus: build ## Create Docker image for Ingress Controller (UBI with NGINX Plus and NGINX App Protect DoS) @@ -207,7 +206,7 @@ ubi-image-nap-dos-v5-plus: build ## Create Docker image for Ingress Controller ( --build-arg BUILD_OS=ubi-8-plus-nap-v5 \ --build-arg NAP_MODULES=waf,dos \ --build-arg NGINX_AGENT=$(NGINX_AGENT) \ - --build-arg WAF_VERSION=$(WAF_VERSION) + --build-arg WAF_VERSION=v5 .PHONY: all-images ## Create all the Docker images for Ingress Controller all-images: alpine-image alpine-image-plus alpine-image-plus-fips alpine-image-nap-plus-fips debian-image debian-image-plus debian-image-nap-plus debian-image-dos-plus debian-image-nap-dos-plus ubi-image ubi-image-plus ubi-image-nap-plus ubi-image-dos-plus ubi-image-nap-dos-plus diff --git a/charts/nginx-ingress/values.yaml b/charts/nginx-ingress/values.yaml index 5c54bdf959..003a060b30 100644 --- a/charts/nginx-ingress/values.yaml +++ b/charts/nginx-ingress/values.yaml @@ -22,7 +22,7 @@ controller: ## Enable the App Protect WAF module in the Ingress Controller. enable: false ## Enables App Protect WAF v5. - v5: true + v5: false ## Sets log level for App Protect WAF. Allowed values: fatal, error, warn, info, debug, trace # logLevel: fatal From 8240d6957e92248449508acf196d661fd5e458eb Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Fri, 7 Jun 2024 17:36:57 +0100 Subject: [PATCH 11/34] Add v5 build stages to ci and update sed in dockerfile --- .github/workflows/build-plus.yml | 1 + .github/workflows/ci.yml | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/.github/workflows/build-plus.yml b/.github/workflows/build-plus.yml index 384ab7b94e..90179baf08 100644 --- a/.github/workflows/build-plus.yml +++ b/.github/workflows/build-plus.yml @@ -205,6 +205,7 @@ jobs: PREBUILT_BASE_IMG=gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic-base/plus:${{ inputs.base-image-md5 }}-${{ inputs.image }}${{ steps.nap_modules.outputs.name != '' && format('-{0}', steps.nap_modules.outputs.name) || '' }} IC_VERSION=${{ github.ref_type == 'tag' && steps.meta.outputs.version || 'CI' }} ${{ inputs.nap_modules != '' && format('NAP_MODULES={0}', steps.nap_modules.outputs.modules) || '' }} + ${{ contains(inputs.image, 'v5') && 'WAF_VERSION=v5' || '' }} ${{ (contains(inputs.target, 'aws') && inputs.nap_modules != '') && format('NAP_MODULES_AWS={0}', steps.nap_modules.outputs.modules) || '' }} secrets: | "nginx-repo.crt=${{ inputs.nap_modules != '' && secrets.NGINX_AP_CRT || secrets.NGINX_CRT }}" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 39ea0b4627..35be053de8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -739,6 +739,22 @@ jobs: target: goreleaser platforms: "linux/amd64" nap_modules: waf + - image: alpine-plus-nap-v5-fips + target: goreleaser + platforms: "linux/amd64" + nap_modules: waf + - image: debian-plus-nap-v5 + target: goreleaser + platforms: "linux/amd64" + nap_modules: waf + - image: ubi-9-plus-nap-v5 + target: goreleaser + platforms: "linux/amd64" + nap_modules: waf + - image: ubi-8-plus-nap-v5 + target: goreleaser + platforms: "linux/amd64" + nap_modules: waf uses: ./.github/workflows/build-plus.yml with: platforms: ${{ matrix.platforms }} From f1e2738859544c8e6fba97fefeae0e50e77a3ac7 Mon Sep 17 00:00:00 2001 From: shaun-nx Date: Fri, 7 Jun 2024 17:39:45 +0100 Subject: [PATCH 12/34] Update unit tests to use /etc/app_protect/bundles/ --- internal/configs/version2/templates_test.go | 2 +- internal/configs/virtualserver_test.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/configs/version2/templates_test.go b/internal/configs/version2/templates_test.go index 83e75cade0..2dccad22d4 100644 --- a/internal/configs/version2/templates_test.go +++ b/internal/configs/version2/templates_test.go @@ -2705,7 +2705,7 @@ var ( VerifyDepth: 2, }, WAF: &WAF{ - ApBundle: "/etc/nginx/waf/bundles/NginxDefaultPolicy.tgz", + ApBundle: "/etc/app_protect/bundles/NginxDefaultPolicy.tgz", ApSecurityLogEnable: true, ApLogConf: []string{"/etc/nginx/waf/nac-logconfs/default-logconf"}, }, diff --git a/internal/configs/virtualserver_test.go b/internal/configs/virtualserver_test.go index a7f89270db..5f51237136 100644 --- a/internal/configs/virtualserver_test.go +++ b/internal/configs/virtualserver_test.go @@ -6378,7 +6378,7 @@ func TestGeneratePolicies_GeneratesWAFPolicyOnValidApBundle(t *testing.T) { want: policiesCfg{ WAF: &version2.WAF{ Enable: "on", - ApBundle: "/etc/nginx/waf/bundles/testWAFPolicyBundle.tgz", + ApBundle: "/etc/app_protect/bundles/testWAFPolicyBundle.tgz", }, }, }, @@ -6410,9 +6410,9 @@ func TestGeneratePolicies_GeneratesWAFPolicyOnValidApBundle(t *testing.T) { want: policiesCfg{ WAF: &version2.WAF{ Enable: "on", - ApBundle: "/etc/nginx/waf/bundles/testWAFPolicyBundle.tgz", + ApBundle: "/etc/app_protect/bundles/testWAFPolicyBundle.tgz", ApSecurityLogEnable: true, - ApLogConf: []string{"/etc/nginx/waf/bundles/secops_dashboard.tgz syslog:server=localhost:514"}, + ApLogConf: []string{"/etc/app_protect/bundles/secops_dashboard.tgz syslog:server=localhost:514"}, }, }, }, @@ -14663,7 +14663,7 @@ var ( type fakeBundleValidator struct{} func (*fakeBundleValidator) validate(bundle string) (string, error) { - bundle = fmt.Sprintf("/etc/nginx/waf/bundles/%s", bundle) + bundle = fmt.Sprintf("/etc/app_protect/bundles/%s", bundle) if strings.Contains(bundle, "invalid") { return bundle, fmt.Errorf("invalid bundle %s", bundle) } From 24213bc1264a1effe8502e5ceff3bb212c6a3c8e Mon Sep 17 00:00:00 2001 From: Paul Abel Date: Mon, 10 Jun 2024 09:51:36 +0100 Subject: [PATCH 13/34] Tag & Release WAF V5 images --- .github/config/config-plus-gcr-release | 2 + .github/config/config-plus-nginx | 2 + .github/scripts/copy-images.sh | 52 ++++++++++++++++++++++++++ .github/workflows/build-plus.yml | 4 +- 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/.github/config/config-plus-gcr-release b/.github/config/config-plus-gcr-release index 0af0ae550d..90bb4b7bc3 100644 --- a/.github/config/config-plus-gcr-release +++ b/.github/config/config-plus-gcr-release @@ -1,7 +1,9 @@ export TARGET_REGISTRY=gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/release declare -a PLUS_TAG_POSTFIX_LIST=("" "-ubi" "-alpine" "-alpine-fips" "-mktpl" "-alpine-mktpl" "-alpine-mktpl-fips") declare -a NAP_WAF_TAG_POSTFIX_LIST=("" "-ubi" "-mktpl" "-ubi-mktpl" "-alpine-fips") +declare -a NAP_WAFV5_TAG_POSTFIX_LIST=("" "-ubi" "-alpine-fips") declare -a NAP_DOS_TAG_POSTFIX_LIST=("" "-ubi" "-mktpl" "-ubi-mktpl") declare -a NAP_WAF_DOS_TAG_POSTFIX_LIST=("" "-ubi" "-mktpl" "-ubi-mktpl") +declare -a NAP_WAFV5_DOS_TAG_POSTFIX_LIST=("" "-ubi") declare -a ADDITIONAL_TAGS=("latest" "${ADDITIONAL_TAG}") export PUBLISH_OSS=false diff --git a/.github/config/config-plus-nginx b/.github/config/config-plus-nginx index de809c41b8..bb2be4ffc3 100644 --- a/.github/config/config-plus-nginx +++ b/.github/config/config-plus-nginx @@ -2,7 +2,9 @@ export TARGET_REGISTRY=docker-mgmt.nginx.com export TARGET_NAP_WAF_DOS_IMAGE_PREFIX="nginx-ic-nap-dos/nginx-plus-ingress" declare -a PLUS_TAG_POSTFIX_LIST=("" "-ubi" "-alpine" "-alpine-fips") declare -a NAP_WAF_TAG_POSTFIX_LIST=("" "-ubi" "-alpine-fips") +declare -a NAP_WAFV5_TAG_POSTFIX_LIST=("" "-ubi" "-alpine-fips") declare -a NAP_DOS_TAG_POSTFIX_LIST=("" "-ubi") declare -a NAP_WAF_DOS_TAG_POSTFIX_LIST=("" "-ubi") +declare -a NAP_WAFV5_DOS_TAG_POSTFIX_LIST=("" "-ubi") declare -a ADDITIONAL_TAGS=("latest" "${ADDITIONAL_TAG}") export PUBLISH_OSS=false diff --git a/.github/scripts/copy-images.sh b/.github/scripts/copy-images.sh index b63fa618e5..19b21c48c1 100755 --- a/.github/scripts/copy-images.sh +++ b/.github/scripts/copy-images.sh @@ -28,19 +28,25 @@ TARGET_OSS_IMAGE_PREFIX=${TARGET_OSS_IMAGE_PREFIX:-"nginx-ic/nginx-ingress"} SOURCE_PLUS_IMAGE_PREFIX=${SOURCE_PLUS_IMAGE_PREFIX:-"nginx-ic/nginx-plus-ingress"} SOURCE_NAP_WAF_IMAGE_PREFIX=${SOURCE_NAP_WAF_IMAGE_PREFIX:-"nginx-ic-nap/nginx-plus-ingress"} +SOURCE_NAP_WAFV5_IMAGE_PREFIX=${SOURCE_NAP_WAFV5_IMAGE_PREFIX:-"nginx-ic-nap-v5/nginx-plus-ingress"} SOURCE_NAP_DOS_IMAGE_PREFIX=${SOURCE_NAP_DOS_IMAGE_PREFIX:-"nginx-ic-dos/nginx-plus-ingress"} SOURCE_NAP_WAF_DOS_IMAGE_PREFIX=${SOURCE_NAP_WAF_DOS_IMAGE_PREFIX:-"nginx-ic-dos-nap/nginx-plus-ingress"} +SOURCE_NAP_WAFV5_DOS_IMAGE_PREFIX=${SOURCE_NAP_WAFV5_DOS_IMAGE_PREFIX:-"nginx-ic-dos-nap-v5/nginx-plus-ingress"} TARGET_PLUS_IMAGE_PREFIX=${TARGET_PLUS_IMAGE_PREFIX:-"nginx-ic/nginx-plus-ingress"} TARGET_NAP_WAF_IMAGE_PREFIX=${TARGET_NAP_WAF_IMAGE_PREFIX:-"nginx-ic-nap/nginx-plus-ingress"} +TARGET_NAP_WAFV5_IMAGE_PREFIX=${TARGET_NAP_WAFV5_IMAGE_PREFIX:-"nginx-ic-nap/nginx-plus-ingress"} TARGET_NAP_DOS_IMAGE_PREFIX=${TARGET_NAP_DOS_IMAGE_PREFIX:-"nginx-ic-dos/nginx-plus-ingress"} TARGET_NAP_WAF_DOS_IMAGE_PREFIX=${TARGET_NAP_WAF_DOS_IMAGE_PREFIX:-"nginx-ic-dos-nap/nginx-plus-ingress"} +TARGET_NAP_WAFV5_DOS_IMAGE_PREFIX=${TARGET_NAP_WAFV5_DOS_IMAGE_PREFIX:-"nginx-ic-dos-nap-v5/nginx-plus-ingress"} declare -a OSS_TAG_POSTFIX_LIST=("" "-ubi" "-alpine") declare -a PLUS_TAG_POSTFIX_LIST=("" "-ubi" "-alpine" "-alpine-fips") declare -a NAP_WAF_TAG_POSTFIX_LIST=("" "-ubi" "-alpine-fips") +declare -a NAP_WAFV5_TAG_POSTFIX_LIST=() declare -a NAP_DOS_TAG_POSTFIX_LIST=("" "-ubi") declare -a NAP_WAF_DOS_TAG_POSTFIX_LIST=("" "-ubi") +declare -a NAP_WAFV5_DOS_TAG_POSTFIX_LIST=() declare -a ADDITIONAL_TAGS=("latest" "${ADDITIONAL_TAG}") CONFIG_PATH=${CONFIG_PATH:-~/.nic-release/config} @@ -152,6 +158,29 @@ if $PUBLISH_WAF; then done fi done + for postfix in "${NAP_WAFV5_TAG_POSTFIX_LIST[@]}"; do + image=${SOURCE_REGISTRY}/${SOURCE_NAP_WAFV5_IMAGE_PREFIX}:${SOURCE_TAG}${postfix} + echo "Processing image ${image}" + new_tag=${TARGET_REGISTRY}/${TARGET_NAP_WAFV5_IMAGE_PREFIX}:${TARGET_TAG}${postfix} + if $IS_IMMUTABLE && skopeo --override-os linux --override-arch amd64 inspect docker://${new_tag} > /dev/null 2>&1; then + echo " ECR is immutable & tag ${new_tag} already exists, skipping." + else + echo " Pushing image NAP WAFV5 ${new_tag}..." + if ! $DRY_RUN; then + skopeo copy --retry-times 5 ${ARCH_OPTS} ${SOURCE_OPTS} ${TARGET_OPTS} docker://${image} docker://${new_tag} + fi + for tag in "${ADDITIONAL_TAGS[@]}"; do + if [ -z "${tag}" ]; then + continue + fi + additional_tag=${TARGET_REGISTRY}/${TARGET_NAP_WAFV5_IMAGE_PREFIX}:${tag}${postfix} + echo " Pushing image NAP WAFV5 ${additional_tag}..." + if ! $DRY_RUN; then + skopeo copy --retry-times 5 ${ARCH_OPTS} ${SOURCE_OPTS} ${TARGET_OPTS} docker://${image} docker://${additional_tag} + fi + done + fi + done else echo "Skipping Publish Plus WAF flow" fi @@ -208,6 +237,29 @@ if $PUBLISH_WAF_DOS; then done fi done + for postfix in "${NAP_WAFV5_DOS_TAG_POSTFIX_LIST[@]}"; do + image=${SOURCE_REGISTRY}/${SOURCE_NAP_WAFV5_DOS_IMAGE_PREFIX}:${SOURCE_TAG}${postfix} + echo "Processing image ${image}" + new_tag=${TARGET_REGISTRY}/${TARGET_NAP_WAFV5_DOS_IMAGE_PREFIX}:${TARGET_TAG}${postfix} + if $IS_IMMUTABLE && skopeo --override-os linux --override-arch amd64 inspect docker://${new_tag} > /dev/null 2>&1; then + echo " ECR is immutable & tag ${new_tag} already exists, skipping." + else + echo " Pushing image NAP WAFV5/DOS ${new_tag}..." + if ! $DRY_RUN; then + skopeo copy --retry-times 5 ${ARCH_OPTS} ${SOURCE_OPTS} ${TARGET_OPTS} docker://${image} docker://${new_tag} + fi + for tag in "${ADDITIONAL_TAGS[@]}"; do + if [ -z "${tag}" ]; then + continue + fi + additional_tag=${TARGET_REGISTRY}/${TARGET_NAP_WAFV5_DOS_IMAGE_PREFIX}:${tag}${postfix} + echo " Pushing image NAP WAFV5/DOS ${additional_tag}..." + if ! $DRY_RUN; then + skopeo copy --retry-times 5 ${ARCH_OPTS} ${SOURCE_OPTS} ${TARGET_OPTS} docker://${image} docker://${additional_tag} + fi + done + fi + done else echo "Skipping Publish Plus WAF/DOS flow" fi diff --git a/.github/workflows/build-plus.yml b/.github/workflows/build-plus.yml index 90179baf08..4240042153 100644 --- a/.github/workflows/build-plus.yml +++ b/.github/workflows/build-plus.yml @@ -123,8 +123,8 @@ jobs: uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1 with: images: | - name=gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic${{ contains(inputs.nap_modules, 'dos') && '-dos' || '' }}${{ contains(inputs.nap_modules, 'waf') && '-nap' || '' }}/nginx-plus-ingress - name=docker-mgmt.nginx.com/nginx-ic${{ contains(inputs.nap_modules, 'waf') && '-nap' || '' }}${{ contains(inputs.nap_modules, 'dos') && '-dos' || '' }}/nginx-plus-ingress,enable=${{ inputs.publish-nginx-reqistry && ! contains(inputs.target, 'aws') }} + name=gcr.io/f5-gcs-7899-ptg-ingrss-ctlr/dev/nginx-ic${{ contains(inputs.nap_modules, 'dos') && '-dos' || '' }}${{ contains(inputs.nap_modules, 'waf') && '-nap' || '' }}${{ contains(inputs.image, 'v5') && '-v5' || '' }}/nginx-plus-ingress + name=docker-mgmt.nginx.com/nginx-ic${{ contains(inputs.nap_modules, 'waf') && '-nap' || '' }}${{ contains(inputs.image, 'v5') && '-v5' || '' }}${{ contains(inputs.nap_modules, 'dos') && '-dos' || '' }}/nginx-plus-ingress,enable=${{ inputs.publish-nginx-reqistry && ! contains(inputs.target, 'aws') }} name=709825985650.dkr.ecr.us-east-1.amazonaws.com/nginx/nginx-plus-ingress${{ contains(inputs.nap_modules, 'dos') && '-dos' || '' }}${{ contains(inputs.nap_modules, 'waf') && '-nap' || '' }},enable=${{ inputs.publish-aws-market-place && contains(inputs.target, 'aws') }} flavor: | suffix=${{ contains(inputs.image, 'ubi') && '-ubi' || '' }}${{ contains(inputs.image, 'alpine') && '-alpine' || '' }}${{ contains(inputs.target, 'aws') && '-mktpl' || '' }}${{ contains(inputs.image, 'fips') && '-fips' || ''}},onlatest=true From 52e029032ca03105bac5b20cd0dbf1ec51eb4640 Mon Sep 17 00:00:00 2001 From: Eoin O'Shaughnessy Date: Mon, 10 Jun 2024 12:01:54 +0100 Subject: [PATCH 14/34] initial pass of helm values for waf v5 --- charts/nginx-ingress/templates/_helpers.tpl | 53 +++--- charts/nginx-ingress/values.schema.json | 187 ++++++++++++++++++++ charts/nginx-ingress/values.yaml | 53 +++++- 3 files changed, 272 insertions(+), 21 deletions(-) diff --git a/charts/nginx-ingress/templates/_helpers.tpl b/charts/nginx-ingress/templates/_helpers.tpl index d2033df055..1cc9538e27 100644 --- a/charts/nginx-ingress/templates/_helpers.tpl +++ b/charts/nginx-ingress/templates/_helpers.tpl @@ -152,10 +152,27 @@ Expand wildcard TLS name. Expand image name. */}} {{- define "nginx-ingress.image" -}} -{{- if .Values.controller.image.digest -}} -{{- printf "%s@%s" .Values.controller.image.repository .Values.controller.image.digest -}} +{{ include "nginx-ingress.image-digest-or-tag" (dict "image" .Values.controller.image "default" .Chart.AppVersion ) }} +{{- end -}} + +{{- define "nap-enforcer.image" -}} +{{ include "nginx-ingress.image-digest-or-tag" (dict "image" .Values.controller.appprotect.enforcer.image "default" .Chart.AppVersion ) }} +{{- end -}} + +{{- define "nap-config-manager.image" -}} +{{ include "nginx-ingress.image-digest-or-tag" (dict "image" .Values.controller.appprotect.configManager.image "default" .Chart.AppVersion ) }} +{{- end -}} + +{{/* +Accepts an image struct like .Values.controller.image along with a default value to use +if the digest or tag is not set. Can be called like: +include "nginx-ingress.image-digest-or-tag" (dict "image" .Values.controller.image "default" .Chart.AppVersion +*/}} +{{- define "nginx-ingress.image-digest-or-tag" -}} +{{- if .image.digest -}} +{{- printf "%s@%s" .image.repository .image.digest -}} {{- else -}} -{{- printf "%s:%s" .Values.controller.image.repository (include "nginx-ingress.tag" .) -}} +{{- printf "%s:%s" .image.repository (default .default .image.tag) -}} {{- end -}} {{- end -}} @@ -313,12 +330,7 @@ List of volumes for controller. emptyDir: {} {{- end }} {{- if .Values.controller.appprotect.v5 }} -- name: app-protect-bd-config - emptyDir: {} -- name: app-protect-config - emptyDir: {} -- name: app-protect-bundles - emptyDir: {} +{{- toYaml .Values.controller.appprotect.volumes }} {{- end }} {{- if .Values.controller.volumes }} {{ toYaml .Values.controller.volumes }} @@ -399,24 +411,25 @@ volumeMounts: {{- define "nginx-ingress.appprotect.v5" -}} {{- if .Values.controller.appprotect.v5}} - name: waf-enforcer - image: private-registry.nginx.com/nap/waf-enforcer:5.2.0 - imagePullPolicy: Always + image: {{ include "nap-enforcer.image" . }} + imagePullPolicy: "{{ .Values.controller.appprotect.enforcer.image.pullPolicy }}" +{{- if .Values.controller.appprotect.enforcer.securityContext }} + securityContext: +{{ toYaml .Values.controller.appprotect.enforcer.securityContext | nindent 6 }} +{{- end }} env: - name: ENFORCER_PORT - value: "50000" + value: "{{ .Values.controller.appprotect.enforcer.port | default 50000 }}" volumeMounts: - name: app-protect-bd-config mountPath: /opt/app_protect/bd_config - name: waf-config-mgr - image: private-registry.nginx.com/nap/waf-config-mgr:5.2.0 - imagePullPolicy: Always + image: {{ include "nap-config-manager.image" . }} + imagePullPolicy: "{{ .Values.controller.appprotect.configManager.image.pullPolicy }}" +{{- if .Values.controller.appprotect.configManager.securityContext }} securityContext: - allowPrivilegeEscalation: false - runAsUser: 101 #nginx - runAsNonRoot: true - capabilities: - drop: - - all +{{ toYaml .Values.controller.appprotect.configManager.securityContext | nindent 6 }} +{{- end }} volumeMounts: - name: app-protect-bd-config mountPath: /opt/app_protect/bd_config diff --git a/charts/nginx-ingress/values.schema.json b/charts/nginx-ingress/values.schema.json index 991c345476..4106701fba 100644 --- a/charts/nginx-ingress/values.schema.json +++ b/charts/nginx-ingress/values.schema.json @@ -148,6 +148,193 @@ "debug", "trace" ] + }, + "volumes": { + "type": "array", + "default": [ + { + "name": "app-protect-bd-config", + "emptyDir": {} + }, + { + "name": "app-protect-config", + "emptyDir": {} + }, + { + "name": "app-protect-bundles", + "emptyDir": {} + } + ], + "title": "Volumes for App Protect WAF v5", + "items": { + "type": "object", + "$ref": "https://raw.githubusercontent.com/nginxinc/kubernetes-json-schema/master/v1.29.0/_definitions.json#/definitions/io.k8s.api.core.v1.Volume" + } + }, + "enforcer": { + "type": "object", + "properties": { + "port": { + "type": "integer", + "default": 50000, + "title": "Port which the App Protect WAF v5 Enforcer process runs on", + "examples": [ + 50000 + ] + }, + "image": { + "type": "object", + "default": {}, + "title": "The image Schema", + "required": [ + "repository" + ], + "properties": { + "repository": { + "type": "string", + "default": "private-registry.nginx.com/nap/waf-enforcer", + "title": "The repository of the App Protect WAF v5 Enforcer image", + "examples": [ + "private-registry.nginx.com/nap/waf-enforcer" + ] + }, + "tag": { + "type": "string", + "default": "5.2.0", + "title": "The tag of the App Protect WAF v5 Enforcer image", + "examples": [ + "5.2.0" + ] + }, + "digest": { + "type": "string", + "default": "", + "title": "The digest of the App Protect WAF v5 Enforcer image", + "examples": [ + "sha256:2710c264e8eaeb663cee63db37b75a1ac1709f63a130fb091c843a6c3a4dc572" + ] + }, + "pullPolicy": { + "type": "string", + "default": "IfNotPresent", + "title": "The pullPolicy for the App Protect WAF v5 Enforcer image", + "allOf": [ + { + "$ref": "https://raw.githubusercontent.com/nginxinc/kubernetes-json-schema/master/v1.29.0/_definitions.json#/definitions/io.k8s.api.core.v1.Container/properties/imagePullPolicy" + }, + { + "enum": [ + "Always", + "IfNotPresent", + "Never" + ] + } + ], + "examples": [ + "Always", + "IfNotPresent", + "Never" + ] + } + }, + "examples": [ + { + "repository": "private-registry.nginx.com/nap/waf-enforcer", + "tag": "5.2.0", + "pullPolicy": "IfNotPresent" + } + ] + }, + "securityContext": { + "type": "object", + "default": {}, + "title": "The securityContext Schema", + "$ref": "https://raw.githubusercontent.com/nginxinc/kubernetes-json-schema/master/v1.29.0/_definitions.json#/definitions/io.k8s.api.core.v1.SecurityContext" + } + } + }, + "configManager": { + "type": "object", + "properties": { + "image": { + "type": "object", + "default": {}, + "title": "The image Schema", + "required": [ + "repository" + ], + "properties": { + "repository": { + "type": "string", + "default": "private-registry.nginx.com/nap/waf-config-mgr", + "title": "The repository of the App Protect WAF v5 Config Manager image", + "examples": [ + "private-registry.nginx.com/nap/waf-config-mgr" + ] + }, + "tag": { + "type": "string", + "default": "5.2.0", + "title": "The tag of the App Protect WAF v5 Config Manager image", + "examples": [ + "5.2.0" + ] + }, + "digest": { + "type": "string", + "default": "", + "title": "The digest of the App Protect WAF v5 Config Manager image", + "examples": [ + "sha256:2710c264e8eaeb663cee63db37b75a1ac1709f63a130fb091c843a6c3a4dc572" + ] + }, + "pullPolicy": { + "type": "string", + "default": "IfNotPresent", + "title": "The pullPolicy for the App Protect WAF v5 Config Manager image", + "allOf": [ + { + "$ref": "https://raw.githubusercontent.com/nginxinc/kubernetes-json-schema/master/v1.29.0/_definitions.json#/definitions/io.k8s.api.core.v1.Container/properties/imagePullPolicy" + }, + { + "enum": [ + "Always", + "IfNotPresent", + "Never" + ] + } + ], + "examples": [ + "Always", + "IfNotPresent", + "Never" + ] + } + }, + "examples": [ + { + "repository": "private-registry.nginx.com/nap/waf-config-mgr", + "tag": "5.2.0", + "pullPolicy": "IfNotPresent" + } + ] + }, + "securityContext": { + "type": "object", + "default": { + "allowPrivilegeEscalation": false, + "runAsUser": 101, + "runAsNonRoot": true, + "capabilities": { + "drop": [ + "all" + ] + } + }, + "title": "The securityContext Schema", + "$ref": "https://raw.githubusercontent.com/nginxinc/kubernetes-json-schema/master/v1.29.0/_definitions.json#/definitions/io.k8s.api.core.v1.SecurityContext" + } + } } }, "examples": [ diff --git a/charts/nginx-ingress/values.yaml b/charts/nginx-ingress/values.yaml index 003a060b30..a198954a23 100644 --- a/charts/nginx-ingress/values.yaml +++ b/charts/nginx-ingress/values.yaml @@ -26,6 +26,56 @@ controller: ## Sets log level for App Protect WAF. Allowed values: fatal, error, warn, info, debug, trace # logLevel: fatal + # Volumes for App Protect WAF v5 + # Required volumes are: app-protect-bd-config, app-protect-config, and app-protect-bundles + volumes: + - name: app-protect-bd-config + emptyDir: {} + - name: app-protect-config + emptyDir: {} + - name: app-protect-bundles + emptyDir: {} + + ## Configuration for App Protect WAF v5 Enforcer + enforcer: + # Port that the App Protect WAF v5 Enforcer runs on. + port: 50000 + image: + ## The image repository of the App Protect WAF v5 Enforcer. + repository: private-registry.nginx.com/nap/waf-enforcer + + ## The tag of the App Protect WAF v5 Enforcer image. + tag: "5.2.0" + ## The digest of the App Protect WAF v5 Enforcer image. + ## If digest is specified it has precedence over tag and will be used instead + # digest: "sha256:CHANGEME" + + ## The pull policy for the App Protect WAF v5 Enforcer image. + pullPolicy: IfNotPresent + # securityContext: {} + + ## Configuration for App Protect WAF v5 Configuration Manager + configManager: + image: + ## The image repository of the App Protect WAF v5 Configuration Manager. + repository: private-registry.nginx.com/nap/waf-config-mgr + + ## The tag of the App Protect WAF v5 Configuration Manager image. + tag: "5.2.0" + ## The digest of the App Protect WAF v5 Configuration Manager image. + ## If digest is specified it has precedence over tag and will be used instead + # digest: "sha256:CHANGEME" + + ## The pull policy for the App Protect WAF v5 Configuration Manager image. + pullPolicy: IfNotPresent + securityContext: + allowPrivilegeEscalation: false + runAsUser: 101 #nginx + runAsNonRoot: true + capabilities: + drop: + - all + ## Support for App Protect DoS appprotectdos: ## Enable the App Protect DoS module in the Ingress Controller. @@ -175,7 +225,8 @@ controller: type: RuntimeDefault ## The security context for the Ingress Controller containers. - securityContext: {} # Remove curly brackets before adding values + securityContext: + {} # Remove curly brackets before adding values # allowPrivilegeEscalation: true # readOnlyRootFilesystem: true # runAsUser: 101 #nginx From dfaecf4bbabac4141f3270f14b8bc9c1238071e3 Mon Sep 17 00:00:00 2001 From: Paul Abel Date: Mon, 10 Jun 2024 12:21:29 +0100 Subject: [PATCH 15/34] remove wafv5-dos publish steps --- .github/config/config-plus-gcr-release | 1 - .github/config/config-plus-nginx | 1 - .github/scripts/copy-images.sh | 23 ----------------------- 3 files changed, 25 deletions(-) diff --git a/.github/config/config-plus-gcr-release b/.github/config/config-plus-gcr-release index 90bb4b7bc3..0a29939d56 100644 --- a/.github/config/config-plus-gcr-release +++ b/.github/config/config-plus-gcr-release @@ -4,6 +4,5 @@ declare -a NAP_WAF_TAG_POSTFIX_LIST=("" "-ubi" "-mktpl" "-ubi-mktpl" "-alpine-fi declare -a NAP_WAFV5_TAG_POSTFIX_LIST=("" "-ubi" "-alpine-fips") declare -a NAP_DOS_TAG_POSTFIX_LIST=("" "-ubi" "-mktpl" "-ubi-mktpl") declare -a NAP_WAF_DOS_TAG_POSTFIX_LIST=("" "-ubi" "-mktpl" "-ubi-mktpl") -declare -a NAP_WAFV5_DOS_TAG_POSTFIX_LIST=("" "-ubi") declare -a ADDITIONAL_TAGS=("latest" "${ADDITIONAL_TAG}") export PUBLISH_OSS=false diff --git a/.github/config/config-plus-nginx b/.github/config/config-plus-nginx index bb2be4ffc3..969f28b4d1 100644 --- a/.github/config/config-plus-nginx +++ b/.github/config/config-plus-nginx @@ -5,6 +5,5 @@ declare -a NAP_WAF_TAG_POSTFIX_LIST=("" "-ubi" "-alpine-fips") declare -a NAP_WAFV5_TAG_POSTFIX_LIST=("" "-ubi" "-alpine-fips") declare -a NAP_DOS_TAG_POSTFIX_LIST=("" "-ubi") declare -a NAP_WAF_DOS_TAG_POSTFIX_LIST=("" "-ubi") -declare -a NAP_WAFV5_DOS_TAG_POSTFIX_LIST=("" "-ubi") declare -a ADDITIONAL_TAGS=("latest" "${ADDITIONAL_TAG}") export PUBLISH_OSS=false diff --git a/.github/scripts/copy-images.sh b/.github/scripts/copy-images.sh index 19b21c48c1..b729509a8e 100755 --- a/.github/scripts/copy-images.sh +++ b/.github/scripts/copy-images.sh @@ -237,29 +237,6 @@ if $PUBLISH_WAF_DOS; then done fi done - for postfix in "${NAP_WAFV5_DOS_TAG_POSTFIX_LIST[@]}"; do - image=${SOURCE_REGISTRY}/${SOURCE_NAP_WAFV5_DOS_IMAGE_PREFIX}:${SOURCE_TAG}${postfix} - echo "Processing image ${image}" - new_tag=${TARGET_REGISTRY}/${TARGET_NAP_WAFV5_DOS_IMAGE_PREFIX}:${TARGET_TAG}${postfix} - if $IS_IMMUTABLE && skopeo --override-os linux --override-arch amd64 inspect docker://${new_tag} > /dev/null 2>&1; then - echo " ECR is immutable & tag ${new_tag} already exists, skipping." - else - echo " Pushing image NAP WAFV5/DOS ${new_tag}..." - if ! $DRY_RUN; then - skopeo copy --retry-times 5 ${ARCH_OPTS} ${SOURCE_OPTS} ${TARGET_OPTS} docker://${image} docker://${new_tag} - fi - for tag in "${ADDITIONAL_TAGS[@]}"; do - if [ -z "${tag}" ]; then - continue - fi - additional_tag=${TARGET_REGISTRY}/${TARGET_NAP_WAFV5_DOS_IMAGE_PREFIX}:${tag}${postfix} - echo " Pushing image NAP WAFV5/DOS ${additional_tag}..." - if ! $DRY_RUN; then - skopeo copy --retry-times 5 ${ARCH_OPTS} ${SOURCE_OPTS} ${TARGET_OPTS} docker://${image} docker://${additional_tag} - fi - done - fi - done else echo "Skipping Publish Plus WAF/DOS flow" fi From b354c69a9e548e1c0696bff571910081f8009396 Mon Sep 17 00:00:00 2001 From: Paul Abel Date: Mon, 10 Jun 2024 14:41:31 +0100 Subject: [PATCH 16/34] add debian & ubi8 waf v5 targets --- build/Dockerfile | 71 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/build/Dockerfile b/build/Dockerfile index 1ecaf19e53..07070998f4 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -198,7 +198,31 @@ RUN --mount=type=bind,from=alpine-fips-3.17,target=/tmp/fips/ \ && if [ -z "${NGINX_AGENT##true}" ]; then \ agent.sh \ ; fi - + + +############################################# Base image for Debian with NGINX Plus and App Protect WAFv5/DoS ############################################# +FROM debian-plus as debian-plus-nap-v5 +ARG NAP_MODULES + +RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \ + --mount=type=secret,id=nginx-repo.key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \ + --mount=type=bind,from=nginx-files,src=90pkgs-nginx,target=/etc/apt/apt.conf.d/90pkgs-nginx \ + --mount=type=bind,from=nginx-files,src=nap-waf-v5-12.sources,target=/tmp/app-protect.sources \ + --mount=type=bind,from=nginx-files,src=debian-agent-11.sources,target=/etc/apt/sources.list.d/nginx-agent.sources \ + if [ -z "${NAP_MODULES##*waf*}" ]; then \ + cp /tmp/app-protect.sources /etc/apt/sources.list.d/app-protect.sources; \ + fi \ + && apt-get update \ + && if [ -z "${NGINX_AGENT##true}" ]; then apt-get install --no-install-recommends --no-install-suggests -y nginx-agent; fi \ + && if [ -z "${NAP_MODULES##*waf*}" ]; then \ + apt-get install --no-install-recommends --no-install-suggests -y app-protect-module-plus; \ + rm -f /etc/apt/sources.list.d/app-protect.sources; \ + nap-waf.sh; \ + && apt-get purge --auto-remove -y gpg \ + && if [ -z "${NGINX_AGENT##true}" ]; then \ + agent.sh; \ + fi + ############################################# Base image for Debian with NGINX Plus ############################################# FROM debian:12-slim@sha256:804194b909ef23fb995d9412c9378fb3505fe2427b70f3cc425339e48a828fca AS debian-plus @@ -438,6 +462,51 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode rm -f /etc/yum.repos.d/app-protect-dos-8.repo \ && nap-dos.sh; \ fi \ + && if [ -z "${NGINX_AGENT##true}" ]; then \ + agent.sh; \ + fi \ + && dnf clean all + + +############################################# Base image for UBI with NGINX Plus and App Protect WAFv5 ############################################# +FROM redhat/ubi8@sha256:f4292f415f60632a0ff9c0646c4fa859d8b2e1e88a16faa90c6decd1951aea88 as ubi-8-plus-nap-v5 +ARG NAP_MODULES + +RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \ + --mount=type=secret,id=nginx-repo.key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \ + --mount=type=secret,id=rhel_license,dst=/tmp/rhel_license,mode=0644 \ + --mount=type=bind,from=nginx-files,src=nginx_signing.key,target=/tmp/nginx_signing.key \ + --mount=type=bind,from=nginx-files,src=nginx-plus-8.repo,target=/etc/yum.repos.d/nginx-plus.repo,rw \ + --mount=type=bind,from=nginx-files,src=nginx-agent.repo,target=/etc/yum.repos.d/nginx-agent.repo,rw \ + --mount=type=bind,from=nginx-files,src=app-protect-v5-8.repo,target=/tmp/app-protect-8.repo \ + --mount=type=bind,from=nginx-files,src=app-protect-dos-8.repo,target=/tmp/app-protect-dos-8.repo \ + source /tmp/rhel_license \ + && if [ -z "${NAP_MODULES##*waf*}" ]; then \ + cp /tmp/app-protect-8.repo /etc/yum.repos.d/app-protect-8.repo; \ + fi \ + ## the code below is duplicated from the ubi-plus image because NAP DOS doesn't support UBI 9 and minimal versions + && groupadd --system --gid 101 nginx \ + && useradd --system --gid nginx --no-create-home --home-dir /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \ + && rpm --import /tmp/nginx_signing.key \ + && dnf --nodocs install -y nginx-plus nginx-plus-module-njs nginx-plus-module-fips-check \ + && if [ -z "${NGINX_AGENT##true}" ]; then dnf --nodocs install -y nginx-agent; fi \ + ## end of duplicated code + && sed -i 's/\(def in_container():\)/\1\n return False/g' /usr/lib64/python*/*-packages/rhsm/config.py \ + && subscription-manager register --org=${RHEL_ORGANIZATION} --activationkey=${RHEL_ACTIVATION_KEY} || true \ + && subscription-manager attach \ + && dnf config-manager --set-enabled codeready-builder-for-rhel-8-x86_64-rpms \ + && dnf --nodocs install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm \ + && if [ -z "${NAP_MODULES##*waf*}" ]; then \ + dnf --nodocs install -y app-protect-module-plus; \ + fi \ + && subscription-manager unregister \ + && if [ -z "${NAP_MODULES##*waf*}" ]; then \ + rm -f /etc/yum.repos.d/app-protect-8.repo \ + && nap-waf.sh; \ + fi \ + && if [ -z "${NGINX_AGENT##true}" ]; then \ + agent.sh; \ + fi \ && dnf clean all From b19454d41a96290878418acd76c616aa46082ee6 Mon Sep 17 00:00:00 2001 From: Paul Abel Date: Mon, 10 Jun 2024 14:46:24 +0100 Subject: [PATCH 17/34] add WAF_VERSION variable to dockerfile --- build/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/build/Dockerfile b/build/Dockerfile index 07070998f4..90bf127b51 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -6,6 +6,7 @@ ARG DEBIAN_FRONTEND=noninteractive ARG PREBUILT_BASE_IMG=nginx/nginx-ingress:${DOWNLOAD_TAG} ARG NGINX_AGENT=false ARG IMAGE_NAME=nginx/nginx-ingress +ARG WAF_VERSION=v4 ############################################# Base images containing libs for Opentracing and FIPS ############################################# From cc0377dbb96b07ced2011d5c6b3eb274a20492fe Mon Sep 17 00:00:00 2001 From: Eoin O'Shaughnessy Date: Mon, 10 Jun 2024 13:07:28 +0100 Subject: [PATCH 18/34] add enforcer addr config and remove test mount --- charts/nginx-ingress/templates/_helpers.tpl | 7 +++---- charts/nginx-ingress/values.schema.json | 8 ++++++++ charts/nginx-ingress/values.yaml | 4 ++++ cmd/nginx-ingress/flags.go | 11 +++++++---- cmd/nginx-ingress/main.go | 1 + internal/configs/config_params.go | 1 + internal/configs/version1/nginx-plus.tmpl | 2 +- 7 files changed, 25 insertions(+), 9 deletions(-) diff --git a/charts/nginx-ingress/templates/_helpers.tpl b/charts/nginx-ingress/templates/_helpers.tpl index 1cc9538e27..1707eced2a 100644 --- a/charts/nginx-ingress/templates/_helpers.tpl +++ b/charts/nginx-ingress/templates/_helpers.tpl @@ -215,6 +215,9 @@ Build the args for the service binary. {{- if and .Values.controller.appprotect.enable .Values.controller.appprotect.logLevel }} - -app-protect-log-level={{ .Values.controller.appprotect.logLevel }} {{ end }} +{{- if and .Values.controller.appprotect.enable .Values.controller.appprotect.v5 }} +- -app-protect-enforcer-address="{{ .Values.controller.appprotect.enforcer.host | default "127.0.0.1" }}:{{ .Values.controller.appprotect.enforcer.port | default 50000 }}" +{{- end }} - -enable-app-protect-dos={{ .Values.controller.appprotectdos.enable }} {{- if .Values.controller.appprotectdos.enable }} - -app-protect-dos-debug={{ .Values.controller.appprotectdos.debug }} @@ -386,10 +389,6 @@ volumeMounts: mountPath: /opt/app_protect/bd_config - name: app-protect-config mountPath: /opt/app_protect/config - # Normally, only the waf-config-mgr should access this dir. - # This is here for testing. -- name: app-protect-bundles - mountPath: /etc/app_protect/bundles {{- end }} {{- if .Values.controller.volumeMounts }} {{ toYaml .Values.controller.volumeMounts }} diff --git a/charts/nginx-ingress/values.schema.json b/charts/nginx-ingress/values.schema.json index 4106701fba..97c528d0fe 100644 --- a/charts/nginx-ingress/values.schema.json +++ b/charts/nginx-ingress/values.schema.json @@ -174,6 +174,14 @@ "enforcer": { "type": "object", "properties": { + "host": { + "type": "string", + "default": "127.0.0.1", + "title": "Port which the App Protect WAF v5 Enforcer process runs on", + "examples": [ + 50000 + ] + }, "port": { "type": "integer", "default": 50000, diff --git a/charts/nginx-ingress/values.yaml b/charts/nginx-ingress/values.yaml index a198954a23..62a059a540 100644 --- a/charts/nginx-ingress/values.yaml +++ b/charts/nginx-ingress/values.yaml @@ -38,6 +38,10 @@ controller: ## Configuration for App Protect WAF v5 Enforcer enforcer: + # Host that the App Protect WAF v5 Enforcer runs on. + # This will normally be "127.0.0.1" as the Enforcer container + # will run in the same pod as the Ingress Controller container. + host: "127.0.0.1" # Port that the App Protect WAF v5 Enforcer runs on. port: 50000 image: diff --git a/cmd/nginx-ingress/flags.go b/cmd/nginx-ingress/flags.go index 3d02c86b23..8fbf141e97 100644 --- a/cmd/nginx-ingress/flags.go +++ b/cmd/nginx-ingress/flags.go @@ -16,8 +16,10 @@ import ( ) const ( - dynamicSSLReloadParam = "ssl-dynamic-reload" - dynamicWeightChangesParam = "weight-changes-dynamic-reload" + dynamicSSLReloadParam = "ssl-dynamic-reload" + dynamicWeightChangesParam = "weight-changes-dynamic-reload" + appProtectLogLevelDefault = "fatal" + appProtectEnforcerAddrDefault = "127.0.0.1:50000" ) var ( @@ -65,6 +67,9 @@ var ( appProtectDosMaxWorkers = flag.Int("app-protect-dos-max-workers", 0, "Max number of nginx processes to support. Requires -nginx-plus and -enable-app-protect-dos.") appProtectDosMemory = flag.Int("app-protect-dos-memory", 0, "RAM memory size to consume in MB. Requires -nginx-plus and -enable-app-protect-dos.") + appProtectEnforcerAddress = flag.String("app-protect-enforcer-addr", appProtectEnforcerAddrDefault, + `Sets address for App Protect v5 Enforcer. Requires -nginx-plus and -enable-app-protect.`) + agent = flag.Bool("agent", false, "Enable NGINX Agent") agentInstanceGroup = flag.String("agent-instance-group", "nginx-ingress-controller", "Grouping used to associate NGINX Ingress Controller instances") @@ -440,8 +445,6 @@ func validatePort(port int) error { return nil } -const appProtectLogLevelDefault = "fatal" - // validateAppProtectLogLevel makes sure a given logLevel is one of the allowed values func validateAppProtectLogLevel(logLevel string) error { switch strings.ToLower(logLevel) { diff --git a/cmd/nginx-ingress/main.go b/cmd/nginx-ingress/main.go index 28129af1f0..b39b380ddd 100644 --- a/cmd/nginx-ingress/main.go +++ b/cmd/nginx-ingress/main.go @@ -128,6 +128,7 @@ func main() { MainAppProtectLoadModule: *appProtect, MainAppProtectV5LoadModule: appProtectV5, MainAppProtectDosLoadModule: *appProtectDos, + MainAppProtectV5EnforcerAddr: *appProtectEnforcerAddress, EnableLatencyMetrics: *enableLatencyMetrics, EnableOIDC: *enableOIDC, SSLRejectHandshake: sslRejectHandshake, diff --git a/internal/configs/config_params.go b/internal/configs/config_params.go index d7080e281b..d091783a4f 100644 --- a/internal/configs/config_params.go +++ b/internal/configs/config_params.go @@ -147,6 +147,7 @@ type StaticConfigParams struct { MainAppProtectLoadModule bool MainAppProtectV5LoadModule bool MainAppProtectDosLoadModule bool + MainAppProtectV5EnforcerAddr string InternalRouteServerName string EnableLatencyMetrics bool EnableOIDC bool diff --git a/internal/configs/version1/nginx-plus.tmpl b/internal/configs/version1/nginx-plus.tmpl index 0a450d574b..a2de8c9df2 100644 --- a/internal/configs/version1/nginx-plus.tmpl +++ b/internal/configs/version1/nginx-plus.tmpl @@ -86,7 +86,7 @@ http { {{- end}} {{- if .AppProtectV5LoadModule}} - app_protect_enforcer_address 127.0.0.1:50000; + app_protect_enforcer_address {{ .MainAppProtectV5EnforcerAddr }}; {{- end}} {{- if .AccessLogOff}} From 69eae5e5a59305a12d70dc1280c23cee68b95383 Mon Sep 17 00:00:00 2001 From: Eoin O'Shaughnessy Date: Mon, 10 Jun 2024 13:50:24 +0100 Subject: [PATCH 19/34] helm docs for waf v5 --- charts/nginx-ingress/README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/charts/nginx-ingress/README.md b/charts/nginx-ingress/README.md index 239ed97490..7e44b0933c 100644 --- a/charts/nginx-ingress/README.md +++ b/charts/nginx-ingress/README.md @@ -443,6 +443,20 @@ The following tables lists the configurable parameters of the NGINX Ingress Cont |`controller.pod.annotations` | The annotations of the Ingress Controller pod. | {} | |`controller.pod.extraLabels` | The additional extra labels of the Ingress Controller pod. | {} | |`controller.appprotect.enable` | Enables the App Protect WAF module in the Ingress Controller. | false | +|`controller.appprotect.v5` | Enables App Protect WAF v5. | false | +|`controller.appprotect.volumes` | Volumes for App Protect WAF v5. | [{"name": "app-protect-bd-config", "emptyDir": {}},{"name": "app-protect-config", "emptyDir": {}},{"name": "app-protect-bundles", "emptyDir": {}}] | +|`controller.appprotect.enforcer.host` | Host that the App Protect WAF v5 Enforcer runs on. | "127.0.0.1" | +|`controller.appprotect.enforcer.port` | Port that the App Protect WAF v5 Enforcer runs on. | 50000 | +|`controller.appprotect.enforcer.image` | The image repository of the App Protect WAF v5 Enforcer. | private-registry.nginx.com/nap/waf-enforcer | +|`controller.appprotect.enforcer.tag` | The tag of the App Protect WAF v5 Enforcer. | "5.2.0" | +|`controller.appprotect.enforcer.digest` | The digest of the App Protect WAF v5 Enforcer. Takes precedence over tag if set. | "5.2.0" | +|`controller.appprotect.enforcer.pullPolicy` | The pull policy for the App Protect WAF v5 Enforcer image. | "5.2.0" | +|`controller.appprotect.enforcer.securityContext` | The security context for App Protect WAF v5 Enforcer container. | {} | +|`controller.appprotect.configManager.image` | The image repository of the App Protect WAF v5 Configuration Manager. | private-registry.nginx.com/nap/waf-config-mgr | +|`controller.appprotect.configManager.tag` | The tag of the App Protect WAF v5 Configuration Manager. | "5.2.0" | +|`controller.appprotect.configManager.digest` | The digest of the App Protect WAF v5 Configuration Manager. Takes precedence over tag if set. | "5.2.0" | +|`controller.appprotect.configManager.pullPolicy` | The pull policy for the App Protect WAF v5 Configuration Manager image. | "5.2.0" | +|`controller.appprotect.configManager.securityContext` | The security context for App Protect WAF v5 Configuration Manager container. | {"allowPrivilegeEscalation":false,"runAsUser":101,"runAsNonRoot":true,"capabilities":{"drop":["all"]}} | |`controller.appprotectdos.enable` | Enables the App Protect DoS module in the Ingress Controller. | false | |`controller.appprotectdos.debug` | Enable debugging for App Protect DoS. | false | |`controller.appprotectdos.maxDaemons` | Max number of ADMD instances. | 1 | From 6fc642205f10828ca6764ac91b5bde58f2cce2a5 Mon Sep 17 00:00:00 2001 From: Paul Abel Date: Mon, 10 Jun 2024 16:06:04 +0100 Subject: [PATCH 20/34] mount agent.sh on ubi-8-plus-nap --- build/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/build/Dockerfile b/build/Dockerfile index 90bf127b51..61c1e5f6b2 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -425,6 +425,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode --mount=type=bind,from=nginx-files,src=app-protect-dos-8.repo,target=/tmp/app-protect-dos-8.repo \ --mount=type=bind,from=nginx-files,src=nap-waf.sh,target=/usr/local/bin/nap-waf.sh \ --mount=type=bind,from=nginx-files,src=nap-dos.sh,target=/usr/local/bin/nap-dos.sh \ + --mount=type=bind,from=nginx-files,src=agent.sh,target=/usr/local/bin/agent.sh \ source /tmp/rhel_license \ && if [ -z "${NAP_MODULES##*waf*}" ]; then \ cp /tmp/app-protect-8.repo /etc/yum.repos.d/app-protect-8.repo; \ From 06c627b335342c5cbecc47200800f30faaf78b73 Mon Sep 17 00:00:00 2001 From: Eoin O'Shaughnessy Date: Mon, 10 Jun 2024 16:08:10 +0100 Subject: [PATCH 21/34] adding missing script mounts for ubi8 waf v5 --- build/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/Dockerfile b/build/Dockerfile index 61c1e5f6b2..46fdc2a879 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -482,6 +482,8 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode --mount=type=bind,from=nginx-files,src=nginx-agent.repo,target=/etc/yum.repos.d/nginx-agent.repo,rw \ --mount=type=bind,from=nginx-files,src=app-protect-v5-8.repo,target=/tmp/app-protect-8.repo \ --mount=type=bind,from=nginx-files,src=app-protect-dos-8.repo,target=/tmp/app-protect-dos-8.repo \ + --mount=type=bind,from=nginx-files,src=nap-waf.sh,target=/usr/local/bin/nap-waf.sh \ + --mount=type=bind,from=nginx-files,src=agent.sh,target=/usr/local/bin/agent.sh \ source /tmp/rhel_license \ && if [ -z "${NAP_MODULES##*waf*}" ]; then \ cp /tmp/app-protect-8.repo /etc/yum.repos.d/app-protect-8.repo; \ From 5d5619d2d0effe975a976597e04a1ddd252d6bc6 Mon Sep 17 00:00:00 2001 From: Eoin O'Shaughnessy Date: Tue, 11 Jun 2024 09:40:51 +0100 Subject: [PATCH 22/34] conditional compiler reference for v4 --- build/scripts/agent.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/build/scripts/agent.sh b/build/scripts/agent.sh index b304b0c7c7..0cb6a07ffd 100755 --- a/build/scripts/agent.sh +++ b/build/scripts/agent.sh @@ -2,9 +2,13 @@ set -e -NAP_VERSION=$(cat /opt/app_protect/VERSION) -mkdir -p /etc/ssl/nms /opt/nms-nap-compiler -chown -R 101:0 /etc/ssl/nms /opt/nms-nap-compiler -chmod -R g=u /etc/ssl/nms /opt/nms-nap-compiler -ln -s /opt/app_protect "/opt/nms-nap-compiler/app_protect-${NAP_VERSION}" +if [ -z "${WAF_VERSION##*v4*}" ]; then + NAP_VERSION=$(cat /opt/app_protect/VERSION) + + mkdir -p /etc/ssl/nms /opt/nms-nap-compiler + chown -R 101:0 /etc/ssl/nms /opt/nms-nap-compiler + chmod -R g=u /etc/ssl/nms /opt/nms-nap-compiler + + ln -s /opt/app_protect "/opt/nms-nap-compiler/app_protect-${NAP_VERSION}" +fi From e1fb50732afa435119302b3dc1f4a5cebe2b1afb Mon Sep 17 00:00:00 2001 From: Eoin O'Shaughnessy Date: Tue, 11 Jun 2024 09:56:31 +0100 Subject: [PATCH 23/34] reorder debian waf v5 --- build/Dockerfile | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/build/Dockerfile b/build/Dockerfile index 46a8bce460..49053fde89 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -201,30 +201,6 @@ RUN --mount=type=bind,from=alpine-fips-3.17,target=/tmp/fips/ \ ; fi -############################################# Base image for Debian with NGINX Plus and App Protect WAFv5/DoS ############################################# -FROM debian-plus as debian-plus-nap-v5 -ARG NAP_MODULES - -RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \ - --mount=type=secret,id=nginx-repo.key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \ - --mount=type=bind,from=nginx-files,src=90pkgs-nginx,target=/etc/apt/apt.conf.d/90pkgs-nginx \ - --mount=type=bind,from=nginx-files,src=nap-waf-v5-12.sources,target=/tmp/app-protect.sources \ - --mount=type=bind,from=nginx-files,src=debian-agent-11.sources,target=/etc/apt/sources.list.d/nginx-agent.sources \ - if [ -z "${NAP_MODULES##*waf*}" ]; then \ - cp /tmp/app-protect.sources /etc/apt/sources.list.d/app-protect.sources; \ - fi \ - && apt-get update \ - && if [ -z "${NGINX_AGENT##true}" ]; then apt-get install --no-install-recommends --no-install-suggests -y nginx-agent; fi \ - && if [ -z "${NAP_MODULES##*waf*}" ]; then \ - apt-get install --no-install-recommends --no-install-suggests -y app-protect-module-plus; \ - rm -f /etc/apt/sources.list.d/app-protect.sources; \ - nap-waf.sh; \ - && apt-get purge --auto-remove -y gpg \ - && if [ -z "${NGINX_AGENT##true}" ]; then \ - agent.sh; \ - fi - - ############################################# Base image for Debian with NGINX Plus ############################################# FROM debian:12-slim@sha256:804194b909ef23fb995d9412c9378fb3505fe2427b70f3cc425339e48a828fca AS debian-plus @@ -310,6 +286,29 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode nap-dos.sh \ ; fi +############################################# Base image for Debian with NGINX Plus and App Protect WAFv5/DoS ############################################# +FROM debian-plus as debian-plus-nap-v5 +ARG NAP_MODULES + +RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \ + --mount=type=secret,id=nginx-repo.key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \ + --mount=type=bind,from=nginx-files,src=90pkgs-nginx,target=/etc/apt/apt.conf.d/90pkgs-nginx \ + --mount=type=bind,from=nginx-files,src=nap-waf-v5-12.sources,target=/tmp/app-protect.sources \ + --mount=type=bind,from=nginx-files,src=debian-agent-11.sources,target=/etc/apt/sources.list.d/nginx-agent.sources \ + if [ -z "${NAP_MODULES##*waf*}" ]; then \ + cp /tmp/app-protect.sources /etc/apt/sources.list.d/app-protect.sources; \ + fi \ + && apt-get update \ + && if [ -z "${NGINX_AGENT##true}" ]; then apt-get install --no-install-recommends --no-install-suggests -y nginx-agent; fi \ + && if [ -z "${NAP_MODULES##*waf*}" ]; then \ + apt-get install --no-install-recommends --no-install-suggests -y app-protect-module-plus; \ + rm -f /etc/apt/sources.list.d/app-protect.sources; \ + nap-waf.sh; \ + && apt-get purge --auto-remove -y gpg \ + && if [ -z "${NGINX_AGENT##true}" ]; then \ + agent.sh; \ + fi + ############################################# Base image for UBI with NGINX Plus ############################################# FROM ubi-minimal AS ubi-plus From 06c4a717984ee8373c081bf48b7200ac22863d62 Mon Sep 17 00:00:00 2001 From: Eoin O'Shaughnessy Date: Tue, 11 Jun 2024 10:10:57 +0100 Subject: [PATCH 24/34] fix debian waf v5 build --- build/Dockerfile | 3 +++ build/scripts/nap-waf.sh | 11 ++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/build/Dockerfile b/build/Dockerfile index 49053fde89..8e75cbfc26 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -294,6 +294,8 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode --mount=type=secret,id=nginx-repo.key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \ --mount=type=bind,from=nginx-files,src=90pkgs-nginx,target=/etc/apt/apt.conf.d/90pkgs-nginx \ --mount=type=bind,from=nginx-files,src=nap-waf-v5-12.sources,target=/tmp/app-protect.sources \ + --mount=type=bind,from=nginx-files,src=agent.sh,target=/usr/local/bin/agent.sh \ + --mount=type=bind,from=nginx-files,src=nap-waf.sh,target=/usr/local/bin/nap-waf.sh \ --mount=type=bind,from=nginx-files,src=debian-agent-11.sources,target=/etc/apt/sources.list.d/nginx-agent.sources \ if [ -z "${NAP_MODULES##*waf*}" ]; then \ cp /tmp/app-protect.sources /etc/apt/sources.list.d/app-protect.sources; \ @@ -304,6 +306,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode apt-get install --no-install-recommends --no-install-suggests -y app-protect-module-plus; \ rm -f /etc/apt/sources.list.d/app-protect.sources; \ nap-waf.sh; \ + fi \ && apt-get purge --auto-remove -y gpg \ && if [ -z "${NGINX_AGENT##true}" ]; then \ agent.sh; \ diff --git a/build/scripts/nap-waf.sh b/build/scripts/nap-waf.sh index 5d295ea500..cf736732d7 100755 --- a/build/scripts/nap-waf.sh +++ b/build/scripts/nap-waf.sh @@ -2,7 +2,12 @@ set -e -mkdir -p /etc/nginx/waf/nac-policies /etc/nginx/waf/nac-logconfs /etc/nginx/waf/nac-usersigs /var/log/app_protect /opt/app_protect -chown -R 101:0 /etc/app_protect /usr/share/ts /var/log/app_protect/ /opt/app_protect/ -chmod -R g=u /etc/app_protect /usr/share/ts /var/log/app_protect/ /opt/app_protect/ +for i in /etc/nginx/waf/nac-policies /etc/nginx/waf/nac-logconfs /etc/nginx/waf/nac-usersigs /etc/app_protect /usr/share/ts /var/log/app_protect/ /opt/app_protect/; do + if [ ! -d ${i} ]; then + mkdir -p ${i} + fi + chown -R 101:0 ${i} + chmod -R g=u ${i} +done + touch /etc/nginx/waf/nac-usersigs/index.conf From 637dc8cb68b7740f7862a79a9fcbaf35ed4172b2 Mon Sep 17 00:00:00 2001 From: Paul Abel Date: Tue, 11 Jun 2024 11:21:59 +0100 Subject: [PATCH 25/34] update agent install logic --- build/Dockerfile | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/build/Dockerfile b/build/Dockerfile index 8e75cbfc26..656cbfd7b3 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -156,7 +156,7 @@ RUN --mount=type=bind,from=alpine-fips-3.17,target=/tmp/fips/ \ && printf "%s\n" "https://pkgs.nginx.com/app-protect-security-updates/alpine/v$(grep -E -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ && printf "%s\n" "https://pkgs.nginx.com/nginx-agent/alpine/v$(grep -E -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ && apk add --no-cache libcap-utils libcurl nginx-plus nginx-plus-module-njs nginx-plus-module-opentracing nginx-plus-module-fips-check \ - && if [ -z "${NGINX_AGENT##true}" ]; then apk add --no-cache nginx-agent; fi \ + && if [ "${NGINX_AGENT}" = "true" ]; then apk add --no-cache nginx-agent; fi \ && mkdir -p /usr/ssl \ && cp -av /tmp/fips/usr/lib/ossl-modules/fips.so /usr/lib/ossl-modules/fips.so \ && cp -av /tmp/fips/usr/ssl/fipsmodule.cnf /usr/ssl/fipsmodule.cnf \ @@ -166,7 +166,7 @@ RUN --mount=type=bind,from=alpine-fips-3.17,target=/tmp/fips/ \ && apk add --no-cache app-protect app-protect-attack-signatures app-protect-threat-campaigns \ && sed -i -e '/nginx.com/d' /etc/apk/repositories \ && nap-waf.sh \ - && if [ -z "${NGINX_AGENT##true}" ]; then \ + && if [ "${NGINX_AGENT}" = "true" ]; then \ agent.sh \ ; fi @@ -186,7 +186,7 @@ RUN --mount=type=bind,from=alpine-fips-3.17,target=/tmp/fips/ \ && printf "%s\n" "https://pkgs.nginx.com/app-protect-x-plus/alpine/v$(grep -E -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ && printf "%s\n" "https://pkgs.nginx.com/nginx-agent/alpine/v$(grep -E -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ && apk add --no-cache libcap-utils libcurl nginx-plus nginx-plus-module-njs nginx-plus-module-opentracing nginx-plus-module-fips-check \ - && if [ -z "${NGINX_AGENT##true}" ]; then apk add --no-cache nginx-agent; fi \ + && if [ "${NGINX_AGENT}" = "true" ]; then apk add --no-cache nginx-agent; fi \ && mkdir -p /usr/ssl \ && cp -av /tmp/fips/usr/lib/ossl-modules/fips.so /usr/lib/ossl-modules/fips.so \ && cp -av /tmp/fips/usr/ssl/fipsmodule.cnf /usr/ssl/fipsmodule.cnf \ @@ -196,7 +196,7 @@ RUN --mount=type=bind,from=alpine-fips-3.17,target=/tmp/fips/ \ && apk add --no-cache app-protect-module-plus \ && sed -i -e '/nginx.com/d' /etc/apk/repositories \ && nap-waf.sh \ - && if [ -z "${NGINX_AGENT##true}" ]; then \ + && if [ "${NGINX_AGENT}" = "true" ]; then \ agent.sh \ ; fi @@ -257,7 +257,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode && apt-get update \ && apt-get install --no-install-recommends --no-install-suggests -y nginx-plus nginx-plus-module-njs nginx-plus-module-opentracing nginx-plus-module-fips-check libcap2-bin libcurl4 \ ## end of duplicated code - && if [ -z "${NGINX_AGENT##true}" ]; then apt-get install --no-install-recommends --no-install-suggests -y nginx-agent; fi \ + && if [ "${NGINX_AGENT}" = "true" ]; then apt-get install --no-install-recommends --no-install-suggests -y nginx-agent; fi \ && if [ -z "${NAP_MODULES##*waf*}" ]; then \ apt-get install --no-install-recommends --no-install-suggests -y app-protect app-protect-attack-signatures app-protect-threat-campaigns; \ fi \ @@ -278,7 +278,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode && rm -rf /var/lib/apt/lists/* \ && if [ -z "${NAP_MODULES##*waf*}" ]; then \ nap-waf.sh \ - && if [ -z "${NGINX_AGENT##true}" ]; then \ + && if [ "${NGINX_AGENT}" = "true" ]; then \ agent.sh \ ; fi \ ; fi \ @@ -301,14 +301,14 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode cp /tmp/app-protect.sources /etc/apt/sources.list.d/app-protect.sources; \ fi \ && apt-get update \ - && if [ -z "${NGINX_AGENT##true}" ]; then apt-get install --no-install-recommends --no-install-suggests -y nginx-agent; fi \ + && if [ "${NGINX_AGENT}" = "true" ]; then apt-get install --no-install-recommends --no-install-suggests -y nginx-agent; fi \ && if [ -z "${NAP_MODULES##*waf*}" ]; then \ apt-get install --no-install-recommends --no-install-suggests -y app-protect-module-plus; \ rm -f /etc/apt/sources.list.d/app-protect.sources; \ nap-waf.sh; \ fi \ && apt-get purge --auto-remove -y gpg \ - && if [ -z "${NGINX_AGENT##true}" ]; then \ + && if [ "${NGINX_AGENT}" = "true" ]; then \ agent.sh; \ fi @@ -352,7 +352,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode && useradd --system --gid nginx --no-create-home --home-dir /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \ && rpm --import /tmp/nginx_signing.key \ && microdnf --nodocs install -y nginx-plus nginx-plus-module-njs nginx-plus-module-fips-check \ - && if [ -z "${NGINX_AGENT##true}" ]; then microdnf --nodocs install -y nginx-agent; fi \ + && if [ "${NGINX_AGENT}" = "true" ]; then microdnf --nodocs install -y nginx-agent; fi \ && subscription-manager register --org=${RHEL_ORGANIZATION} --activationkey=${RHEL_ACTIVATION_KEY} || true \ && subscription-manager attach \ && rpm --import /tmp/app-protect-security-updates.key \ @@ -366,7 +366,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode && subscription-manager unregister \ && microdnf remove -y shadow-utils subscription-manager \ && microdnf clean all && rm -rf /var/cache/dnf \ - && if [ -z "${NGINX_AGENT##true}" ]; then \ + && if [ "${NGINX_AGENT}" = "true" ]; then \ agent.sh \ ; fi @@ -391,7 +391,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode && useradd --system --gid nginx --no-create-home --home-dir /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \ && rpm --import /tmp/nginx_signing.key \ && microdnf --nodocs install -y nginx-plus nginx-plus-module-njs nginx-plus-module-fips-check \ - && if [ -z "${NGINX_AGENT##true}" ]; then microdnf --nodocs install -y nginx-agent; fi \ + && if [ "${NGINX_AGENT}" = "true" ]; then microdnf --nodocs install -y nginx-agent; fi \ && subscription-manager register --org=${RHEL_ORGANIZATION} --activationkey=${RHEL_ACTIVATION_KEY} || true \ && subscription-manager attach \ && if [ -z "${NAP_MODULES##*waf*}" ]; then \ @@ -407,7 +407,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode && subscription-manager unregister \ && microdnf remove -y shadow-utils subscription-manager \ && microdnf clean all && rm -rf /var/cache/dnf \ - && if [ -z "${NGINX_AGENT##true}" ]; then \ + && if [ "${NGINX_AGENT}" = "true" ]; then \ agent.sh; \ fi @@ -440,7 +440,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode && useradd --system --gid nginx --no-create-home --home-dir /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \ && rpm --import /tmp/nginx_signing.key \ && dnf --nodocs install -y nginx-plus nginx-plus-module-njs nginx-plus-module-fips-check \ - && if [ -z "${NGINX_AGENT##true}" ]; then dnf --nodocs install -y nginx-agent; fi \ + && if [ "${NGINX_AGENT}" = "true" ]; then dnf --nodocs install -y nginx-agent; fi \ ## end of duplicated code ## fix for CVEs && sed -i 's/\(def in_container():\)/\1\n return False/g' /usr/lib64/python*/*-packages/rhsm/config.py \ @@ -466,7 +466,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode rm -f /etc/yum.repos.d/app-protect-dos-8.repo \ && nap-dos.sh; \ fi \ - && if [ -z "${NGINX_AGENT##true}" ]; then \ + && if [ "${NGINX_AGENT}" = "true" ]; then \ agent.sh; \ fi \ && dnf clean all @@ -495,7 +495,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode && useradd --system --gid nginx --no-create-home --home-dir /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \ && rpm --import /tmp/nginx_signing.key \ && dnf --nodocs install -y nginx-plus nginx-plus-module-njs nginx-plus-module-fips-check \ - && if [ -z "${NGINX_AGENT##true}" ]; then dnf --nodocs install -y nginx-agent; fi \ + && if [ "${NGINX_AGENT}" = "true" ]; then dnf --nodocs install -y nginx-agent; fi \ ## end of duplicated code && sed -i 's/\(def in_container():\)/\1\n return False/g' /usr/lib64/python*/*-packages/rhsm/config.py \ && subscription-manager register --org=${RHEL_ORGANIZATION} --activationkey=${RHEL_ACTIVATION_KEY} || true \ @@ -510,7 +510,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode rm -f /etc/yum.repos.d/app-protect-8.repo \ && nap-waf.sh; \ fi \ - && if [ -z "${NGINX_AGENT##true}" ]; then \ + && if [ "${NGINX_AGENT}" = "true" ]; then \ agent.sh; \ fi \ && dnf clean all From dbfcb6efc1f09276b63c301a14f22c4a41423f56 Mon Sep 17 00:00:00 2001 From: Eoin O'Shaughnessy Date: Tue, 11 Jun 2024 13:41:58 +0100 Subject: [PATCH 26/34] fix enforcer address flag --- cmd/nginx-ingress/flags.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/nginx-ingress/flags.go b/cmd/nginx-ingress/flags.go index 8fbf141e97..d36381974e 100644 --- a/cmd/nginx-ingress/flags.go +++ b/cmd/nginx-ingress/flags.go @@ -67,7 +67,7 @@ var ( appProtectDosMaxWorkers = flag.Int("app-protect-dos-max-workers", 0, "Max number of nginx processes to support. Requires -nginx-plus and -enable-app-protect-dos.") appProtectDosMemory = flag.Int("app-protect-dos-memory", 0, "RAM memory size to consume in MB. Requires -nginx-plus and -enable-app-protect-dos.") - appProtectEnforcerAddress = flag.String("app-protect-enforcer-addr", appProtectEnforcerAddrDefault, + appProtectEnforcerAddress = flag.String("app-protect-enforcer-address", appProtectEnforcerAddrDefault, `Sets address for App Protect v5 Enforcer. Requires -nginx-plus and -enable-app-protect.`) agent = flag.Bool("agent", false, "Enable NGINX Agent") From 9b5b02e76cd6f3c815211ccf5c55a33192716bda Mon Sep 17 00:00:00 2001 From: Eoin O'Shaughnessy Date: Tue, 11 Jun 2024 14:47:07 +0100 Subject: [PATCH 27/34] fix agent arg --- build/Dockerfile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/build/Dockerfile b/build/Dockerfile index 656cbfd7b3..1e11f98bd5 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -142,6 +142,7 @@ RUN --mount=type=bind,from=alpine-fips-3.19,target=/tmp/fips/ \ ############################################# Base image for Alpine with NGINX Plus, App Protect WAF and FIPS ############################################# FROM alpine:3.17@sha256:53cf9478b76f4c8fae126acbdfb79bed6e69e628faff572ebe4a029d3d247d98 as alpine-plus-nap-fips ARG NGINX_PLUS_VERSION +ARG NGINX_AGENT RUN --mount=type=bind,from=alpine-fips-3.17,target=/tmp/fips/ \ --mount=type=secret,id=nginx-repo.crt,dst=/etc/apk/cert.pem,mode=0644 \ @@ -174,6 +175,7 @@ RUN --mount=type=bind,from=alpine-fips-3.17,target=/tmp/fips/ \ ############################################# Base image for Alpine with NGINX Plus, App Protect WAFv5 and FIPS ############################################# FROM alpine:3.17@sha256:53cf9478b76f4c8fae126acbdfb79bed6e69e628faff572ebe4a029d3d247d98 as alpine-plus-nap-v5-fips ARG NGINX_PLUS_VERSION +ARG NGINX_AGENT RUN --mount=type=bind,from=alpine-fips-3.17,target=/tmp/fips/ \ --mount=type=secret,id=nginx-repo.crt,dst=/etc/apk/cert.pem,mode=0644 \ @@ -227,6 +229,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode ############################################# Base image for Debian with NGINX Plus and App Protect WAF/DoS ############################################# FROM debian:11-slim@sha256:0e75382930ceb533e2f438071307708e79dc86d9b8e433cc6dd1a96872f2651d as debian-plus-nap ARG NAP_MODULES +ARG NGINX_AGENT RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \ --mount=type=secret,id=nginx-repo.key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \ @@ -289,6 +292,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode ############################################# Base image for Debian with NGINX Plus and App Protect WAFv5/DoS ############################################# FROM debian-plus as debian-plus-nap-v5 ARG NAP_MODULES +ARG NGINX_AGENT RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \ --mount=type=secret,id=nginx-repo.key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \ @@ -334,6 +338,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode ############################################# Base image for UBI with NGINX Plus and App Protect WAF ############################################# FROM ubi-minimal as ubi-9-plus-nap ARG NAP_MODULES +ARG NGINX_AGENT RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \ --mount=type=secret,id=nginx-repo.key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \ @@ -374,6 +379,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode ############################################# Base image for UBI with NGINX Plus and App Protect WAFv5 ############################################# FROM ubi-minimal as ubi-9-plus-nap-v5 ARG NAP_MODULES +ARG NGINX_AGENT RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \ --mount=type=secret,id=nginx-repo.key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \ @@ -415,6 +421,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode ############################################# Base image for UBI with NGINX Plus and App Protect WAF & DoS ############################################# FROM redhat/ubi8@sha256:143123d85045df426c5bbafc6863659880ebe276eb02c77ee868b88d08dbd05d as ubi-8-plus-nap ARG NAP_MODULES +ARG NGINX_AGENT RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \ --mount=type=secret,id=nginx-repo.key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \ @@ -475,6 +482,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode ############################################# Base image for UBI with NGINX Plus and App Protect WAFv5 ############################################# FROM redhat/ubi8@sha256:f4292f415f60632a0ff9c0646c4fa859d8b2e1e88a16faa90c6decd1951aea88 as ubi-8-plus-nap-v5 ARG NAP_MODULES +ARG NGINX_AGENT RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \ --mount=type=secret,id=nginx-repo.key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \ From 6b5a36d1f7ef4a280445a4da35ff475d9dd04504 Mon Sep 17 00:00:00 2001 From: Eoin O'Shaughnessy Date: Tue, 11 Jun 2024 16:44:19 +0100 Subject: [PATCH 28/34] re-add bundle mount to NIC --- charts/nginx-ingress/templates/_helpers.tpl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/charts/nginx-ingress/templates/_helpers.tpl b/charts/nginx-ingress/templates/_helpers.tpl index 1707eced2a..051cd17b0d 100644 --- a/charts/nginx-ingress/templates/_helpers.tpl +++ b/charts/nginx-ingress/templates/_helpers.tpl @@ -389,6 +389,10 @@ volumeMounts: mountPath: /opt/app_protect/bd_config - name: app-protect-config mountPath: /opt/app_protect/config + # app-protect-bundles is mounted so that Ingress Controller + # can verify that referenced bundles are present +- name: app-protect-bundles + mountPath: /etc/app_protect/bundles {{- end }} {{- if .Values.controller.volumeMounts }} {{ toYaml .Values.controller.volumeMounts }} From fe17f41e0d5d66cc97a312dd9b0c4564ec6d5387 Mon Sep 17 00:00:00 2001 From: oseoin Date: Tue, 11 Jun 2024 18:02:23 +0100 Subject: [PATCH 29/34] Update charts/nginx-ingress/values.schema.json Co-authored-by: Paul Abel <128620221+pdabelf5@users.noreply.github.com> Signed-off-by: oseoin --- charts/nginx-ingress/values.schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/nginx-ingress/values.schema.json b/charts/nginx-ingress/values.schema.json index 97c528d0fe..c1e4764ce0 100644 --- a/charts/nginx-ingress/values.schema.json +++ b/charts/nginx-ingress/values.schema.json @@ -179,7 +179,7 @@ "default": "127.0.0.1", "title": "Port which the App Protect WAF v5 Enforcer process runs on", "examples": [ - 50000 + 127.0.0.1 ] }, "port": { From e22453b26a78a2cd992eb15997dce2b673870837 Mon Sep 17 00:00:00 2001 From: Eoin O'Shaughnessy Date: Wed, 12 Jun 2024 09:29:05 +0100 Subject: [PATCH 30/34] fix enforcer address --- internal/configs/configmaps.go | 1 + internal/configs/version1/config.go | 1 + internal/configs/version1/nginx-plus.tmpl | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/configs/configmaps.go b/internal/configs/configmaps.go index 5bf00d4437..c4041336da 100644 --- a/internal/configs/configmaps.go +++ b/internal/configs/configmaps.go @@ -567,6 +567,7 @@ func GenerateNginxMainConfig(staticCfgParams *StaticConfigParams, config *Config AppProtectLoadModule: staticCfgParams.MainAppProtectLoadModule, AppProtectV5LoadModule: staticCfgParams.MainAppProtectV5LoadModule, AppProtectDosLoadModule: staticCfgParams.MainAppProtectDosLoadModule, + AppProtectV5EnforcerAddr: staticCfgParams.MainAppProtectV5EnforcerAddr, AppProtectFailureModeAction: config.MainAppProtectFailureModeAction, AppProtectCompressedRequestsAction: config.MainAppProtectCompressedRequestsAction, AppProtectCookieSeed: config.MainAppProtectCookieSeed, diff --git a/internal/configs/version1/config.go b/internal/configs/version1/config.go index dc066244a9..85d8c2006a 100644 --- a/internal/configs/version1/config.go +++ b/internal/configs/version1/config.go @@ -246,6 +246,7 @@ type MainConfig struct { WorkerShutdownTimeout string AppProtectLoadModule bool AppProtectV5LoadModule bool + AppProtectV5EnforcerAddr string AppProtectFailureModeAction string AppProtectCompressedRequestsAction string AppProtectCookieSeed string diff --git a/internal/configs/version1/nginx-plus.tmpl b/internal/configs/version1/nginx-plus.tmpl index a2de8c9df2..e13589d5b3 100644 --- a/internal/configs/version1/nginx-plus.tmpl +++ b/internal/configs/version1/nginx-plus.tmpl @@ -86,7 +86,7 @@ http { {{- end}} {{- if .AppProtectV5LoadModule}} - app_protect_enforcer_address {{ .MainAppProtectV5EnforcerAddr }}; + app_protect_enforcer_address {{ .AppProtectV5EnforcerAddr }}; {{- end}} {{- if .AccessLogOff}} From 1e24f0bc56d9cbc98b5a984f658a180b32a50e63 Mon Sep 17 00:00:00 2001 From: Eoin O'Shaughnessy Date: Wed, 12 Jun 2024 10:33:33 +0100 Subject: [PATCH 31/34] switch waf bundle path depending on v5 or earlier --- cmd/nginx-ingress/main.go | 15 ++++++++++----- internal/configs/config_params.go | 1 + internal/configs/configurator.go | 1 - internal/configs/version2/templates_test.go | 2 +- internal/configs/virtualserver.go | 3 +-- internal/configs/virtualserver_test.go | 8 ++++---- 6 files changed, 17 insertions(+), 13 deletions(-) diff --git a/cmd/nginx-ingress/main.go b/cmd/nginx-ingress/main.go index b39b380ddd..8d3c46897d 100644 --- a/cmd/nginx-ingress/main.go +++ b/cmd/nginx-ingress/main.go @@ -48,11 +48,13 @@ var ( ) const ( - nginxVersionLabel = "app.nginx.org/version" - versionLabel = "app.kubernetes.io/version" - appProtectVersionLabel = "appprotect.f5.com/version" - agentVersionLabel = "app.nginx.org/agent-version" - appProtectVersionPath = "/opt/app_protect/RELEASE" + nginxVersionLabel = "app.nginx.org/version" + versionLabel = "app.kubernetes.io/version" + appProtectVersionLabel = "appprotect.f5.com/version" + agentVersionLabel = "app.nginx.org/agent-version" + appProtectVersionPath = "/opt/app_protect/RELEASE" + appProtectBundleFolder = "/etc/nginx/waf/bundles/" + appProtectv5BundleFolder = "/etc/app_protect/bundles/" ) func main() { @@ -82,12 +84,14 @@ func main() { var appProtectVersion string var appProtectV5 bool + appProtectBundlePath := appProtectBundleFolder if *appProtect { appProtectVersion = getAppProtectVersionInfo() r := regexp.MustCompile("^5.*") if r.MatchString(appProtectVersion) { appProtectV5 = true + appProtectBundlePath = appProtectv5BundleFolder } } @@ -137,6 +141,7 @@ func main() { DynamicWeightChangesReload: *enableDynamicWeightChangesReload, StaticSSLPath: nginxManager.GetSecretsDir(), NginxVersion: nginxVersion, + AppProtectBundlePath: appProtectBundlePath, } processNginxConfig(staticCfgParams, cfgParams, templateExecutor, nginxManager) diff --git a/internal/configs/config_params.go b/internal/configs/config_params.go index d091783a4f..be86ae4eb9 100644 --- a/internal/configs/config_params.go +++ b/internal/configs/config_params.go @@ -157,6 +157,7 @@ type StaticConfigParams struct { StaticSSLPath string DynamicWeightChangesReload bool NginxVersion nginx.Version + AppProtectBundlePath string } // GlobalConfigParams holds global configuration parameters. For now, it only holds listeners. diff --git a/internal/configs/configurator.go b/internal/configs/configurator.go index eeb7230c38..d8412b8bba 100644 --- a/internal/configs/configurator.go +++ b/internal/configs/configurator.go @@ -31,7 +31,6 @@ import ( const ( pemFileNameForWildcardTLSSecret = "/etc/nginx/secrets/wildcard" // #nosec G101 - appProtectBundleFolder = "/etc/app_protect/bundles/" appProtectPolicyFolder = "/etc/nginx/waf/nac-policies/" appProtectLogConfFolder = "/etc/nginx/waf/nac-logconfs/" appProtectUserSigFolder = "/etc/nginx/waf/nac-usersigs/" diff --git a/internal/configs/version2/templates_test.go b/internal/configs/version2/templates_test.go index 2dccad22d4..28ea24e599 100644 --- a/internal/configs/version2/templates_test.go +++ b/internal/configs/version2/templates_test.go @@ -2705,7 +2705,7 @@ var ( VerifyDepth: 2, }, WAF: &WAF{ - ApBundle: "/etc/app_protect/bundles/NginxDefaultPolicy.tgz", + ApBundle: "/fake/bundle/path/NginxDefaultPolicy.tgz", ApSecurityLogEnable: true, ApLogConf: []string{"/etc/nginx/waf/nac-logconfs/default-logconf"}, }, diff --git a/internal/configs/virtualserver.go b/internal/configs/virtualserver.go index aa6c12fcdf..64e819bfda 100644 --- a/internal/configs/virtualserver.go +++ b/internal/configs/virtualserver.go @@ -315,7 +315,7 @@ func newVirtualServerConfigurator( bundleValidator bundleValidator, ) *virtualServerConfigurator { if bundleValidator == nil { - bundleValidator = newInternalBundleValidator(appProtectBundleFolder) + bundleValidator = newInternalBundleValidator(staticParams.AppProtectBundlePath) } return &virtualServerConfigurator{ cfgParams: cfgParams, @@ -1325,7 +1325,6 @@ func (p *policiesCfg) addWAFConfig( } if waf.ApBundle != "" { - p.WAF.ApBundle = appProtectBundleFolder + waf.ApBundle bundlePath, err := p.BundleValidator.validate(waf.ApBundle) if err != nil { res.addWarningf("WAF policy %s references an invalid or non-existing App Protect bundle %s", polKey, bundlePath) diff --git a/internal/configs/virtualserver_test.go b/internal/configs/virtualserver_test.go index 5f51237136..22cc242b48 100644 --- a/internal/configs/virtualserver_test.go +++ b/internal/configs/virtualserver_test.go @@ -6378,7 +6378,7 @@ func TestGeneratePolicies_GeneratesWAFPolicyOnValidApBundle(t *testing.T) { want: policiesCfg{ WAF: &version2.WAF{ Enable: "on", - ApBundle: "/etc/app_protect/bundles/testWAFPolicyBundle.tgz", + ApBundle: "/fake/bundle/path/testWAFPolicyBundle.tgz", }, }, }, @@ -6410,9 +6410,9 @@ func TestGeneratePolicies_GeneratesWAFPolicyOnValidApBundle(t *testing.T) { want: policiesCfg{ WAF: &version2.WAF{ Enable: "on", - ApBundle: "/etc/app_protect/bundles/testWAFPolicyBundle.tgz", + ApBundle: "/fake/bundle/path/testWAFPolicyBundle.tgz", ApSecurityLogEnable: true, - ApLogConf: []string{"/etc/app_protect/bundles/secops_dashboard.tgz syslog:server=localhost:514"}, + ApLogConf: []string{"/fake/bundle/path/secops_dashboard.tgz syslog:server=localhost:514"}, }, }, }, @@ -14663,7 +14663,7 @@ var ( type fakeBundleValidator struct{} func (*fakeBundleValidator) validate(bundle string) (string, error) { - bundle = fmt.Sprintf("/etc/app_protect/bundles/%s", bundle) + bundle = fmt.Sprintf("/fake/bundle/path/%s", bundle) if strings.Contains(bundle, "invalid") { return bundle, fmt.Errorf("invalid bundle %s", bundle) } From 52b6c9efd8e4dc649cfa8ed83186f42c23ddfc4c Mon Sep 17 00:00:00 2001 From: Eoin O'Shaughnessy Date: Wed, 12 Jun 2024 10:40:47 +0100 Subject: [PATCH 32/34] helm lint fixes --- charts/nginx-ingress/values.schema.json | 2 +- charts/nginx-ingress/values.yaml | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/charts/nginx-ingress/values.schema.json b/charts/nginx-ingress/values.schema.json index c1e4764ce0..d73c968af7 100644 --- a/charts/nginx-ingress/values.schema.json +++ b/charts/nginx-ingress/values.schema.json @@ -179,7 +179,7 @@ "default": "127.0.0.1", "title": "Port which the App Protect WAF v5 Enforcer process runs on", "examples": [ - 127.0.0.1 + "127.0.0.1" ] }, "port": { diff --git a/charts/nginx-ingress/values.yaml b/charts/nginx-ingress/values.yaml index 62a059a540..efb7adb6c9 100644 --- a/charts/nginx-ingress/values.yaml +++ b/charts/nginx-ingress/values.yaml @@ -229,8 +229,7 @@ controller: type: RuntimeDefault ## The security context for the Ingress Controller containers. - securityContext: - {} # Remove curly brackets before adding values + securityContext: {} # Remove curly brackets before adding values # allowPrivilegeEscalation: true # readOnlyRootFilesystem: true # runAsUser: 101 #nginx From 20ebbbd2d3d4b23094099eaaa894ae2a09d8fbc0 Mon Sep 17 00:00:00 2001 From: Eoin O'Shaughnessy Date: Wed, 12 Jun 2024 10:47:20 +0100 Subject: [PATCH 33/34] ubi build fix --- build/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Dockerfile b/build/Dockerfile index 1e11f98bd5..935e53dde8 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -409,7 +409,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode && rm -f /etc/yum.repos.d/app-protect-9.repo \ && nap-waf.sh \ && rm -f /etc/yum.repos.d/app-protect-9.repo; \ - ; fi \ + fi \ && subscription-manager unregister \ && microdnf remove -y shadow-utils subscription-manager \ && microdnf clean all && rm -rf /var/cache/dnf \ From 75b78aec09a17fe74864713c2ad120da75e0f566 Mon Sep 17 00:00:00 2001 From: Eoin O'Shaughnessy Date: Wed, 12 Jun 2024 13:36:49 +0100 Subject: [PATCH 34/34] explicit v4 dir for waf bundles --- charts/nginx-ingress/values.yaml | 5 +++-- cmd/nginx-ingress/main.go | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/charts/nginx-ingress/values.yaml b/charts/nginx-ingress/values.yaml index efb7adb6c9..ea91a10a12 100644 --- a/charts/nginx-ingress/values.yaml +++ b/charts/nginx-ingress/values.yaml @@ -56,7 +56,7 @@ controller: ## The pull policy for the App Protect WAF v5 Enforcer image. pullPolicy: IfNotPresent - # securityContext: {} + securityContext: {} ## Configuration for App Protect WAF v5 Configuration Manager configManager: @@ -229,7 +229,8 @@ controller: type: RuntimeDefault ## The security context for the Ingress Controller containers. - securityContext: {} # Remove curly brackets before adding values + securityContext: + {} # Remove curly brackets before adding values # allowPrivilegeEscalation: true # readOnlyRootFilesystem: true # runAsUser: 101 #nginx diff --git a/cmd/nginx-ingress/main.go b/cmd/nginx-ingress/main.go index 8d3c46897d..d911d2f818 100644 --- a/cmd/nginx-ingress/main.go +++ b/cmd/nginx-ingress/main.go @@ -53,7 +53,7 @@ const ( appProtectVersionLabel = "appprotect.f5.com/version" agentVersionLabel = "app.nginx.org/agent-version" appProtectVersionPath = "/opt/app_protect/RELEASE" - appProtectBundleFolder = "/etc/nginx/waf/bundles/" + appProtectv4BundleFolder = "/etc/nginx/waf/bundles/" appProtectv5BundleFolder = "/etc/app_protect/bundles/" ) @@ -84,7 +84,7 @@ func main() { var appProtectVersion string var appProtectV5 bool - appProtectBundlePath := appProtectBundleFolder + appProtectBundlePath := appProtectv4BundleFolder if *appProtect { appProtectVersion = getAppProtectVersionInfo()