From ae0c8248664867084216121fdfc0a94eea68c6d1 Mon Sep 17 00:00:00 2001 From: Alex Fenlon Date: Tue, 21 Apr 2026 12:36:49 +0100 Subject: [PATCH 01/23] WAF + Agent v3 --- .github/data/matrix-images-nap.json | 57 +- .github/data/matrix-smoke-nap.json | 8 + .github/workflows/build-plus.yml | 2 +- Makefile | 69 +- build/Dockerfile | 314 +++++-- charts/nginx-ingress/templates/_helpers.tpl | 16 +- charts/tests/__snapshots__/helmunit_test.snap | 853 +++++++++++++++--- charts/tests/helmunit_test.go | 5 + .../testdata/app-protect-wafv5-agentv3.yaml | 25 + .../app-protect-waf-v5/ingress.yaml | 19 + .../security-monitoring-v5/README.md | 112 +++ .../security-monitoring-v5/syslog.yaml | 32 + .../virtual-server.yaml | 16 + .../security-monitoring-v5/waf.yaml | 12 + .../security-monitoring-v5/webapp.yaml | 32 + .../security-monitoring-v5/README.md | 128 +++ .../security-monitoring-v5/cafe-ingress.yaml | 30 + .../security-monitoring-v5/cafe-secret.yaml | 8 + .../security-monitoring-v5/cafe.yaml | 66 ++ .../security-monitoring-v5/syslog.yaml | 32 + .../security-monitoring-v5/waf.yaml | 12 + 21 files changed, 1657 insertions(+), 191 deletions(-) create mode 100644 charts/tests/testdata/app-protect-wafv5-agentv3.yaml create mode 100644 examples/custom-resources/app-protect-waf-v5/ingress.yaml create mode 100644 examples/custom-resources/security-monitoring-v5/README.md create mode 100644 examples/custom-resources/security-monitoring-v5/syslog.yaml create mode 100644 examples/custom-resources/security-monitoring-v5/virtual-server.yaml create mode 100644 examples/custom-resources/security-monitoring-v5/waf.yaml create mode 100644 examples/custom-resources/security-monitoring-v5/webapp.yaml create mode 100644 examples/ingress-resources/security-monitoring-v5/README.md create mode 100644 examples/ingress-resources/security-monitoring-v5/cafe-ingress.yaml create mode 100644 examples/ingress-resources/security-monitoring-v5/cafe-secret.yaml create mode 100644 examples/ingress-resources/security-monitoring-v5/cafe.yaml create mode 100644 examples/ingress-resources/security-monitoring-v5/syslog.yaml create mode 100644 examples/ingress-resources/security-monitoring-v5/waf.yaml diff --git a/.github/data/matrix-images-nap.json b/.github/data/matrix-images-nap.json index 6e55cd2a0c..57cfd40483 100644 --- a/.github/data/matrix-images-nap.json +++ b/.github/data/matrix-images-nap.json @@ -1,6 +1,7 @@ { "image": [ - "debian-plus-nap" + "debian-plus-nap", + "debian-plus-nap-agent" ], "platforms": [ "linux/amd64" @@ -20,53 +21,107 @@ "platforms": "linux/amd64", "nap_modules": "waf" }, + { + "image": "ubi-8-plus-nap-agent", + "target": "goreleaser", + "platforms": "linux/amd64", + "nap_modules": "waf" + }, { "image": "ubi-8-plus-nap-v5", "target": "goreleaser", "platforms": "linux/amd64", "nap_modules": "waf" }, + { + "image": "ubi-8-plus-nap-v5-agent", + "target": "goreleaser", + "platforms": "linux/amd64", + "nap_modules": "waf" + }, { "image": "ubi-9-plus-nap", "target": "goreleaser", "platforms": "linux/amd64", "nap_modules": "waf" }, + { + "image": "ubi-9-plus-nap-agent", + "target": "goreleaser", + "platforms": "linux/amd64", + "nap_modules": "waf" + }, { "image": "ubi-9-plus-nap", "target": "goreleaser", "platforms": "linux/amd64", "nap_modules": "dos" }, + { + "image": "ubi-9-plus-nap-agent", + "target": "goreleaser", + "platforms": "linux/amd64", + "nap_modules": "dos" + }, { "image": "ubi-9-plus-nap", "target": "goreleaser", "platforms": "linux/amd64", "nap_modules": "waf,dos" }, + { + "image": "ubi-9-plus-nap-agent", + "target": "goreleaser", + "platforms": "linux/amd64", + "nap_modules": "waf,dos" + }, { "image": "alpine-plus-nap-fips", "target": "goreleaser", "platforms": "linux/amd64", "nap_modules": "waf" }, + { + "image": "alpine-plus-nap-fips-agent", + "target": "goreleaser", + "platforms": "linux/amd64", + "nap_modules": "waf" + }, { "image": "alpine-plus-nap-v5-fips", "target": "goreleaser", "platforms": "linux/amd64", "nap_modules": "waf" }, + { + "image": "alpine-plus-nap-v5-fips-agent", + "target": "goreleaser", + "platforms": "linux/amd64", + "nap_modules": "waf" + }, { "image": "debian-plus-nap-v5", "target": "goreleaser", "platforms": "linux/amd64", "nap_modules": "waf" }, + { + "image": "debian-plus-nap-v5-agent", + "target": "goreleaser", + "platforms": "linux/amd64", + "nap_modules": "waf" + }, { "image": "ubi-9-plus-nap-v5", "target": "goreleaser", "platforms": "linux/amd64", "nap_modules": "waf" + }, + { + "image": "ubi-9-plus-nap-v5-agent", + "target": "goreleaser", + "platforms": "linux/amd64", + "nap_modules": "waf" } ] } diff --git a/.github/data/matrix-smoke-nap.json b/.github/data/matrix-smoke-nap.json index 652492ba7b..ae0bfcceae 100644 --- a/.github/data/matrix-smoke-nap.json +++ b/.github/data/matrix-smoke-nap.json @@ -71,6 +71,14 @@ "nap_modules": "waf", "marker": "agentv2", "platforms": "linux/amd64" + }, + { + "label": "AGENT_V3_NAP 1/1", + "image": "debian-plus-nap-agent", + "type": "plus", + "nap_modules": "waf", + "marker": "agentv3", + "platforms": "linux/amd64" } ], "k8s": [] diff --git a/.github/workflows/build-plus.yml b/.github/workflows/build-plus.yml index 9fca6fd75e..3c5f7bd5b6 100644 --- a/.github/workflows/build-plus.yml +++ b/.github/workflows/build-plus.yml @@ -169,7 +169,7 @@ jobs: 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' || '' }}${{ contains(inputs.image, 'v5') && '-v5' || '' }}/nginx-plus-ingress flavor: | - suffix=${{ contains(inputs.image, 'ubi-9') && '-ubi' || '' }}${{ contains(inputs.image, 'ubi-8') && '-ubi8' || '' }}${{ contains(inputs.image, 'alpine') && '-alpine' || '' }}${{ contains(inputs.target, 'aws') && '-mktpl' || '' }}${{ contains(inputs.image, 'fips') && '-fips' || ''}} + suffix=${{ contains(inputs.image, 'ubi-9') && '-ubi' || '' }}${{ contains(inputs.image, 'ubi-8') && '-ubi8' || '' }}${{ contains(inputs.image, 'alpine') && '-alpine' || '' }}${{ contains(inputs.target, 'aws') && '-mktpl' || '' }}${{ contains(inputs.image, 'fips') && '-fips' || ''}}${{ contains(inputs.image, 'agent') && '-agent' || '' }} tags: | type=raw,value=${{ inputs.tag }} labels: | diff --git a/Makefile b/Makefile index aa491af3bb..c240bf0cfa 100644 --- a/Makefile +++ b/Makefile @@ -222,7 +222,8 @@ debian-image-nap-v5-plus: build ## Create Docker image for Ingress Controller (D .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 + $(DOCKER_CMD) $(PLUS_ARGS) --build-arg BUILD_OS=debian-plus-nap-agent --build-arg NAP_MODULES=dos \ + --build-arg NGINX_AGENT_VERSION=$(NGINX_AGENT_VERSION) .PHONY: debian-image-nap-dos-plus debian-image-nap-dos-plus: build ## Create Docker image for Ingress Controller (Debian with NGINX Plus, NGINX App Protect WAF and DoS) @@ -260,18 +261,78 @@ ubi8-image-nap-v5-plus: build ## Create Docker image for Ingress Controller (UBI .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-9-plus-nap \ - --build-arg NAP_MODULES=dos + $(DOCKER_CMD) $(PLUS_ARGS) --secret id=rhel_license,src=rhel_license --build-arg BUILD_OS=ubi-9-plus-nap-agent \ + --build-arg NAP_MODULES=dos --build-arg NGINX_AGENT_VERSION=$(NGINX_AGENT_VERSION) .PHONY: ubi-image-nap-dos-plus 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-9-plus-nap \ --build-arg NAP_MODULES=waf,dos --build-arg NAP_WAF_VERSION=$(NAP_WAF_VERSION) --build-arg NAP_AGENT_VERSION=$(NAP_AGENT_VERSION) +.PHONY: alpine-image-nap-plus-fips-agent +alpine-image-nap-plus-fips-agent: build ## Create Docker image for Ingress Controller (Alpine with NGINX Plus, NGINX App Protect WAF, FIPS and Agent v3) + $(DOCKER_CMD) $(PLUS_ARGS) --build-arg BUILD_OS=alpine-plus-nap-fips-agent --build-arg NAP_WAF_VERSION=$(NAP_WAF_VERSION) \ + --build-arg NAP_AGENT_VERSION=$(NAP_AGENT_VERSION) --build-arg NGINX_AGENT_VERSION=$(NGINX_AGENT_VERSION) + +.PHONY: alpine-image-nap-v5-plus-fips-agent +alpine-image-nap-v5-plus-fips-agent: build ## Create Docker image for Ingress Controller (Alpine with NGINX Plus, NGINX App Protect WAFv5, FIPS and Agent v3) + $(DOCKER_CMD) $(PLUS_ARGS) --build-arg BUILD_OS=alpine-plus-nap-v5-fips-agent --build-arg NAP_WAF_VERSION=$(NAP_WAF_VERSION) \ + --build-arg NAP_AGENT_VERSION=$(NAP_AGENT_VERSION) --build-arg NGINX_AGENT_VERSION=$(NGINX_AGENT_VERSION) + +.PHONY: debian-image-nap-plus-agent +debian-image-nap-plus-agent: build ## Create Docker image for Ingress Controller (Debian with NGINX Plus, NGINX App Protect WAF and Agent v3) + $(DOCKER_CMD) $(PLUS_ARGS) --build-arg BUILD_OS=debian-plus-nap-agent --build-arg NAP_MODULES=waf \ + --build-arg NAP_WAF_VERSION=$(NAP_WAF_VERSION) --build-arg NAP_WAF_PLUGIN_VERSION=$(NAP_WAF_PLUGIN_VERSION) \ + --build-arg NAP_WAF_COMMON_VERSION=$(NAP_WAF_COMMON_VERSION) --build-arg NAP_AGENT_VERSION=$(NAP_AGENT_VERSION) \ + --build-arg NGINX_AGENT_VERSION=$(NGINX_AGENT_VERSION) + +.PHONY: debian-image-nap-v5-plus-agent +debian-image-nap-v5-plus-agent: build ## Create Docker image for Ingress Controller (Debian with NGINX Plus, NGINX App Protect WAFv5 and Agent v3) + $(DOCKER_CMD) $(PLUS_ARGS) --build-arg BUILD_OS=debian-plus-nap-v5-agent --build-arg NAP_WAF_VERSION=$(NAP_WAF_VERSION) \ + --build-arg NAP_WAF_PLUGIN_VERSION=$(NAP_WAF_PLUGIN_VERSION) --build-arg NAP_AGENT_VERSION=$(NAP_AGENT_VERSION) \ + --build-arg NGINX_AGENT_VERSION=$(NGINX_AGENT_VERSION) + +.PHONY: debian-image-nap-dos-plus-agent +debian-image-nap-dos-plus-agent: build ## Create Docker image for Ingress Controller (Debian with NGINX Plus, NGINX App Protect WAF, DoS and Agent v3) + $(DOCKER_CMD) $(PLUS_ARGS) --build-arg BUILD_OS=debian-plus-nap-agent --build-arg NAP_MODULES=waf,dos \ + --build-arg NAP_WAF_VERSION=$(NAP_WAF_VERSION) --build-arg NAP_WAF_PLUGIN_VERSION=$(NAP_WAF_PLUGIN_VERSION) \ + --build-arg NAP_WAF_COMMON_VERSION=$(NAP_WAF_COMMON_VERSION) --build-arg NAP_AGENT_VERSION=$(NAP_AGENT_VERSION) \ + --build-arg NGINX_AGENT_VERSION=$(NGINX_AGENT_VERSION) + +.PHONY: ubi-image-nap-plus-agent +ubi-image-nap-plus-agent: build ## Create Docker image for Ingress Controller (UBI with NGINX Plus, NGINX App Protect WAF and Agent v3) + $(DOCKER_CMD) $(PLUS_ARGS) --secret id=rhel_license,src=rhel_license --build-arg BUILD_OS=ubi-9-plus-nap-agent \ + --build-arg NAP_MODULES=waf --build-arg NAP_WAF_VERSION=$(NAP_WAF_VERSION) --build-arg NAP_AGENT_VERSION=$(NAP_AGENT_VERSION) \ + --build-arg NGINX_AGENT_VERSION=$(NGINX_AGENT_VERSION) + +.PHONY: ubi8-image-nap-plus-agent +ubi8-image-nap-plus-agent: build ## Create Docker image for Ingress Controller (UBI8 with NGINX Plus, NGINX App Protect WAF and Agent v3) + $(DOCKER_CMD) $(PLUS_ARGS) --secret id=rhel_license,src=rhel_license --build-arg BUILD_OS=ubi-8-plus-nap-agent \ + --build-arg NAP_MODULES=waf --build-arg NAP_WAF_VERSION=$(NAP_WAF_VERSION) --build-arg NAP_AGENT_VERSION=$(NAP_AGENT_VERSION) \ + --build-arg NGINX_AGENT_VERSION=$(NGINX_AGENT_VERSION) + +.PHONY: ubi-image-nap-v5-plus-agent +ubi-image-nap-v5-plus-agent: build ## Create Docker image for Ingress Controller (UBI with NGINX Plus, NGINX App Protect WAFv5 and Agent v3) + $(DOCKER_CMD) $(PLUS_ARGS) --secret id=rhel_license,src=rhel_license \ + --build-arg BUILD_OS=ubi-9-plus-nap-v5-agent --build-arg NAP_WAF_VERSION=$(NAP_WAF_VERSION) \ + --build-arg NAP_AGENT_VERSION=$(NAP_AGENT_VERSION) --build-arg NGINX_AGENT_VERSION=$(NGINX_AGENT_VERSION) + +.PHONY: ubi8-image-nap-v5-plus-agent +ubi8-image-nap-v5-plus-agent: build ## Create Docker image for Ingress Controller (UBI8 with NGINX Plus, NGINX App Protect WAFv5 and Agent v3) + $(DOCKER_CMD) $(PLUS_ARGS) --secret id=rhel_license,src=rhel_license \ + --build-arg BUILD_OS=ubi-8-plus-nap-v5-agent --build-arg NAP_WAF_VERSION=$(NAP_WAF_VERSION) \ + --build-arg NAP_AGENT_VERSION=$(NAP_AGENT_VERSION) --build-arg NGINX_AGENT_VERSION=$(NGINX_AGENT_VERSION) + +.PHONY: ubi-image-nap-dos-plus-agent +ubi-image-nap-dos-plus-agent: build ## Create Docker image for Ingress Controller (UBI with NGINX Plus, NGINX App Protect WAF, DoS and Agent v3) + $(DOCKER_CMD) $(PLUS_ARGS) --secret id=rhel_license,src=rhel_license --build-arg BUILD_OS=ubi-9-plus-nap-agent \ + --build-arg NAP_MODULES=waf,dos --build-arg NAP_WAF_VERSION=$(NAP_WAF_VERSION) --build-arg NAP_AGENT_VERSION=$(NAP_AGENT_VERSION) \ + --build-arg NGINX_AGENT_VERSION=$(NGINX_AGENT_VERSION) + .PHONY: all-images ## Create all the Docker images for Ingress Controller all-images: docker builder prune -af; \ - images="alpine-image alpine-image-nap-plus-fips alpine-image-nap-v5-plus-fips alpine-image-plus alpine-image-plus-fips debian-image debian-image-dos-plus debian-image-nap-dos-plus debian-image-nap-plus debian-image-nap-v5-plus debian-image-plus ubi-image ubi-image-dos-plus ubi-image-nap-dos-plus ubi-image-nap-plus ubi-image-nap-v5-plus ubi-image-plus ubi8-image-nap-v5-plus"; \ + images="alpine-image alpine-image-nap-plus-fips alpine-image-nap-plus-fips-agent alpine-image-nap-v5-plus-fips alpine-image-nap-v5-plus-fips-agent alpine-image-plus alpine-image-plus-fips debian-image debian-image-dos-plus debian-image-nap-dos-plus debian-image-nap-dos-plus-agent debian-image-nap-plus debian-image-nap-plus-agent debian-image-nap-v5-plus debian-image-nap-v5-plus-agent debian-image-plus ubi-image ubi-image-dos-plus ubi-image-nap-dos-plus ubi-image-nap-dos-plus-agent ubi-image-nap-plus ubi-image-nap-plus-agent ubi-image-nap-v5-plus ubi-image-nap-v5-plus-agent ubi-image-plus ubi8-image-nap-plus-agent ubi8-image-nap-v5-plus ubi8-image-nap-v5-plus-agent"; \ for img in $$images; do \ TAG="$(strip $(TAG))-$$img" make $$img; \ done diff --git a/build/Dockerfile b/build/Dockerfile index aac1e02c76..a31b0c511d 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -211,12 +211,11 @@ RUN --mount=type=bind,from=alpine-fips-3.22,target=/tmp/fips/ \ && cp -av /tmp/nginx/reporting/tracking.info /etc/nginx/reporting/tracking.info -############################################# Base image for Alpine with NGINX Plus, App Protect WAF and FIPS ############################################# -FROM alpine:3.22@sha256:55ae5d250caebc548793f321534bc6a8ef1d116f334f18f4ada1b2daad3251b2 AS alpine-plus-nap-fips +############################################# Base image for Alpine with NGINX Plus, App Protect WAF and FIPS (no agent) ############################################# +FROM alpine:3.22@sha256:55ae5d250caebc548793f321534bc6a8ef1d116f334f18f4ada1b2daad3251b2 AS alpine-plus-nap-fips-base ARG NGINX_PLUS_VERSION ARG NAP_WAF_VERSION ARG PACKAGE_REPO -ARG NAP_AGENT_VERSION ENV NGINX_VERSION=${NGINX_PLUS_VERSION} @@ -225,15 +224,12 @@ RUN --mount=type=bind,from=alpine-fips-3.22,target=/tmp/fips/ \ --mount=type=secret,id=nginx-repo.key,dst=/etc/apk/cert.key,mode=0644 \ --mount=type=bind,from=nginx-files,src=app-protect-security-updates.rsa.pub,target=/etc/apk/keys/app-protect-security-updates.rsa.pub \ --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 \ --mount=type=bind,from=nginx-files,src=tracking.info,target=/tmp/nginx/reporting/tracking.info \ printf "%s\n" "https://${PACKAGE_REPO}/plus/${NGINX_PLUS_VERSION}/alpine/v$(grep -E -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ && printf "%s\n" "https://${PACKAGE_REPO}/app-protect/${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-security-updates/alpine/v$(grep -E -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ - && printf "%s\n" "https://${PACKAGE_REPO}/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-otel nginx-plus-module-fips-check \ - && apk add --no-cache nginx-agent~${NAP_AGENT_VERSION} \ && 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 \ @@ -242,16 +238,44 @@ RUN --mount=type=bind,from=alpine-fips-3.22,target=/tmp/fips/ \ && cp -av /tmp/nginx/reporting/tracking.info /etc/nginx/reporting/tracking.info \ && apk add --no-cache app-protect~=${NAP_WAF_VERSION/+/.} app-protect-attack-signatures app-protect-threat-campaigns \ && sed -i -e '/nginx.com/d' /etc/apk/repositories \ - && nap-waf.sh \ - agent.sh + && nap-waf.sh -############################################# Base image for Alpine with NGINX Plus, App Protect WAFv5 and FIPS ############################################# -FROM alpine:3.22@sha256:55ae5d250caebc548793f321534bc6a8ef1d116f334f18f4ada1b2daad3251b2 AS alpine-plus-nap-v5-fips +############################################# Base image for Alpine with NGINX Plus, App Protect WAF and FIPS ############################################# +FROM alpine-plus-nap-fips-base AS alpine-plus-nap-fips +ARG NAP_AGENT_VERSION +ARG PACKAGE_REPO + +RUN --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=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 \ + printf "%s\n" "https://${PACKAGE_REPO}/nginx-agent/alpine/v$(grep -E -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ + && apk add --no-cache nginx-agent~${NAP_AGENT_VERSION} \ + && sed -i -e '/nginx.com/d' /etc/apk/repositories \ + && agent.sh + + +############################################# Base image for Alpine with NGINX Plus, App Protect WAF, FIPS and Agent v3 ############################################# +FROM alpine-plus-nap-fips-base AS alpine-plus-nap-fips-agent +ARG NGINX_AGENT_VERSION +ARG PACKAGE_REPO + +RUN --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=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 \ + printf "%s\n" "https://${PACKAGE_REPO}/nginx-agent/alpine/v$(grep -E -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ + && apk add --no-cache nginx-agent~${NGINX_AGENT_VERSION} \ + && sed -i -e '/nginx.com/d' /etc/apk/repositories \ + && agent.sh + + +############################################# Base image for Alpine with NGINX Plus, App Protect WAFv5 and FIPS (no agent) ############################################# +FROM alpine:3.22@sha256:55ae5d250caebc548793f321534bc6a8ef1d116f334f18f4ada1b2daad3251b2 AS alpine-plus-nap-v5-fips-base ARG NGINX_PLUS_VERSION ARG PACKAGE_REPO ARG NAP_WAF_VERSION -ARG NAP_AGENT_VERSION ENV NGINX_VERSION=${NGINX_PLUS_VERSION} @@ -259,14 +283,11 @@ RUN --mount=type=bind,from=alpine-fips-3.22,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=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 \ --mount=type=bind,from=nginx-files,src=tracking.info,target=/tmp/nginx/reporting/tracking.info \ printf "%s\n" "https://${PACKAGE_REPO}/plus/${NGINX_PLUS_VERSION}/alpine/v$(grep -E -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ && printf "%s\n" "https://${PACKAGE_REPO}/app-protect-x-plus/alpine/v$(grep -E -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ - && printf "%s\n" "https://${PACKAGE_REPO}/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-otel nginx-plus-module-fips-check \ - && apk add --no-cache nginx-agent~${NAP_AGENT_VERSION} \ && 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 \ @@ -275,8 +296,37 @@ RUN --mount=type=bind,from=alpine-fips-3.22,target=/tmp/fips/ \ && cp -av /tmp/nginx/reporting/tracking.info /etc/nginx/reporting/tracking.info \ && apk add --no-cache app-protect-module-plus~=${NAP_WAF_VERSION/+/.} \ && sed -i -e '/nginx.com/d' /etc/apk/repositories \ - && nap-waf.sh \ - agent.sh + && nap-waf.sh + + +############################################# Base image for Alpine with NGINX Plus, App Protect WAFv5 and FIPS ############################################# +FROM alpine-plus-nap-v5-fips-base AS alpine-plus-nap-v5-fips +ARG NAP_AGENT_VERSION +ARG PACKAGE_REPO + +RUN --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=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 \ + printf "%s\n" "https://${PACKAGE_REPO}/nginx-agent/alpine/v$(grep -E -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ + && apk add --no-cache nginx-agent~${NAP_AGENT_VERSION} \ + && sed -i -e '/nginx.com/d' /etc/apk/repositories \ + && agent.sh + + +############################################# Base image for Alpine with NGINX Plus, App Protect WAFv5, FIPS and Agent v3 ############################################# +FROM alpine-plus-nap-v5-fips-base AS alpine-plus-nap-v5-fips-agent +ARG NGINX_AGENT_VERSION +ARG PACKAGE_REPO + +RUN --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=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 \ + printf "%s\n" "https://${PACKAGE_REPO}/nginx-agent/alpine/v$(grep -E -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ + && apk add --no-cache nginx-agent~${NGINX_AGENT_VERSION} \ + && sed -i -e '/nginx.com/d' /etc/apk/repositories \ + && agent.sh ############################################# Base image for Debian with NGINX Plus only ############################################# @@ -328,14 +378,13 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode && agent.sh \ && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx-agent.sources -############################################# Base image for Debian with NGINX Plus and App Protect WAF/DoS ############################################# -FROM debian-plus-only AS debian-plus-nap +############################################# Base image for Debian with NGINX Plus and App Protect WAF/DoS (no agent) ############################################# +FROM debian-plus-only AS debian-plus-nap-base ARG NAP_MODULES ARG NGINX_PLUS_VERSION ARG NAP_WAF_VERSION ARG NAP_WAF_COMMON_VERSION ARG NAP_WAF_PLUGIN_VERSION -ARG NAP_AGENT_VERSION ENV NGINX_VERSION=${NGINX_PLUS_VERSION} @@ -344,13 +393,10 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode --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-12.sources,target=/tmp/app-protect.sources \ --mount=type=bind,from=nginx-files,src=nap-dos-12.sources,target=/tmp/app-protect-dos.sources \ - --mount=type=bind,from=nginx-files,src=debian-agent-12.sources,target=/tmp/nginx-agent.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=nap-dos.sh,target=/usr/local/bin/nap-dos.sh \ if [ -z "${NAP_MODULES##*waf*}" ]; then \ cp /tmp/app-protect.sources /etc/apt/sources.list.d/app-protect.sources \ - && cp /tmp/nginx-agent.sources /etc/apt/sources.list.d/nginx-agent.sources \ && apt-get update \ && apt-get install --no-install-recommends --no-install-suggests -y app-protect=${NAP_WAF_VERSION}* \ nginx-plus-module-appprotect=${NAP_WAF_VERSION}* \ @@ -360,10 +406,8 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode app-protect-plugin=${NAP_WAF_PLUGIN_VERSION}* \ app-protect-attack-signatures \ app-protect-threat-campaigns \ - nginx-agent=${NAP_AGENT_VERSION}.* \ - && rm -f /etc/apt/sources.list.d/app-protect.sources /etc/apt/sources.list.d/nginx-agent.sources \ - && nap-waf.sh \ - && agent.sh; \ + && rm -f /etc/apt/sources.list.d/app-protect.sources \ + && nap-waf.sh; \ fi \ && if [ -z "${NAP_MODULES##*dos*}" ]; then \ cp /tmp/app-protect-dos.sources /etc/apt/sources.list.d/app-protect-dos.sources \ @@ -374,12 +418,41 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode fi \ && rm -rf /var/lib/apt/lists/* -############################################# Base image for Debian with NGINX Plus and App Protect WAFv5 ############################################# -FROM debian-plus-only AS debian-plus-nap-v5 +############################################# Base image for Debian with NGINX Plus and App Protect WAF/DoS ############################################# +FROM debian-plus-nap-base AS debian-plus-nap +ARG NAP_AGENT_VERSION + +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=debian-agent-12.sources,target=/tmp/nginx-agent.sources \ + --mount=type=bind,from=nginx-files,src=agent.sh,target=/usr/local/bin/agent.sh \ + cp /tmp/nginx-agent.sources /etc/apt/sources.list.d/nginx-agent.sources \ + && apt-get update \ + && apt-get install --no-install-recommends --no-install-suggests -y nginx-agent=${NAP_AGENT_VERSION}.* \ + && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx-agent.sources \ + && agent.sh + +############################################# Base image for Debian with NGINX Plus, App Protect WAF/DoS and Agent v3 ############################################# +FROM debian-plus-nap-base AS debian-plus-nap-agent +ARG NGINX_AGENT_VERSION + +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=debian-agent-12.sources,target=/tmp/nginx-agent.sources \ + --mount=type=bind,from=nginx-files,src=agent.sh,target=/usr/local/bin/agent.sh \ + cp /tmp/nginx-agent.sources /etc/apt/sources.list.d/nginx-agent.sources \ + && apt-get update \ + && apt-get install --no-install-recommends --no-install-suggests -y nginx-agent=${NGINX_AGENT_VERSION}* \ + && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx-agent.sources \ + && agent.sh + +############################################# Base image for Debian with NGINX Plus and App Protect WAFv5 (no agent) ############################################# +FROM debian-plus-only AS debian-plus-nap-v5-base ARG NGINX_PLUS_VERSION ARG NAP_WAF_VERSION ARG NAP_WAF_PLUGIN_VERSION -ARG NAP_AGENT_VERSION ENV NGINX_VERSION=${NGINX_PLUS_VERSION} @@ -387,12 +460,41 @@ 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=/etc/apt/sources.list.d/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-12.sources,target=/etc/apt/sources.list.d/nginx-agent.sources \ apt-get update \ - && apt-get install --no-install-recommends --no-install-suggests -y nginx-agent=${NAP_AGENT_VERSION}.* app-protect-module-plus=${NAP_WAF_VERSION}* nginx-plus-module-appprotect=${NAP_WAF_VERSION}* app-protect-plugin=${NAP_WAF_PLUGIN_VERSION}* \ - && nap-waf.sh \ + && apt-get install --no-install-recommends --no-install-suggests -y app-protect-module-plus=${NAP_WAF_VERSION}* nginx-plus-module-appprotect=${NAP_WAF_VERSION}* app-protect-plugin=${NAP_WAF_PLUGIN_VERSION}* \ + && nap-waf.sh + + +############################################# Base image for Debian with NGINX Plus and App Protect WAFv5 ############################################# +FROM debian-plus-nap-v5-base AS debian-plus-nap-v5 +ARG NAP_AGENT_VERSION + +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=debian-agent-12.sources,target=/tmp/nginx-agent.sources \ + --mount=type=bind,from=nginx-files,src=agent.sh,target=/usr/local/bin/agent.sh \ + cp /tmp/nginx-agent.sources /etc/apt/sources.list.d/nginx-agent.sources \ + && apt-get update \ + && apt-get install --no-install-recommends --no-install-suggests -y nginx-agent=${NAP_AGENT_VERSION}.* \ + && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx-agent.sources \ + && agent.sh + + +############################################# Base image for Debian with NGINX Plus, App Protect WAFv5 and Agent v3 ############################################# +FROM debian-plus-nap-v5-base AS debian-plus-nap-v5-agent +ARG NGINX_AGENT_VERSION + +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=debian-agent-12.sources,target=/tmp/nginx-agent.sources \ + --mount=type=bind,from=nginx-files,src=agent.sh,target=/usr/local/bin/agent.sh \ + cp /tmp/nginx-agent.sources /etc/apt/sources.list.d/nginx-agent.sources \ + && apt-get update \ + && apt-get install --no-install-recommends --no-install-suggests -y nginx-agent=${NGINX_AGENT_VERSION}* \ + && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx-agent.sources \ && agent.sh @@ -422,13 +524,12 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode && ubi-clean.sh -############################################# Base image for UBI with NGINX Plus and App Protect WAF & DoS ############################################# -FROM ubi-minimal AS ubi-9-plus-nap +############################################# Base image for UBI with NGINX Plus and App Protect WAF & DoS (no agent) ############################################# +FROM ubi-minimal AS ubi-9-plus-nap-base ARG NAP_MODULES ARG BUILD_OS ARG NGINX_PLUS_VERSION ARG NAP_WAF_VERSION -ARG NAP_AGENT_VERSION ENV NGINX_VERSION=${NGINX_PLUS_VERSION} @@ -437,12 +538,10 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode --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 \ - --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-security-updates.key,target=/tmp/app-protect-security-updates.key \ --mount=type=bind,from=nginx-files,src=app-protect-9.repo,target=/tmp/app-protect-9.repo \ --mount=type=bind,from=nginx-files,src=app-protect-dos-9.repo,target=/tmp/app-protect-dos-9.repo \ --mount=type=bind,from=nginx-files,src=ubi-setup.sh,target=/usr/local/bin/ubi-setup.sh \ - --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=nap-dos.sh,target=/usr/local/bin/nap-dos.sh \ --mount=type=bind,from=nginx-files,src=ubi-clean.sh,target=/usr/local/bin/ubi-clean.sh \ @@ -451,7 +550,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode mkdir -p /etc/nginx/reporting/ && cp -av /tmp/nginx/reporting/tracking.info /etc/nginx/reporting/tracking.info \ && ubi-setup.sh \ && rpm -Uvh /ubi-bin/c-ares-*.rpm \ - && microdnf --nodocs install -y nginx-plus nginx-plus-module-njs nginx-plus-module-fips-check nginx-plus-module-otel nginx-agent-${NAP_AGENT_VERSION}.* \ + && microdnf --nodocs install -y nginx-plus nginx-plus-module-njs nginx-plus-module-fips-check nginx-plus-module-otel \ && source /tmp/rhel_license \ && microdnf --nodocs install -y ca-certificates shadow-utils subscription-manager \ && rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm \ @@ -463,8 +562,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode && microdnf --enablerepo=codeready-builder-for-rhel-9-x86_64-rpms --nodocs install -y \ app-protect-${NAP_WAF_VERSION}* app-protect-attack-signatures app-protect-threat-campaigns \ && rm -f /etc/yum.repos.d/app-protect-9.repo \ - && nap-waf.sh \ - && agent.sh; \ + && nap-waf.sh; \ fi \ && if [ -z "${NAP_MODULES##*dos*}" ]; then \ cp /tmp/app-protect-dos-9.repo /etc/yum.repos.d/app-protect-dos-9.repo \ @@ -476,11 +574,36 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode && ubi-clean.sh -############################################# Base image for UBI with NGINX Plus and App Protect WAFv5 ############################################# -FROM ubi-minimal AS ubi-9-plus-nap-v5 +############################################# Base image for UBI with NGINX Plus and App Protect WAF & DoS ############################################# +FROM ubi-9-plus-nap-base AS ubi-9-plus-nap +ARG NAP_AGENT_VERSION + +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=nginx-agent.repo,target=/etc/yum.repos.d/nginx-agent.repo,rw \ + --mount=type=bind,from=nginx-files,src=agent.sh,target=/usr/local/bin/agent.sh \ + microdnf --nodocs install -y nginx-agent-${NAP_AGENT_VERSION}.* \ + && microdnf clean all \ + && agent.sh + + +############################################# Base image for UBI with NGINX Plus, App Protect WAF/DoS and Agent v3 ############################################# +FROM ubi-9-plus-nap-base AS ubi-9-plus-nap-agent +ARG NGINX_AGENT_VERSION + +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=nginx-agent.repo,target=/etc/yum.repos.d/nginx-agent.repo,rw \ + --mount=type=bind,from=nginx-files,src=agent.sh,target=/usr/local/bin/agent.sh \ + microdnf --nodocs install -y nginx-agent-${NGINX_AGENT_VERSION}.* \ + && microdnf clean all \ + && agent.sh + + +############################################# Base image for UBI with NGINX Plus and App Protect WAFv5 (no agent) ############################################# +FROM ubi-minimal AS ubi-9-plus-nap-v5-base ARG NGINX_PLUS_VERSION ARG NAP_WAF_VERSION -ARG NAP_AGENT_VERSION ENV NGINX_VERSION=${NGINX_PLUS_VERSION} @@ -489,10 +612,8 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode --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 \ - --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=/etc/yum.repos.d/app-protect-9.repo \ --mount=type=bind,from=nginx-files,src=ubi-setup.sh,target=/usr/local/bin/ubi-setup.sh \ - --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=ubi-clean.sh,target=/usr/local/bin/ubi-clean.sh \ --mount=type=bind,from=ubi9-packages,src=/,target=/ubi-bin/ \ @@ -504,18 +625,42 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode && rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm \ && rpm -Uvh /ubi-bin/c-ares-*.rpm \ && microdnf --nodocs install -y ca-certificates shadow-utils subscription-manager \ - && microdnf --nodocs install -y nginx-plus-module-otel nginx-agent-${NAP_AGENT_VERSION}.* app-protect-module-plus-${NAP_WAF_VERSION}* \ + && microdnf --nodocs install -y nginx-plus-module-otel app-protect-module-plus-${NAP_WAF_VERSION}* \ && nap-waf.sh \ - && ubi-clean.sh \ + && ubi-clean.sh + + +############################################# Base image for UBI with NGINX Plus and App Protect WAFv5 ############################################# +FROM ubi-9-plus-nap-v5-base AS ubi-9-plus-nap-v5 +ARG NAP_AGENT_VERSION + +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=nginx-agent.repo,target=/etc/yum.repos.d/nginx-agent.repo,rw \ + --mount=type=bind,from=nginx-files,src=agent.sh,target=/usr/local/bin/agent.sh \ + microdnf --nodocs install -y nginx-agent-${NAP_AGENT_VERSION}.* \ + && microdnf clean all \ && agent.sh -############################################# Base image for UBI8 with NGINX Plus and App Protect WAF ############################################# -FROM redhat/ubi8@sha256:10db73dc171cbb937023e2913745abd15c7b3d5c0f3877ddb104b45cd7eeb6b6 AS ubi-8-plus-nap +############################################# Base image for UBI with NGINX Plus, App Protect WAFv5 and Agent v3 ############################################# +FROM ubi-9-plus-nap-v5-base AS ubi-9-plus-nap-v5-agent +ARG NGINX_AGENT_VERSION + +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=nginx-agent.repo,target=/etc/yum.repos.d/nginx-agent.repo,rw \ + --mount=type=bind,from=nginx-files,src=agent.sh,target=/usr/local/bin/agent.sh \ + microdnf --nodocs install -y nginx-agent-${NGINX_AGENT_VERSION}.* \ + && microdnf clean all \ + && agent.sh + + +############################################# Base image for UBI8 with NGINX Plus and App Protect WAF (no agent) ############################################# +FROM redhat/ubi8@sha256:10db73dc171cbb937023e2913745abd15c7b3d5c0f3877ddb104b45cd7eeb6b6 AS ubi-8-plus-nap-base ARG NGINX_PLUS_VERSION ARG NAP_WAF_VERSION ARG BUILD_OS -ARG NAP_AGENT_VERSION ENV NGINX_VERSION=${NGINX_PLUS_VERSION} @@ -524,11 +669,9 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode --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-security-updates.key,target=/tmp/app-protect-security-updates.key \ --mount=type=bind,from=nginx-files,src=app-protect-8.repo,target=/etc/yum.repos.d/app-protect-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 \ --mount=type=bind,from=nginx-files,src=tracking.info,target=/tmp/nginx/reporting/tracking.info \ --mount=type=bind,from=ubi8-packages,src=/,target=/ubi-bin/ \ mkdir -p /etc/nginx/reporting/ && cp -av /tmp/nginx/reporting/tracking.info /etc/nginx/reporting/tracking.info \ @@ -538,7 +681,7 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode && rpm --import /tmp/nginx_signing.key \ && rpm --import /tmp/app-protect-security-updates.key \ && rpm -Uvh /ubi-bin/c-ares-*.rpm \ - && dnf --nodocs install -y nginx-plus nginx-plus-module-njs nginx-plus-module-otel nginx-plus-module-fips-check nginx-agent-${NAP_AGENT_VERSION}.* \ + && dnf --nodocs install -y nginx-plus nginx-plus-module-njs nginx-plus-module-otel nginx-plus-module-fips-check \ && 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} --name ${BUILD_OS}-$(uname -m) || true \ && subscription-manager attach \ @@ -547,15 +690,39 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode && dnf --nodocs install -y app-protect-${NAP_WAF_VERSION}* app-protect-attack-signatures app-protect-threat-campaigns \ && subscription-manager unregister \ && nap-waf.sh \ - && agent.sh \ && dnf clean all -############################################# Base image for UBI8 with NGINX Plus and App Protect WAFv5 ############################################# -FROM redhat/ubi8@sha256:10db73dc171cbb937023e2913745abd15c7b3d5c0f3877ddb104b45cd7eeb6b6 AS ubi-8-plus-nap-v5 +############################################# Base image for UBI8 with NGINX Plus and App Protect WAF ############################################# +FROM ubi-8-plus-nap-base AS ubi-8-plus-nap +ARG NAP_AGENT_VERSION + +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=nginx-agent.repo,target=/etc/yum.repos.d/nginx-agent.repo,rw \ + --mount=type=bind,from=nginx-files,src=agent.sh,target=/usr/local/bin/agent.sh \ + dnf --nodocs install -y nginx-agent-${NAP_AGENT_VERSION}.* \ + && dnf clean all \ + && agent.sh + + +############################################# Base image for UBI8 with NGINX Plus, App Protect WAF and Agent v3 ############################################# +FROM ubi-8-plus-nap-base AS ubi-8-plus-nap-agent +ARG NGINX_AGENT_VERSION + +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=nginx-agent.repo,target=/etc/yum.repos.d/nginx-agent.repo,rw \ + --mount=type=bind,from=nginx-files,src=agent.sh,target=/usr/local/bin/agent.sh \ + dnf --nodocs install -y nginx-agent-${NGINX_AGENT_VERSION}.* \ + && dnf clean all \ + && agent.sh + + +############################################# Base image for UBI8 with NGINX Plus and App Protect WAFv5 (no agent) ############################################# +FROM redhat/ubi8@sha256:10db73dc171cbb937023e2913745abd15c7b3d5c0f3877ddb104b45cd7eeb6b6 AS ubi-8-plus-nap-v5-base ARG NGINX_PLUS_VERSION ARG NAP_WAF_VERSION -ARG NAP_AGENT_VERSION ENV NGINX_VERSION=${NGINX_PLUS_VERSION} @@ -564,10 +731,8 @@ RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode --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=/etc/yum.repos.d/app-protect-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 \ --mount=type=bind,from=nginx-files,src=tracking.info,target=/tmp/nginx/reporting/tracking.info \ --mount=type=bind,from=ubi8-packages,src=/,target=/ubi-bin/ \ source /tmp/rhel_license \ @@ -577,13 +742,38 @@ 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 \ && rpm -Uvh /ubi-bin/c-ares-*.rpm \ - && dnf --nodocs install -y nginx-plus nginx-plus-module-njs nginx-plus-module-otel nginx-plus-module-fips-check nginx-agent-${NAP_AGENT_VERSION}.* \ + && dnf --nodocs install -y nginx-plus nginx-plus-module-njs nginx-plus-module-otel nginx-plus-module-fips-check \ && dnf --nodocs install -y app-protect-module-plus-${NAP_WAF_VERSION}* \ && nap-waf.sh \ - && agent.sh \ && dnf clean all +############################################# Base image for UBI8 with NGINX Plus and App Protect WAFv5 ############################################# +FROM ubi-8-plus-nap-v5-base AS ubi-8-plus-nap-v5 +ARG NAP_AGENT_VERSION + +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=nginx-agent.repo,target=/etc/yum.repos.d/nginx-agent.repo,rw \ + --mount=type=bind,from=nginx-files,src=agent.sh,target=/usr/local/bin/agent.sh \ + dnf --nodocs install -y nginx-agent-${NAP_AGENT_VERSION}.* \ + && dnf clean all \ + && agent.sh + + +############################################# Base image for UBI8 with NGINX Plus, App Protect WAFv5 and Agent v3 ############################################# +FROM ubi-8-plus-nap-v5-base AS ubi-8-plus-nap-v5-agent +ARG NGINX_AGENT_VERSION + +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=nginx-agent.repo,target=/etc/yum.repos.d/nginx-agent.repo,rw \ + --mount=type=bind,from=nginx-files,src=agent.sh,target=/usr/local/bin/agent.sh \ + dnf --nodocs install -y nginx-agent-${NGINX_AGENT_VERSION}.* \ + && dnf clean all \ + && agent.sh + + ############################################# Create common files, permissions and setcap ############################################# FROM ${BUILD_OS} AS common diff --git a/charts/nginx-ingress/templates/_helpers.tpl b/charts/nginx-ingress/templates/_helpers.tpl index ca0d038f29..f3d0195063 100644 --- a/charts/nginx-ingress/templates/_helpers.tpl +++ b/charts/nginx-ingress/templates/_helpers.tpl @@ -414,14 +414,15 @@ List of volumes for controller. - name: agent-conf configMap: name: {{ include "nginx-ingress.agentConfigName" . }} +- name: agent-etc + emptyDir: {} {{- if ne .Values.nginxAgent.dataplaneKeySecretName "" }} - name: dataplane-key secret: secretName: {{ .Values.nginxAgent.dataplaneKeySecretName }} -{{- else }} +{{- end }} - name: agent-dynamic emptyDir: {} -{{- end }} {{- if and .Values.nginxAgent.instanceManager.tls (or (ne (.Values.nginxAgent.instanceManager.tls.secret | default "") "") (ne (.Values.nginxAgent.instanceManager.tls.caSecret | default "") "")) }} - name: nginx-agent-tls projected: @@ -480,16 +481,17 @@ volumeMounts: {{ toYaml .Values.controller.volumeMounts }} {{- end }} {{- if .Values.nginxAgent.enable }} +- name: agent-etc + mountPath: /etc/nginx-agent - name: agent-conf mountPath: /etc/nginx-agent/nginx-agent.conf subPath: nginx-agent.conf {{- if ne .Values.nginxAgent.dataplaneKeySecretName "" }} - name: dataplane-key mountPath: /etc/nginx-agent/secrets -{{- else }} +{{- end }} - name: agent-dynamic mountPath: /var/lib/nginx-agent -{{- end }} {{- if and .Values.nginxAgent.instanceManager.tls (or (ne (.Values.nginxAgent.instanceManager.tls.secret | default "") "") (ne (.Values.nginxAgent.instanceManager.tls.caSecret | default "") "")) }} - name: nginx-agent-tls mountPath: /etc/ssl/nms @@ -543,12 +545,18 @@ log: allowed_directories: - /etc/nginx - /usr/lib/nginx/modules +{{- if .Values.controller.appprotect.enable }} + - /etc/app_protect +{{- end }} features: - certificates - connection - metrics - file-watcher +{{- if .Values.controller.appprotect.enable }} + - logs-nap +{{- end }} ## command server settings command: diff --git a/charts/tests/__snapshots__/helmunit_test.snap b/charts/tests/__snapshots__/helmunit_test.snap index d09e5be9d8..b8a3009f06 100755 --- a/charts/tests/__snapshots__/helmunit_test.snap +++ b/charts/tests/__snapshots__/helmunit_test.snap @@ -1336,6 +1336,8 @@ spec: - name: agent-conf configMap: name: app-protect-waf-agentv2-nginx-ingress-agent-config + - name: agent-etc + emptyDir: {} - name: agent-dynamic emptyDir: {} - name: nginx-agent-tls @@ -1390,6 +1392,8 @@ spec: - NET_BIND_SERVICE volumeMounts: + - name: agent-etc + mountPath: /etc/nginx-agent - name: agent-conf mountPath: /etc/nginx-agent/nginx-agent.conf subPath: nginx-agent.conf @@ -1512,16 +1516,577 @@ data: {} /-/-/-/ # Source: nginx-ingress/templates/controller-configmap.yaml -/-/-/-/ +/-/-/-/ +apiVersion: v1 +kind: ConfigMap +metadata: + name: appprotect-wafv5-nginx-ingress-mgmt + namespace: appprotect-wafv5 + labels: + helm.sh/chart: nginx-ingress-2.6.0 + app.kubernetes.io/name: nginx-ingress + app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/version: "5.5.0" + app.kubernetes.io/managed-by: Helm +data: + license-token-secret-name: license-token +/-/-/-/ +# Source: nginx-ingress/templates/controller-leader-election-configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: appprotect-wafv5-nginx-ingress-leader-election + namespace: appprotect-wafv5 + labels: + helm.sh/chart: nginx-ingress-2.6.0 + app.kubernetes.io/name: nginx-ingress + app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/version: "5.5.0" + app.kubernetes.io/managed-by: Helm +/-/-/-/ +# Source: nginx-ingress/templates/clusterrole.yaml +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: appprotect-wafv5-nginx-ingress + labels: + helm.sh/chart: nginx-ingress-2.6.0 + app.kubernetes.io/name: nginx-ingress + app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/version: "5.5.0" + app.kubernetes.io/managed-by: Helm +rules: +- apiGroups: + - "" + resources: + - configmaps + - namespaces + - pods + - secrets + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + - list +- apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - list + - watch +- apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - get + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - nodes + verbs: + - list +- apiGroups: + - "apps" + resources: + - replicasets + - daemonsets + - statefulsets + verbs: + - get +- apiGroups: + - networking.k8s.io + resources: + - ingressclasses + verbs: + - get + - list +- apiGroups: + - networking.k8s.io + resources: + - ingresses/status + verbs: + - update +- apiGroups: + - appprotect.f5.com + resources: + - appolicies + - aplogconfs + - apusersigs + verbs: + - get + - watch + - list +- apiGroups: + - k8s.nginx.org + resources: + - virtualservers + - virtualserverroutes + - globalconfigurations + - transportservers + - policies + verbs: + - list + - watch + - get +- apiGroups: + - k8s.nginx.org + resources: + - virtualservers/status + - virtualserverroutes/status + - policies/status + - transportservers/status + verbs: + - update +/-/-/-/ +# Source: nginx-ingress/templates/clusterrolebinding.yaml +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: appprotect-wafv5-nginx-ingress + labels: + helm.sh/chart: nginx-ingress-2.6.0 + app.kubernetes.io/name: nginx-ingress + app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/version: "5.5.0" + app.kubernetes.io/managed-by: Helm +subjects: +- kind: ServiceAccount + name: appprotect-wafv5-nginx-ingress + namespace: appprotect-wafv5 +roleRef: + kind: ClusterRole + name: appprotect-wafv5-nginx-ingress + apiGroup: rbac.authorization.k8s.io +/-/-/-/ +# Source: nginx-ingress/templates/controller-role.yaml +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: appprotect-wafv5-nginx-ingress + labels: + helm.sh/chart: nginx-ingress-2.6.0 + app.kubernetes.io/name: nginx-ingress + app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/version: "5.5.0" + app.kubernetes.io/managed-by: Helm + namespace: appprotect-wafv5 +rules: +- apiGroups: + - "" + resources: + - configmaps + - pods + - secrets + - services + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get +- apiGroups: + - "" + resources: + - pods + verbs: + - update +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + - list +- apiGroups: + - coordination.k8s.io + resources: + - leases + resourceNames: + - appprotect-wafv5-nginx-ingress-leader-election + verbs: + - get + - update +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create +/-/-/-/ +# Source: nginx-ingress/templates/controller-rolebinding.yaml +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: appprotect-wafv5-nginx-ingress + labels: + helm.sh/chart: nginx-ingress-2.6.0 + app.kubernetes.io/name: nginx-ingress + app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/version: "5.5.0" + app.kubernetes.io/managed-by: Helm + namespace: appprotect-wafv5 +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: appprotect-wafv5-nginx-ingress +subjects: +- kind: ServiceAccount + name: appprotect-wafv5-nginx-ingress + namespace: appprotect-wafv5 +/-/-/-/ +# Source: nginx-ingress/templates/controller-service.yaml +apiVersion: v1 +kind: Service +metadata: + name: appprotect-wafv5-nginx-ingress-controller + namespace: appprotect-wafv5 + labels: + helm.sh/chart: nginx-ingress-2.6.0 + app.kubernetes.io/name: nginx-ingress + app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/version: "5.5.0" + app.kubernetes.io/managed-by: Helm +spec: + externalTrafficPolicy: Local + type: LoadBalancer + ports: + - port: 80 + targetPort: 80 + protocol: TCP + name: http + nodePort: + - port: 443 + targetPort: 443 + protocol: TCP + name: https + nodePort: + selector: + app.kubernetes.io/name: nginx-ingress + app.kubernetes.io/instance: appprotect-wafv5 +/-/-/-/ +# Source: nginx-ingress/templates/controller-deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: appprotect-wafv5-nginx-ingress-controller + namespace: appprotect-wafv5 + labels: + helm.sh/chart: nginx-ingress-2.6.0 + app.kubernetes.io/name: nginx-ingress + app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/version: "5.5.0" + app.kubernetes.io/managed-by: Helm +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: nginx-ingress + app.kubernetes.io/instance: appprotect-wafv5 + template: + metadata: + labels: + app.kubernetes.io/name: nginx-ingress + app.kubernetes.io/instance: appprotect-wafv5 + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "9113" + prometheus.io/scheme: "http" + spec: + volumes: + + - emptyDir: {} + name: app-protect-bd-config + - emptyDir: {} + name: app-protect-config + - emptyDir: {} + name: app-protect-bundles + serviceAccountName: appprotect-wafv5-nginx-ingress + automountServiceAccountToken: true + securityContext: + seccompProfile: + type: RuntimeDefault + terminationGracePeriodSeconds: 30 + hostNetwork: false + dnsPolicy: ClusterFirst + containers: + - image: nginx/nginx-ingress:5.5.0 + name: nginx-ingress + imagePullPolicy: "IfNotPresent" + ports: + - name: http + containerPort: 80 + protocol: TCP + - name: https + containerPort: 443 + protocol: TCP + - name: prometheus + containerPort: 9113 + - name: readiness-port + containerPort: 8081 + readinessProbe: + httpGet: + path: /nginx-ready + port: readiness-port + periodSeconds: 1 + initialDelaySeconds: 0 + resources: + requests: + cpu: 100m + memory: 128Mi + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: false + runAsUser: 101 #nginx + runAsNonRoot: true + capabilities: + drop: + - ALL + add: + - NET_BIND_SERVICE + volumeMounts: + + - name: app-protect-bd-config + 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 + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + args: + + - -nginx-plus=true + - -nginx-reload-timeout=60000 + - -enable-app-protect=true + - -app-protect-enforcer-address="localhost:50001" + - -enable-app-protect-dos=false + - -nginx-configmaps=$(POD_NAMESPACE)/appprotect-wafv5-nginx-ingress + - -mgmt-configmap=$(POD_NAMESPACE)/appprotect-wafv5-nginx-ingress-mgmt + - -ingress-class=nginx + - -health-status=false + - -health-status-uri=/nginx-health + - -nginx-debug=false + - -log-level=info + - -log-format=glog + - -enable-config-safety=false + - -nginx-status=true + - -nginx-status-port=8080 + - -nginx-status-allow-cidrs=127.0.0.1 + - -report-ingress-status + - -external-service=appprotect-wafv5-nginx-ingress-controller + - -enable-leader-election=true + - -leader-election-lock-name=appprotect-wafv5-nginx-ingress-leader-election + - -enable-prometheus-metrics=true + - -prometheus-metrics-listen-port=9113 + - -prometheus-tls-secret= + - -enable-service-insight=false + - -service-insight-listen-port=9114 + - -service-insight-tls-secret= + - -enable-custom-resources=true + - -enable-snippets=false + - -disable-ipv6=false + - -enable-tls-passthrough=false + - -enable-cert-manager=false + - -enable-oidc=false + - -enable-external-dns=false + - -default-http-listener-port=80 + - -default-https-listener-port=443 + - -ready-status=true + - -ready-status-port=8081 + - -enable-latency-metrics=false + - -ssl-dynamic-reload=true + - -enable-telemetry-reporting=true + - -weight-changes-dynamic-reload=false + + - name: waf-enforcer + image: my.private.reg/nap/waf-enforcer:5.12.1 + imagePullPolicy: "IfNotPresent" + env: + - name: ENFORCER_PORT + value: "50001" + - name: ENFORCER_CONFIG_TIMEOUT + value: "0" + volumeMounts: + - name: app-protect-bd-config + mountPath: /opt/app_protect/bd_config + - name: waf-config-mgr + image: my.private.reg/nap/waf-config-mgr:5.12.1 + imagePullPolicy: "IfNotPresent" + securityContext: + + allowPrivilegeEscalation: false + capabilities: + drop: + - all + runAsNonRoot: true + runAsUser: 101 + 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 +/-/-/-/ +# Source: nginx-ingress/templates/controller-ingress-class.yaml +apiVersion: networking.k8s.io/v1 +kind: IngressClass +metadata: + name: nginx + labels: + helm.sh/chart: nginx-ingress-2.6.0 + app.kubernetes.io/name: nginx-ingress + app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/version: "5.5.0" + app.kubernetes.io/managed-by: Helm +spec: + controller: nginx.org/ingress-controller +/-/-/-/ +# Source: nginx-ingress/templates/controller-lease.yaml +apiVersion: coordination.k8s.io/v1 +kind: Lease +metadata: + name: appprotect-wafv5-nginx-ingress-leader-election + namespace: appprotect-wafv5 + labels: + helm.sh/chart: nginx-ingress-2.6.0 + app.kubernetes.io/name: nginx-ingress + app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/version: "5.5.0" + app.kubernetes.io/managed-by: Helm +--- + +[TestHelmNICTemplate/appProtectWAFV5AgentV2 - 1] +/-/-/-/ +# Source: nginx-ingress/templates/controller-serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: app-protect-wafv5-agentv2-nginx-ingress + namespace: default + labels: + helm.sh/chart: nginx-ingress-2.6.0 + app.kubernetes.io/name: nginx-ingress + app.kubernetes.io/instance: app-protect-wafv5-agentv2 + app.kubernetes.io/version: "5.5.0" + app.kubernetes.io/managed-by: Helm +/-/-/-/ +# Source: nginx-ingress/templates/controller-configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: app-protect-wafv5-agentv2-nginx-ingress + namespace: default + labels: + helm.sh/chart: nginx-ingress-2.6.0 + app.kubernetes.io/name: nginx-ingress + app.kubernetes.io/instance: app-protect-wafv5-agentv2 + app.kubernetes.io/version: "5.5.0" + app.kubernetes.io/managed-by: Helm +data: + {} +/-/-/-/ +# Source: nginx-ingress/templates/controller-configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: app-protect-wafv5-agentv2-nginx-ingress-agent-config + namespace: default + labels: + helm.sh/chart: nginx-ingress-2.6.0 + app.kubernetes.io/name: nginx-ingress + app.kubernetes.io/instance: app-protect-wafv5-agentv2 + app.kubernetes.io/version: "5.5.0" + app.kubernetes.io/managed-by: Helm +data: + nginx-agent.conf: |- + + log: + level: info + path: "" + server: + host: nim.example.com + grpcPort: 443 + metrics: nim.example.com + command: nim.example.com + tls: + enable: true + skip_verify: false + ca: "/etc/ssl/nms/ca.crt" + cert: "/etc/ssl/nms/tls.crt" + key: "/etc/ssl/nms/tls.key" + features: + - registration + - nginx-counting + - metrics + - dataplane-status + extensions: + - nginx-app-protect + - nap-monitoring + nginx_app_protect: + report_interval: 15s + precompiled_publication: true + nap_monitoring: + collector_buffer_size: 50000 + processor_buffer_size: 50000 + syslog_ip: 127.0.0.1 + syslog_port: 1514 +/-/-/-/ +# Source: nginx-ingress/templates/controller-configmap.yaml apiVersion: v1 kind: ConfigMap metadata: - name: appprotect-wafv5-nginx-ingress-mgmt - namespace: appprotect-wafv5 + name: app-protect-wafv5-agentv2-nginx-ingress-mgmt + namespace: default labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/instance: app-protect-wafv5-agentv2 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm data: @@ -1531,12 +2096,12 @@ data: apiVersion: v1 kind: ConfigMap metadata: - name: appprotect-wafv5-nginx-ingress-leader-election - namespace: appprotect-wafv5 + name: app-protect-wafv5-agentv2-nginx-ingress-leader-election + namespace: default labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/instance: app-protect-wafv5-agentv2 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm /-/-/-/ @@ -1544,11 +2109,11 @@ metadata: kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: appprotect-wafv5-nginx-ingress + name: app-protect-wafv5-agentv2-nginx-ingress labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/instance: app-protect-wafv5-agentv2 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm rules: @@ -1669,34 +2234,34 @@ rules: kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: appprotect-wafv5-nginx-ingress + name: app-protect-wafv5-agentv2-nginx-ingress labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/instance: app-protect-wafv5-agentv2 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm subjects: - kind: ServiceAccount - name: appprotect-wafv5-nginx-ingress - namespace: appprotect-wafv5 + name: app-protect-wafv5-agentv2-nginx-ingress + namespace: default roleRef: kind: ClusterRole - name: appprotect-wafv5-nginx-ingress + name: app-protect-wafv5-agentv2-nginx-ingress apiGroup: rbac.authorization.k8s.io /-/-/-/ # Source: nginx-ingress/templates/controller-role.yaml kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: appprotect-wafv5-nginx-ingress + name: app-protect-wafv5-agentv2-nginx-ingress labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/instance: app-protect-wafv5-agentv2 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm - namespace: appprotect-wafv5 + namespace: default rules: - apiGroups: - "" @@ -1734,7 +2299,7 @@ rules: resources: - leases resourceNames: - - appprotect-wafv5-nginx-ingress-leader-election + - app-protect-wafv5-agentv2-nginx-ingress-leader-election verbs: - get - update @@ -1749,33 +2314,33 @@ rules: kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: appprotect-wafv5-nginx-ingress + name: app-protect-wafv5-agentv2-nginx-ingress labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/instance: app-protect-wafv5-agentv2 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm - namespace: appprotect-wafv5 + namespace: default roleRef: apiGroup: rbac.authorization.k8s.io kind: Role - name: appprotect-wafv5-nginx-ingress + name: app-protect-wafv5-agentv2-nginx-ingress subjects: - kind: ServiceAccount - name: appprotect-wafv5-nginx-ingress - namespace: appprotect-wafv5 + name: app-protect-wafv5-agentv2-nginx-ingress + namespace: default /-/-/-/ # Source: nginx-ingress/templates/controller-service.yaml apiVersion: v1 kind: Service metadata: - name: appprotect-wafv5-nginx-ingress-controller - namespace: appprotect-wafv5 + name: app-protect-wafv5-agentv2-nginx-ingress-controller + namespace: default labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/instance: app-protect-wafv5-agentv2 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm spec: @@ -1794,18 +2359,18 @@ spec: nodePort: selector: app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/instance: app-protect-wafv5-agentv2 /-/-/-/ # Source: nginx-ingress/templates/controller-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: - name: appprotect-wafv5-nginx-ingress-controller - namespace: appprotect-wafv5 + name: app-protect-wafv5-agentv2-nginx-ingress-controller + namespace: default labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/instance: app-protect-wafv5-agentv2 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm spec: @@ -1813,12 +2378,13 @@ spec: selector: matchLabels: app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/instance: app-protect-wafv5-agentv2 template: metadata: labels: app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/instance: app-protect-wafv5-agentv2 + agent-configuration-revision-hash: "7f0862bf" annotations: prometheus.io/scrape: "true" prometheus.io/port: "9113" @@ -1832,7 +2398,21 @@ spec: name: app-protect-config - emptyDir: {} name: app-protect-bundles - serviceAccountName: appprotect-wafv5-nginx-ingress + - name: agent-conf + configMap: + name: app-protect-wafv5-agentv2-nginx-ingress-agent-config + - name: agent-etc + emptyDir: {} + - name: agent-dynamic + emptyDir: {} + - name: nginx-agent-tls + projected: + sources: + - secret: + name: tls-secret + - secret: + name: ca-secret + serviceAccountName: app-protect-wafv5-agentv2-nginx-ingress automountServiceAccountToken: true securityContext: seccompProfile: @@ -1885,6 +2465,16 @@ spec: # can verify that referenced bundles are present - name: app-protect-bundles mountPath: /etc/app_protect/bundles + - name: agent-etc + mountPath: /etc/nginx-agent + - name: agent-conf + mountPath: /etc/nginx-agent/nginx-agent.conf + subPath: nginx-agent.conf + - name: agent-dynamic + mountPath: /var/lib/nginx-agent + - name: nginx-agent-tls + mountPath: /etc/ssl/nms + readOnly: true env: - name: POD_NAMESPACE valueFrom: @@ -1901,8 +2491,8 @@ spec: - -enable-app-protect=true - -app-protect-enforcer-address="localhost:50001" - -enable-app-protect-dos=false - - -nginx-configmaps=$(POD_NAMESPACE)/appprotect-wafv5-nginx-ingress - - -mgmt-configmap=$(POD_NAMESPACE)/appprotect-wafv5-nginx-ingress-mgmt + - -nginx-configmaps=$(POD_NAMESPACE)/app-protect-wafv5-agentv2-nginx-ingress + - -mgmt-configmap=$(POD_NAMESPACE)/app-protect-wafv5-agentv2-nginx-ingress-mgmt - -ingress-class=nginx - -health-status=false - -health-status-uri=/nginx-health @@ -1914,9 +2504,9 @@ spec: - -nginx-status-port=8080 - -nginx-status-allow-cidrs=127.0.0.1 - -report-ingress-status - - -external-service=appprotect-wafv5-nginx-ingress-controller + - -external-service=app-protect-wafv5-agentv2-nginx-ingress-controller - -enable-leader-election=true - - -leader-election-lock-name=appprotect-wafv5-nginx-ingress-leader-election + - -leader-election-lock-name=app-protect-wafv5-agentv2-nginx-ingress-leader-election - -enable-prometheus-metrics=true - -prometheus-metrics-listen-port=9113 - -prometheus-tls-secret= @@ -1938,6 +2528,8 @@ spec: - -ssl-dynamic-reload=true - -enable-telemetry-reporting=true - -weight-changes-dynamic-reload=false + - -agent=true + - -agent-instance-group=app-protect-wafv5-agentv2-nginx-ingress-controller - name: waf-enforcer image: my.private.reg/nap/waf-enforcer:5.12.1 @@ -1977,7 +2569,7 @@ metadata: labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/instance: app-protect-wafv5-agentv2 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm spec: @@ -1987,28 +2579,28 @@ spec: apiVersion: coordination.k8s.io/v1 kind: Lease metadata: - name: appprotect-wafv5-nginx-ingress-leader-election - namespace: appprotect-wafv5 + name: app-protect-wafv5-agentv2-nginx-ingress-leader-election + namespace: default labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: appprotect-wafv5 + app.kubernetes.io/instance: app-protect-wafv5-agentv2 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm --- -[TestHelmNICTemplate/appProtectWAFV5AgentV2 - 1] +[TestHelmNICTemplate/appProtectWAFV5AgentV3 - 1] /-/-/-/ # Source: nginx-ingress/templates/controller-serviceaccount.yaml apiVersion: v1 kind: ServiceAccount metadata: - name: app-protect-wafv5-agentv2-nginx-ingress + name: app-protect-wafv5-agentv3-nginx-ingress namespace: default labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: app-protect-wafv5-agentv2 + app.kubernetes.io/instance: app-protect-wafv5-agentv3 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm /-/-/-/ @@ -2016,12 +2608,12 @@ metadata: apiVersion: v1 kind: ConfigMap metadata: - name: app-protect-wafv5-agentv2-nginx-ingress + name: app-protect-wafv5-agentv3-nginx-ingress namespace: default labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: app-protect-wafv5-agentv2 + app.kubernetes.io/instance: app-protect-wafv5-agentv3 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm data: @@ -2031,58 +2623,59 @@ data: apiVersion: v1 kind: ConfigMap metadata: - name: app-protect-wafv5-agentv2-nginx-ingress-agent-config + name: app-protect-wafv5-agentv3-nginx-ingress-agent-config namespace: default labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: app-protect-wafv5-agentv2 + app.kubernetes.io/instance: app-protect-wafv5-agentv3 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm data: nginx-agent.conf: |- log: + # set log level (error, info, debug; default "info") level: info + # set log path. if empty, don't log to file. path: "" - server: - host: nim.example.com - grpcPort: 443 - metrics: nim.example.com - command: nim.example.com - tls: - enable: true - skip_verify: false - ca: "/etc/ssl/nms/ca.crt" - cert: "/etc/ssl/nms/tls.crt" - key: "/etc/ssl/nms/tls.key" + + allowed_directories: + - /etc/nginx + - /usr/lib/nginx/modules + - /etc/app_protect + features: - - registration - - nginx-counting + - certificates + - connection - metrics - - dataplane-status - extensions: - - nginx-app-protect - - nap-monitoring - nginx_app_protect: - report_interval: 15s - precompiled_publication: true - nap_monitoring: - collector_buffer_size: 50000 - processor_buffer_size: 50000 - syslog_ip: 127.0.0.1 - syslog_port: 1514 + - file-watcher + + ## command server settings + command: + server: + host: agent.connect.nginx.com + port: 443 + auth: + tokenpath: "/etc/nginx-agent/secrets/dataplane.key" + tls: + skip_verify: false + + ## collector settings + collector: + log: + path: "stdout" /-/-/-/ # Source: nginx-ingress/templates/controller-configmap.yaml apiVersion: v1 kind: ConfigMap metadata: - name: app-protect-wafv5-agentv2-nginx-ingress-mgmt + name: app-protect-wafv5-agentv3-nginx-ingress-mgmt namespace: default labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: app-protect-wafv5-agentv2 + app.kubernetes.io/instance: app-protect-wafv5-agentv3 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm data: @@ -2092,12 +2685,12 @@ data: apiVersion: v1 kind: ConfigMap metadata: - name: app-protect-wafv5-agentv2-nginx-ingress-leader-election + name: app-protect-wafv5-agentv3-nginx-ingress-leader-election namespace: default labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: app-protect-wafv5-agentv2 + app.kubernetes.io/instance: app-protect-wafv5-agentv3 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm /-/-/-/ @@ -2105,11 +2698,11 @@ metadata: kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: app-protect-wafv5-agentv2-nginx-ingress + name: app-protect-wafv5-agentv3-nginx-ingress labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: app-protect-wafv5-agentv2 + app.kubernetes.io/instance: app-protect-wafv5-agentv3 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm rules: @@ -2230,31 +2823,31 @@ rules: kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: app-protect-wafv5-agentv2-nginx-ingress + name: app-protect-wafv5-agentv3-nginx-ingress labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: app-protect-wafv5-agentv2 + app.kubernetes.io/instance: app-protect-wafv5-agentv3 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm subjects: - kind: ServiceAccount - name: app-protect-wafv5-agentv2-nginx-ingress + name: app-protect-wafv5-agentv3-nginx-ingress namespace: default roleRef: kind: ClusterRole - name: app-protect-wafv5-agentv2-nginx-ingress + name: app-protect-wafv5-agentv3-nginx-ingress apiGroup: rbac.authorization.k8s.io /-/-/-/ # Source: nginx-ingress/templates/controller-role.yaml kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: app-protect-wafv5-agentv2-nginx-ingress + name: app-protect-wafv5-agentv3-nginx-ingress labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: app-protect-wafv5-agentv2 + app.kubernetes.io/instance: app-protect-wafv5-agentv3 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm namespace: default @@ -2295,7 +2888,7 @@ rules: resources: - leases resourceNames: - - app-protect-wafv5-agentv2-nginx-ingress-leader-election + - app-protect-wafv5-agentv3-nginx-ingress-leader-election verbs: - get - update @@ -2310,33 +2903,33 @@ rules: kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: app-protect-wafv5-agentv2-nginx-ingress + name: app-protect-wafv5-agentv3-nginx-ingress labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: app-protect-wafv5-agentv2 + app.kubernetes.io/instance: app-protect-wafv5-agentv3 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm namespace: default roleRef: apiGroup: rbac.authorization.k8s.io kind: Role - name: app-protect-wafv5-agentv2-nginx-ingress + name: app-protect-wafv5-agentv3-nginx-ingress subjects: - kind: ServiceAccount - name: app-protect-wafv5-agentv2-nginx-ingress + name: app-protect-wafv5-agentv3-nginx-ingress namespace: default /-/-/-/ # Source: nginx-ingress/templates/controller-service.yaml apiVersion: v1 kind: Service metadata: - name: app-protect-wafv5-agentv2-nginx-ingress-controller + name: app-protect-wafv5-agentv3-nginx-ingress-controller namespace: default labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: app-protect-wafv5-agentv2 + app.kubernetes.io/instance: app-protect-wafv5-agentv3 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm spec: @@ -2355,18 +2948,18 @@ spec: nodePort: selector: app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: app-protect-wafv5-agentv2 + app.kubernetes.io/instance: app-protect-wafv5-agentv3 /-/-/-/ # Source: nginx-ingress/templates/controller-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: - name: app-protect-wafv5-agentv2-nginx-ingress-controller + name: app-protect-wafv5-agentv3-nginx-ingress-controller namespace: default labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: app-protect-wafv5-agentv2 + app.kubernetes.io/instance: app-protect-wafv5-agentv3 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm spec: @@ -2374,13 +2967,13 @@ spec: selector: matchLabels: app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: app-protect-wafv5-agentv2 + app.kubernetes.io/instance: app-protect-wafv5-agentv3 template: metadata: labels: app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: app-protect-wafv5-agentv2 - agent-configuration-revision-hash: "7f0862bf" + app.kubernetes.io/instance: app-protect-wafv5-agentv3 + agent-configuration-revision-hash: "af84a0cc" annotations: prometheus.io/scrape: "true" prometheus.io/port: "9113" @@ -2396,17 +2989,15 @@ spec: name: app-protect-bundles - name: agent-conf configMap: - name: app-protect-wafv5-agentv2-nginx-ingress-agent-config + name: app-protect-wafv5-agentv3-nginx-ingress-agent-config + - name: agent-etc + emptyDir: {} + - name: dataplane-key + secret: + secretName: dataplane-key - name: agent-dynamic emptyDir: {} - - name: nginx-agent-tls - projected: - sources: - - secret: - name: tls-secret - - secret: - name: ca-secret - serviceAccountName: app-protect-wafv5-agentv2-nginx-ingress + serviceAccountName: app-protect-wafv5-agentv3-nginx-ingress automountServiceAccountToken: true securityContext: seccompProfile: @@ -2459,14 +3050,15 @@ spec: # can verify that referenced bundles are present - name: app-protect-bundles mountPath: /etc/app_protect/bundles + - name: agent-etc + mountPath: /etc/nginx-agent - name: agent-conf mountPath: /etc/nginx-agent/nginx-agent.conf subPath: nginx-agent.conf + - name: dataplane-key + mountPath: /etc/nginx-agent/secrets - name: agent-dynamic mountPath: /var/lib/nginx-agent - - name: nginx-agent-tls - mountPath: /etc/ssl/nms - readOnly: true env: - name: POD_NAMESPACE valueFrom: @@ -2483,8 +3075,8 @@ spec: - -enable-app-protect=true - -app-protect-enforcer-address="localhost:50001" - -enable-app-protect-dos=false - - -nginx-configmaps=$(POD_NAMESPACE)/app-protect-wafv5-agentv2-nginx-ingress - - -mgmt-configmap=$(POD_NAMESPACE)/app-protect-wafv5-agentv2-nginx-ingress-mgmt + - -nginx-configmaps=$(POD_NAMESPACE)/app-protect-wafv5-agentv3-nginx-ingress + - -mgmt-configmap=$(POD_NAMESPACE)/app-protect-wafv5-agentv3-nginx-ingress-mgmt - -ingress-class=nginx - -health-status=false - -health-status-uri=/nginx-health @@ -2496,9 +3088,9 @@ spec: - -nginx-status-port=8080 - -nginx-status-allow-cidrs=127.0.0.1 - -report-ingress-status - - -external-service=app-protect-wafv5-agentv2-nginx-ingress-controller + - -external-service=app-protect-wafv5-agentv3-nginx-ingress-controller - -enable-leader-election=true - - -leader-election-lock-name=app-protect-wafv5-agentv2-nginx-ingress-leader-election + - -leader-election-lock-name=app-protect-wafv5-agentv3-nginx-ingress-leader-election - -enable-prometheus-metrics=true - -prometheus-metrics-listen-port=9113 - -prometheus-tls-secret= @@ -2521,7 +3113,6 @@ spec: - -enable-telemetry-reporting=true - -weight-changes-dynamic-reload=false - -agent=true - - -agent-instance-group=app-protect-wafv5-agentv2-nginx-ingress-controller - name: waf-enforcer image: my.private.reg/nap/waf-enforcer:5.12.1 @@ -2561,7 +3152,7 @@ metadata: labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: app-protect-wafv5-agentv2 + app.kubernetes.io/instance: app-protect-wafv5-agentv3 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm spec: @@ -2571,12 +3162,12 @@ spec: apiVersion: coordination.k8s.io/v1 kind: Lease metadata: - name: app-protect-wafv5-agentv2-nginx-ingress-leader-election + name: app-protect-wafv5-agentv3-nginx-ingress-leader-election namespace: default labels: helm.sh/chart: nginx-ingress-2.6.0 app.kubernetes.io/name: nginx-ingress - app.kubernetes.io/instance: app-protect-wafv5-agentv2 + app.kubernetes.io/instance: app-protect-wafv5-agentv3 app.kubernetes.io/version: "5.5.0" app.kubernetes.io/managed-by: Helm --- @@ -8407,9 +8998,13 @@ spec: - name: agent-conf configMap: name: oss-agent-nginx-ingress-agent-config + - name: agent-etc + emptyDir: {} - name: dataplane-key secret: secretName: dataplane-key + - name: agent-dynamic + emptyDir: {} serviceAccountName: oss-agent-nginx-ingress automountServiceAccountToken: true securityContext: @@ -8455,11 +9050,15 @@ spec: - NET_BIND_SERVICE volumeMounts: + - name: agent-etc + mountPath: /etc/nginx-agent - name: agent-conf mountPath: /etc/nginx-agent/nginx-agent.conf subPath: nginx-agent.conf - name: dataplane-key mountPath: /etc/nginx-agent/secrets + - name: agent-dynamic + mountPath: /var/lib/nginx-agent env: - name: POD_NAMESPACE valueFrom: @@ -11722,9 +12321,13 @@ spec: - name: agent-conf configMap: name: plus-agent-nginx-ingress-agent-config + - name: agent-etc + emptyDir: {} - name: dataplane-key secret: secretName: dataplane-key + - name: agent-dynamic + emptyDir: {} serviceAccountName: plus-agent-nginx-ingress automountServiceAccountToken: true securityContext: @@ -11770,11 +12373,15 @@ spec: - NET_BIND_SERVICE volumeMounts: + - name: agent-etc + mountPath: /etc/nginx-agent - name: agent-conf mountPath: /etc/nginx-agent/nginx-agent.conf subPath: nginx-agent.conf - name: dataplane-key mountPath: /etc/nginx-agent/secrets + - name: agent-dynamic + mountPath: /var/lib/nginx-agent env: - name: POD_NAMESPACE valueFrom: @@ -12241,9 +12848,13 @@ spec: - name: agent-conf configMap: name: plus-agent-all-nginx-ingress-agent-config + - name: agent-etc + emptyDir: {} - name: dataplane-key secret: secretName: dataplane-key + - name: agent-dynamic + emptyDir: {} serviceAccountName: plus-agent-all-nginx-ingress automountServiceAccountToken: true securityContext: @@ -12289,11 +12900,15 @@ spec: - NET_BIND_SERVICE volumeMounts: + - name: agent-etc + mountPath: /etc/nginx-agent - name: agent-conf mountPath: /etc/nginx-agent/nginx-agent.conf subPath: nginx-agent.conf - name: dataplane-key mountPath: /etc/nginx-agent/secrets + - name: agent-dynamic + mountPath: /var/lib/nginx-agent env: - name: POD_NAMESPACE valueFrom: diff --git a/charts/tests/helmunit_test.go b/charts/tests/helmunit_test.go index f5ff708e70..1654ab8e7d 100644 --- a/charts/tests/helmunit_test.go +++ b/charts/tests/helmunit_test.go @@ -166,6 +166,11 @@ func TestHelmNICTemplate(t *testing.T) { releaseName: "app-protect-wafv5-agentv2", namespace: "default", }, + "appProtectWAFV5AgentV3": { + valuesFile: "testdata/app-protect-wafv5-agentv3.yaml", + releaseName: "app-protect-wafv5-agentv3", + namespace: "default", + }, "appProtectWAFV4AgentV2": { valuesFile: "testdata/app-protect-waf-agentv2.yaml", releaseName: "app-protect-waf-agentv2", diff --git a/charts/tests/testdata/app-protect-wafv5-agentv3.yaml b/charts/tests/testdata/app-protect-wafv5-agentv3.yaml new file mode 100644 index 0000000000..ada2c7568c --- /dev/null +++ b/charts/tests/testdata/app-protect-wafv5-agentv3.yaml @@ -0,0 +1,25 @@ +controller: + nginxplus: true + appprotect: + enable: true + v5: true + volumes: + - name: app-protect-bd-config + emptyDir: {} + - name: app-protect-config + emptyDir: {} + - name: app-protect-bundles + emptyDir: {} + enforcer: + host: "localhost" + port: 50001 + image: + repository: my.private.reg/nap/waf-enforcer + configManager: + image: + repository: my.private.reg/nap/waf-config-mgr +nginxAgent: + enable: true + dataplaneKeySecretName: "dataplane-key" + endpointHost: "agent.connect.nginx.com" + endpointPort: 443 diff --git a/examples/custom-resources/app-protect-waf-v5/ingress.yaml b/examples/custom-resources/app-protect-waf-v5/ingress.yaml new file mode 100644 index 0000000000..e1b1363873 --- /dev/null +++ b/examples/custom-resources/app-protect-waf-v5/ingress.yaml @@ -0,0 +1,19 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: webapp-ingress + annotations: + nginx.com/policies: "waf-policy" +spec: + ingressClassName: nginx + rules: + - host: webapp.example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: webapp-svc + port: + number: 80 diff --git a/examples/custom-resources/security-monitoring-v5/README.md b/examples/custom-resources/security-monitoring-v5/README.md new file mode 100644 index 0000000000..4a809209f7 --- /dev/null +++ b/examples/custom-resources/security-monitoring-v5/README.md @@ -0,0 +1,112 @@ +# WAF Security Monitoring with F5 WAF for NGINX v5 + +This example describes how to deploy NGINX Plus Ingress Controller with [F5 WAF for NGINX v5](https://docs.nginx.com/waf/) and [NGINX Agent](https://docs.nginx.com/nginx-agent/overview/) to integrate with [NGINX Instance Manager Security Monitoring](https://docs.nginx.com/nginx-instance-manager/security-monitoring/). It deploys a simple web application and configures WAF protection using compiled policy and log bundles, forwarding security logs to the Security Monitoring dashboard via syslog. + +## Prerequisites + +1. Follow the installation [instructions](https://docs.nginx.com/nginx-ingress-controller/installation) to deploy NGINX + Ingress Controller with F5 WAF for NGINX v5 and NGINX Agent. Configure NGINX Agent to connect to a deployment of NGINX Instance Manager with Security Monitoring, and verify your NGINX Ingress Controller deployment is online in NGINX Instance Manager. + +1. Save the public IP address of the Ingress Controller into a shell variable: + + ```console + IC_IP=XXX.YYY.ZZZ.III + ``` + +1. Save the HTTP port of NGINX Ingress Controller into a shell variable: + + ```console + IC_HTTP_PORT= + ``` + +## Step 1. Deploy a Web Application + +Create the application deployment and service: + +```console +kubectl apply -f webapp.yaml +``` + +## Step 2 - Create and Deploy the WAF Policy and Log Bundles + +1. Compile your WAF policy JSON into a policy bundle (`compiled_policy.tgz`) and a log configuration bundle (`compiled_log.tgz`) using the `waf-compiler` image: + + ```console + docker run --rm \ + -v /tmp:/tmp \ + private-registry.nginx.com/nap/waf-compiler: \ + -p /tmp/your_policy.json \ + -o /tmp/compiled_policy.tgz + ``` + + Refer to the [F5 WAF for NGINX documentation](https://docs.nginx.com/waf/) for details on compiling policy and log bundles. + +1. Copy both bundles to the volume mounted at `/etc/app_protect/bundles` in the Ingress Controller pod: + + ```console + kubectl cp ./compiled_policy.tgz :/etc/app_protect/bundles/compiled_policy.tgz -c nginx-ingress + kubectl cp ./compiled_log.tgz :/etc/app_protect/bundles/compiled_log.tgz -c nginx-ingress + ``` + +## Step 3 - Deploy the Syslog Service + +Create the syslog service and pod that receives App Protect security logs: + +```console +kubectl apply -f syslog.yaml +``` + +## Step 4 - Deploy the WAF Policy + +Create the WAF policy referencing the compiled bundles: + +```console +kubectl apply -f waf.yaml +``` + +The `waf.yaml` Policy resource configures WAF protection using the compiled policy bundle and sends security logs to the syslog service using the compiled log bundle. + +Note the log configuration in the `apLogBundle` must be compiled from a log profile that matches the format required by NGINX Instance Manager Security Monitoring. + +## Step 5 - Configure Load Balancing + +Create the VirtualServer resource: + +```console +kubectl apply -f virtual-server.yaml +``` + +## Step 6 - Test the Application + +1. Send a valid request to the application: + + ```console + curl --resolve webapp.example.com:$IC_HTTP_PORT:$IC_IP http://webapp.example.com:$IC_HTTP_PORT/ + ``` + + ```text + Server address: 10.12.0.18:80 + Server name: webapp-7586895968-r26zn + ... + ``` + +1. Send a request with a suspicious URL: + + ```console + curl --resolve webapp.example.com:$IC_HTTP_PORT:$IC_IP "http://webapp.example.com:$IC_HTTP_PORT/