Deploy NGINX App Protect WAF with Helm
Overview
This document explains how to install F5 NGINX App Protect WAF with Helm.
Prerequisites
- Kubernetes cluster
- Helm installed
- NGINX Docker image
- NGINX JWT license (if NGINX Plus is used)
- Docker registry credentials for private-registry.nginx.com
Build the NGINX Image
Follow the instructions below to build a Docker image containing the NGINX and the NGINX App Protect module.
Download certificates
Log in to My F5 and download the following two files from your active NGINX App Protect WAF subscription:
nginx-repo.key
nginx-repo.crt
Next, create a Dockerfile
using one of the examples provided below.
Official NGINX Dockerfile
While this example utilizes the official NGINX Open Source image as a base, the crucial requirement is that NGINX must be installed as a package from the official NGINX repository, rather than being compiled from source.
# syntax=docker/dockerfile:1
# Base image
FROM nginx:1.25.5-bookworm
# Install NGINX App Protect WAF v5 module
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \
--mount=type=secret,id=nginx-key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \
apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y \
apt-transport-https \
lsb-release \
ca-certificates \
wget \
gnupg \
&& wget https://cs.nginx.com/static/keys/nginx_signing.key \
&& gpg --no-default-keyring --keyring gnupg-ring:/etc/apt/trusted.gpg.d/nginx.gpg \
--import nginx_signing.key \
&& chmod 644 /etc/apt/trusted.gpg.d/nginx.gpg \
&& printf "deb https://pkgs.nginx.com/app-protect-x-oss/debian `lsb_release -cs` nginx-plus\n" | \
tee /etc/apt/sources.list.d/nginx-app-protect.list \
&& wget -P /etc/apt/apt.conf.d https://cs.nginx.com/static/files/90pkgs-nginx \
&& apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y nginx=1.25.5-1~bookworm app-protect-module-oss \
&& apt-get remove --purge --auto-remove -y apt-transport-https lsb-release gnupg wget \
&& rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx-app-protect.list
NGINX Open Source Dockerfile
# syntax=docker/dockerfile:1
# Supported OS_VER's are 3.16/3.17/3.19
ARG OS_VER="3.19"
# Base image
FROM alpine:${OS_VER}
# Install NGINX OSS and NGINX App Protect WAF v5 module
RUN --mount=type=secret,id=nginx-crt,dst=/etc/apk/cert.pem,mode=0644 \
--mount=type=secret,id=nginx-key,dst=/etc/apk/cert.key,mode=0644 \
apk add openssl curl ca-certificates \
&& printf "%s%s%s%s\n" \
"http://nginx.org/packages/mainline/alpine/v" \
`egrep -o '^[0-9]+\.[0-9]+' /etc/alpine-release` \
"/main" \
| tee -a /etc/apk/repositories \
&& wget -O /etc/apk/keys/nginx_signing.rsa.pub https://cs.nginx.com/static/keys/nginx_signing.rsa.pub \
&& printf "https://pkgs.nginx.com/app-protect-x-oss/alpine/v`egrep -o '^[0-9]+\.[0-9]+' /etc/alpine-release`/main\n" | \
tee -a /etc/apk/repositories \
&& apk update \
&& apk add app-protect-module-oss \
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log \
&& rm -rf /var/cache/apk/*
# Expose port
EXPOSE 80
# Define stop signal
STOPSIGNAL SIGQUIT
# Set default command
CMD ["nginx", "-g", "daemon off;"]
# syntax=docker/dockerfile:1
# Base image
FROM amazonlinux:2
# Install NGINX OSS and NGINX App Protect WAF v5 module
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \
--mount=type=secret,id=nginx-key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \
amazon-linux-extras enable epel \
&& yum clean metadata \
&& yum -y install wget ca-certificates epel-release shadow-utils yum-utils \
&& echo "[nginx-mainline]" > /etc/yum.repos.d/nginx.repo \
&& echo "name=nginx mainline repo" >> /etc/yum.repos.d/nginx.repo \
&& echo "baseurl=http://nginx.org/packages/mainline/amzn2/\$releasever/\$basearch/" >> /etc/yum.repos.d/nginx.repo \
&& echo "gpgcheck=1" >> /etc/yum.repos.d/nginx.repo \
&& echo "enabled=1" >> /etc/yum.repos.d/nginx.repo \
&& echo "gpgkey=https://nginx.org/keys/nginx_signing.key" >> /etc/yum.repos.d/nginx.repo \
&& echo "module_hotfixes=true" >> /etc/yum.repos.d/nginx.repo \
&& echo "priority=9" >> /etc/yum.repos.d/nginx.repo \
&& echo "[app-protect-x-oss]" > /etc/yum.repos.d/app-protect-7-x-oss.repo \
&& echo "name=nginx-app-protect repo" >> /etc/yum.repos.d/app-protect-7-x-oss.repo \
&& echo "baseurl=https://pkgs.nginx.com/app-protect-x-oss/centos/7/\$basearch/" >> /etc/yum.repos.d/app-protect-7-x-oss.repo \
&& echo "sslclientcert=/etc/ssl/nginx/nginx-repo.crt" >> /etc/yum.repos.d/app-protect-7-x-oss.repo \
&& echo "sslclientkey=/etc/ssl/nginx/nginx-repo.key" >> /etc/yum.repos.d/app-protect-7-x-oss.repo \
&& echo "gpgcheck=0" >> /etc/yum.repos.d/app-protect-7-x-oss.repo \
&& echo "enabled=1" >> /etc/yum.repos.d/app-protect-7-x-oss.repo \
&& yum -y install app-protect-module-oss \
&& yum clean all \
&& rm -rf /var/cache/yum \
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log
# Expose port
EXPOSE 80
# Define stop signal
STOPSIGNAL SIGQUIT
# Set default command
CMD ["nginx", "-g", "daemon off;"]
# syntax=docker/dockerfile:1
# Base image
FROM centos:7
# Install NGINX OSS and NGINX App Protect WAF v5 module
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \
--mount=type=secret,id=nginx-key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \
yum -y install wget ca-certificates epel-release yum-utils \
&& echo "[nginx-mainline]" > /etc/yum.repos.d/nginx.repo \
&& echo "name=nginx mainline repo" >> /etc/yum.repos.d/nginx.repo \
&& echo "baseurl=http://nginx.org/packages/mainline/centos/\$releasever/\$basearch/" >> /etc/yum.repos.d/nginx.repo \
&& echo "gpgcheck=1" >> /etc/yum.repos.d/nginx.repo \
&& echo "enabled=1" >> /etc/yum.repos.d/nginx.repo \
&& echo "gpgkey=https://nginx.org/keys/nginx_signing.key" >> /etc/yum.repos.d/nginx.repo \
&& echo "module_hotfixes=true" >> /etc/yum.repos.d/nginx.repo \
&& echo "[app-protect-x-oss]" > /etc/yum.repos.d/app-protect-7-x-oss.repo \
&& echo "name=nginx-app-protect repo" >> /etc/yum.repos.d/app-protect-7-x-oss.repo \
&& echo "baseurl=https://pkgs.nginx.com/app-protect-x-oss/centos/7/\$basearch/" >> /etc/yum.repos.d/app-protect-7-x-oss.repo \
&& echo "sslclientcert=/etc/ssl/nginx/nginx-repo.crt" >> /etc/yum.repos.d/app-protect-7-x-oss.repo \
&& echo "sslclientkey=/etc/ssl/nginx/nginx-repo.key" >> /etc/yum.repos.d/app-protect-7-x-oss.repo \
&& echo "gpgcheck=0" >> /etc/yum.repos.d/app-protect-7-x-oss.repo \
&& echo "enabled=1" >> /etc/yum.repos.d/app-protect-7-x-oss.repo \
&& yum -y install app-protect-module-oss \
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log \
&& yum clean all \
&& rm -rf /var/cache/yum
# Expose port
EXPOSE 80
# Define stop signal
STOPSIGNAL SIGQUIT
# Set default command
CMD ["nginx", "-g", "daemon off;"]
# syntax=docker/dockerfile:1
# Supported OS_CODENAME's are: bullseye/bookworm
ARG OS_CODENAME=bookworm
# Base image
FROM debian:${OS_CODENAME}
# Install NGINX OSS and NGINX App Protect WAF v5 module
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \
--mount=type=secret,id=nginx-key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \
apt-get update \
&& apt-get install -y \
apt-transport-https \
lsb-release \
ca-certificates \
wget \
gnupg2 \
debian-archive-keyring \
&& wget -qO - https://nginx.org/keys/nginx_signing.key | gpg --dearmor | \
tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null \
&& gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg \
&& printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/mainline/debian `lsb_release -cs` nginx\n" | \
tee /etc/apt/sources.list.d/nginx.list \
&& wget -qO - https://cs.nginx.com/static/keys/nginx_signing.key | gpg --dearmor | \
tee /usr/share/keyrings/nginx-static-archive-keyring.gpg >/dev/null \
&& gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-static-archive-keyring.gpg \
&& printf "deb [signed-by=/usr/share/keyrings/nginx-static-archive-keyring.gpg] \
https://pkgs.nginx.com/app-protect-x-oss/debian `lsb_release -cs` nginx-plus\n" | \
tee /etc/apt/sources.list.d/nginx-app-protect.list \
&& wget -P /etc/apt/apt.conf.d https://cs.nginx.com/static/files/90pkgs-nginx \
&& apt-get update \
&& DEBIAN_FRONTEND="noninteractive" apt-get install -y nginx=1.25.5-1~`lsb_release -cs` app-protect-module-oss \
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Expose port
EXPOSE 80
# Define stop signal
STOPSIGNAL SIGQUIT
# Set default command
CMD ["nginx", "-g", "daemon off;"]
# syntax=docker/dockerfile:1
# Base image
FROM oraclelinux:8
# Install NGINX OSS and NGINX App Protect WAF v5 module
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \
--mount=type=secret,id=nginx-key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \
dnf -y install wget ca-certificates yum-utils \
&& echo "[nginx-mainline]" > /etc/yum.repos.d/nginx.repo \
&& echo "name=nginx mainline repo" >> /etc/yum.repos.d/nginx.repo \
&& echo "baseurl=http://nginx.org/packages/mainline/centos/\$releasever/\$basearch/" >> /etc/yum.repos.d/nginx.repo \
&& echo "gpgcheck=1" >> /etc/yum.repos.d/nginx.repo \
&& echo "enabled=1" >> /etc/yum.repos.d/nginx.repo \
&& echo "gpgkey=https://nginx.org/keys/nginx_signing.key" >> /etc/yum.repos.d/nginx.repo \
&& echo "module_hotfixes=true" >> /etc/yum.repos.d/nginx.repo \
&& echo "[app-protect-x-oss]" > /etc/yum.repos.d/app-protect-8-x-oss.repo \
&& echo "name=nginx-app-protect repo" >> /etc/yum.repos.d/app-protect-8-x-oss.repo \
&& echo "baseurl=https://pkgs.nginx.com/app-protect-x-oss/centos/8/\$basearch/" >> /etc/yum.repos.d/app-protect-8-x-oss.repo \
&& echo "sslclientcert=/etc/ssl/nginx/nginx-repo.crt" >> /etc/yum.repos.d/app-protect-8-x-oss.repo \
&& echo "sslclientkey=/etc/ssl/nginx/nginx-repo.key" >> /etc/yum.repos.d/app-protect-8-x-oss.repo \
&& echo "gpgcheck=0" >> /etc/yum.repos.d/app-protect-8-x-oss.repo \
&& echo "enabled=1" >> /etc/yum.repos.d/app-protect-8-x-oss.repo \
&& dnf clean all \
&& dnf -y install app-protect-module-oss \
&& dnf clean all \
&& rm -rf /var/cache/dnf \
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log
# Expose port
EXPOSE 80
# Define stop signal
STOPSIGNAL SIGQUIT
# Set default command
CMD ["nginx", "-g", "daemon off;"]
# syntax=docker/dockerfile:1
# Supported UBI_VERSION's are 7/8/9
ARG UBI_VERSION=9
# Base Image
FROM registry.access.redhat.com/ubi${UBI_VERSION}/ubi
# Define the ARG again after FROM to use it in this stage
ARG UBI_VERSION
# Install NGINX OSS and NGINX App Protect WAF v5 module
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \
--mount=type=secret,id=nginx-key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \
PKG_MANAGER=dnf; \
if [ "${UBI_VERSION}" = "7" ]; then \
PKG_MANAGER=yum; \
fi \
&& $PKG_MANAGER -y install wget ca-certificates yum-utils \
&& wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/dependencies.repo \
&& echo "[nginx-mainline]" > /etc/yum.repos.d/nginx.repo \
&& echo "name=nginx mainline repo" >> /etc/yum.repos.d/nginx.repo \
&& echo "baseurl=http://nginx.org/packages/mainline/centos/\$releasever/\$basearch/" >> /etc/yum.repos.d/nginx.repo \
&& echo "gpgcheck=1" >> /etc/yum.repos.d/nginx.repo \
&& echo "enabled=1" >> /etc/yum.repos.d/nginx.repo \
&& echo "gpgkey=https://nginx.org/keys/nginx_signing.key" >> /etc/yum.repos.d/nginx.repo \
&& echo "module_hotfixes=true" >> /etc/yum.repos.d/nginx.repo \
&& echo "[app-protect-x-oss]" > /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-oss.repo \
&& echo "name=nginx-app-protect repo" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-oss.repo \
&& echo "baseurl=https://pkgs.nginx.com/app-protect-x-oss/centos/${UBI_VERSION}/\$basearch/" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-oss.repo \
&& echo "sslclientcert=/etc/ssl/nginx/nginx-repo.crt" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-oss.repo \
&& echo "sslclientkey=/etc/ssl/nginx/nginx-repo.key" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-oss.repo \
&& echo "gpgcheck=0" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-oss.repo \
&& echo "enabled=1" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-oss.repo \
&& $PKG_MANAGER clean all \
&& $PKG_MANAGER install -y app-protect-module-oss \
&& $PKG_MANAGER clean all \
&& rm -rf /var/cache/$PKG_MANAGER \
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log
# Expose port
EXPOSE 80
# Define stop signal
STOPSIGNAL SIGQUIT
# Set default command
CMD ["nginx", "-g", "daemon off;"]
# syntax=docker/dockerfile:1
# Supported OS_CODENAME's are: focal/jammy
ARG OS_CODENAME=jammy
# Base image
FROM ubuntu:${OS_CODENAME}
# Install NGINX OSS and NGINX App Protect WAF v5 module
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \
--mount=type=secret,id=nginx-key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \
apt-get update \
&& apt-get install -y \
apt-transport-https \
lsb-release \
ca-certificates \
wget \
gnupg2 \
ubuntu-keyring \
&& wget -qO - https://nginx.org/keys/nginx_signing.key | gpg --dearmor | \
tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null \
&& gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg \
&& printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
http://nginx.org/packages/mainline/ubuntu `lsb_release -cs` nginx\n" | \
tee /etc/apt/sources.list.d/nginx.list \
&& wget -qO - https://cs.nginx.com/static/keys/nginx_signing.key | gpg --dearmor | \
tee /usr/share/keyrings/nginx-static-archive-keyring.gpg >/dev/null \
&& gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-static-archive-keyring.gpg \
&& printf "deb [signed-by=/usr/share/keyrings/nginx-static-archive-keyring.gpg] \
https://pkgs.nginx.com/app-protect-x-oss/ubuntu `lsb_release -cs` nginx-plus\n" | \
tee /etc/apt/sources.list.d/nginx-app-protect.list \
&& wget -P /etc/apt/apt.conf.d https://cs.nginx.com/static/files/90pkgs-nginx \
&& apt-get update \
&& DEBIAN_FRONTEND="noninteractive" apt-get install -y nginx=1.25.5-1~`lsb_release -cs` app-protect-module-oss \
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Expose port
EXPOSE 80
# Define stop signal
STOPSIGNAL SIGQUIT
# Set default command
CMD ["nginx", "-g", "daemon off;"]
You are ready to Build the image.
NGINX Plus Dockerfile
# syntax=docker/dockerfile:1
# Supported OS_VER's are 3.16/3.17/3.19
ARG OS_VER="3.19"
# Base image
FROM alpine:${OS_VER}
# Install NGINX Plus and NGINX App Protect WAF v5 module
RUN --mount=type=secret,id=nginx-crt,dst=/etc/apk/cert.pem,mode=0644 \
--mount=type=secret,id=nginx-key,dst=/etc/apk/cert.key,mode=0644 \
wget -O /etc/apk/keys/nginx_signing.rsa.pub https://cs.nginx.com/static/keys/nginx_signing.rsa.pub \
&& printf "https://pkgs.nginx.com/plus/alpine/v`egrep -o '^[0-9]+\.[0-9]+' /etc/alpine-release`/main\n" | \
tee -a /etc/apk/repositories \
&& printf "https://pkgs.nginx.com/app-protect-x-plus/alpine/v`egrep -o '^[0-9]+\.[0-9]+' /etc/alpine-release`/main\n" | \
tee -a /etc/apk/repositories \
&& apk update \
&& apk add app-protect-module-plus \
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log \
&& rm -rf /var/cache/apk/*
# Expose port
EXPOSE 80
# Define stop signal
STOPSIGNAL SIGQUIT
# Set default command
CMD ["nginx", "-g", "daemon off;"]
# syntax=docker/dockerfile:1
# Base image
FROM amazonlinux:2
# Install NGINX Plus and NGINX App Protect WAF v5 module
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \
--mount=type=secret,id=nginx-key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \
amazon-linux-extras enable epel \
&& yum clean metadata \
&& yum -y install wget ca-certificates epel-release shadow-utils \
&& wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/nginx-plus-amazon2.repo \
&& echo "[app-protect-x-plus]" > /etc/yum.repos.d/app-protect-7-x-plus.repo \
&& echo "name=nginx-app-protect repo" >> /etc/yum.repos.d/app-protect-7-x-plus.repo \
&& echo "baseurl=https://pkgs.nginx.com/app-protect-x-plus/centos/7/\$basearch/" >> /etc/yum.repos.d/app-protect-7-x-plus.repo \
&& echo "sslclientcert=/etc/ssl/nginx/nginx-repo.crt" >> /etc/yum.repos.d/app-protect-7-x-plus.repo \
&& echo "sslclientkey=/etc/ssl/nginx/nginx-repo.key" >> /etc/yum.repos.d/app-protect-7-x-plus.repo \
&& echo "gpgcheck=0" >> /etc/yum.repos.d/app-protect-7-x-plus.repo \
&& echo "enabled=1" >> /etc/yum.repos.d/app-protect-7-x-plus.repo \
&& yum -y install app-protect-module-plus \
&& yum clean all \
&& rm -rf /var/cache/yum \
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log
# Expose port
EXPOSE 80
# Define stop signal
STOPSIGNAL SIGQUIT
# Set default command
CMD ["nginx", "-g", "daemon off;"]
# syntax=docker/dockerfile:1
# Base image
FROM centos:7
# Install NGINX Plus and NGINX App Protect WAF v5 module
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \
--mount=type=secret,id=nginx-key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \
yum -y install wget ca-certificates epel-release \
&& wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/nginx-plus-7.4.repo \
&& echo "[app-protect-x-plus]" > /etc/yum.repos.d/app-protect-7-x-plus.repo \
&& echo "name=nginx-app-protect repo" >> /etc/yum.repos.d/app-protect-7-x-plus.repo \
&& echo "baseurl=https://pkgs.nginx.com/app-protect-x-plus/centos/7/\$basearch/" >> /etc/yum.repos.d/app-protect-7-x-plus.repo \
&& echo "sslclientcert=/etc/ssl/nginx/nginx-repo.crt" >> /etc/yum.repos.d/app-protect-7-x-plus.repo \
&& echo "sslclientkey=/etc/ssl/nginx/nginx-repo.key" >> /etc/yum.repos.d/app-protect-7-x-plus.repo \
&& echo "gpgcheck=0" >> /etc/yum.repos.d/app-protect-7-x-plus.repo \
&& echo "enabled=1" >> /etc/yum.repos.d/app-protect-7-x-plus.repo \
&& yum -y install app-protect-module-plus \
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log \
&& yum clean all \
&& rm -rf /var/cache/yum
# Expose port
EXPOSE 80
# Define stop signal
STOPSIGNAL SIGQUIT
# Set default command
CMD ["nginx", "-g", "daemon off;"]
# syntax=docker/dockerfile:1
# Supported OS_CODENAME's are: bullseye/bookworm
ARG OS_CODENAME=bookworm
# Base image
FROM debian:${OS_CODENAME}
# Install NGINX Plus and NGINX App Protect WAF v5 module
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \
--mount=type=secret,id=nginx-key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \
apt-get update \
&& apt-get install -y \
apt-transport-https \
lsb-release \
ca-certificates \
wget \
gnupg2 \
debian-archive-keyring \
&& wget -qO - https://cs.nginx.com/static/keys/nginx_signing.key | \
gpg --dearmor | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null \
&& gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg \
&& printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
https://pkgs.nginx.com/plus/debian `lsb_release -cs` nginx-plus\n" | \
tee /etc/apt/sources.list.d/nginx-plus.list \
&& printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
https://pkgs.nginx.com/app-protect-x-plus/debian `lsb_release -cs` nginx-plus\n" | \
tee /etc/apt/sources.list.d/nginx-app-protect.list \
&& wget -P /etc/apt/apt.conf.d https://cs.nginx.com/static/files/90pkgs-nginx \
&& apt-get update \
&& DEBIAN_FRONTEND="noninteractive" apt-get install -y app-protect-module-plus \
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Expose port
EXPOSE 80
# Define stop signal
STOPSIGNAL SIGQUIT
# Set default command
CMD ["nginx", "-g", "daemon off;"]
# syntax=docker/dockerfile:1
# Base image
FROM oraclelinux:8
# Install NGINX Plus and NGINX App Protect WAF v5 module
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \
--mount=type=secret,id=nginx-key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \
dnf -y install wget ca-certificates yum-utils \
&& wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/nginx-plus-8.repo \
&& echo "[app-protect-x-plus]" > /etc/yum.repos.d/app-protect-8-x-plus.repo \
&& echo "name=nginx-app-protect repo" >> /etc/yum.repos.d/app-protect-8-x-plus.repo \
&& echo "baseurl=https://pkgs.nginx.com/app-protect-x-plus/centos/8/\$basearch/" >> /etc/yum.repos.d/app-protect-8-x-plus.repo \
&& echo "sslclientcert=/etc/ssl/nginx/nginx-repo.crt" >> /etc/yum.repos.d/app-protect-8-x-plus.repo \
&& echo "sslclientkey=/etc/ssl/nginx/nginx-repo.key" >> /etc/yum.repos.d/app-protect-8-x-plus.repo \
&& echo "gpgcheck=0" >> /etc/yum.repos.d/app-protect-8-x-plus.repo \
&& echo "enabled=1" >> /etc/yum.repos.d/app-protect-8-x-plus.repo \
&& dnf clean all \
&& dnf -y install app-protect-module-plus \
&& dnf clean all \
&& rm -rf /var/cache/dnf \
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log
# Expose port
EXPOSE 80
# Define stop signal
STOPSIGNAL SIGQUIT
# Set default command
CMD ["nginx", "-g", "daemon off;"]
# syntax=docker/dockerfile:1
# Supported UBI_VERSION's are 7/8/9
ARG UBI_VERSION=9
# Base Image
FROM registry.access.redhat.com/ubi${UBI_VERSION}/ubi
# Define the ARG again after FROM to use it in this stage
ARG UBI_VERSION
# Install NGINX Plus and NGINX App Protect WAF v5 module
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \
--mount=type=secret,id=nginx-key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \
PKG_MANAGER=dnf; \
if [ "${UBI_VERSION}" = "7" ]; then \
PKG_MANAGER=yum; \
NGINX_PLUS_REPO="nginx-plus-7.4.repo"; \
elif [ "${UBI_VERSION}" = "9" ]; then \
NGINX_PLUS_REPO="plus-${UBI_VERSION}.repo"; \
else \
NGINX_PLUS_REPO="nginx-plus-${UBI_VERSION}.repo"; \
fi \
&& $PKG_MANAGER -y install wget ca-certificates \
&& wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/dependencies.repo \
&& wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/${NGINX_PLUS_REPO} \
&& echo "[app-protect-x-plus]" > /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-plus.repo \
&& echo "name=nginx-app-protect repo" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-plus.repo \
&& echo "baseurl=https://pkgs.nginx.com/app-protect-x-plus/centos/${UBI_VERSION}/\$basearch/" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-plus.repo \
&& echo "sslclientcert=/etc/ssl/nginx/nginx-repo.crt" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-plus.repo \
&& echo "sslclientkey=/etc/ssl/nginx/nginx-repo.key" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-plus.repo \
&& echo "gpgcheck=0" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-plus.repo \
&& echo "enabled=1" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-plus.repo \
&& $PKG_MANAGER clean all \
&& $PKG_MANAGER install -y app-protect-module-plus \
&& $PKG_MANAGER clean all \
&& rm -rf /var/cache/$PKG_MANAGER \
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log
# Expose port
EXPOSE 80
# Define stop signal
STOPSIGNAL SIGQUIT
# Set default command
CMD ["nginx", "-g", "daemon off;"]
# syntax=docker/dockerfile:1
# Supported OS_CODENAME's are: focal/jammy
ARG OS_CODENAME=jammy
# Base image
FROM ubuntu:${OS_CODENAME}
# Install NGINX Plus and NGINX App Protect WAF v5 module
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \
--mount=type=secret,id=nginx-key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \
apt-get update \
&& apt-get install -y \
apt-transport-https \
lsb-release \
ca-certificates \
wget \
gnupg2 \
ubuntu-keyring \
&& wget -qO - https://cs.nginx.com/static/keys/nginx_signing.key | \
gpg --dearmor | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null \
&& gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg \
&& printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
https://pkgs.nginx.com/plus/ubuntu `lsb_release -cs` nginx-plus\n" | \
tee /etc/apt/sources.list.d/nginx-plus.list \
&& printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
https://pkgs.nginx.com/app-protect-x-plus/ubuntu `lsb_release -cs` nginx-plus\n" | \
tee /etc/apt/sources.list.d/nginx-app-protect.list \
&& wget -P /etc/apt/apt.conf.d https://cs.nginx.com/static/files/90pkgs-nginx \
&& apt-get update \
&& DEBIAN_FRONTEND="noninteractive" apt-get install -y app-protect-module-plus \
&& ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Expose port
EXPOSE 80
# Define stop signal
STOPSIGNAL SIGQUIT
# Set default command
CMD ["nginx", "-g", "daemon off;"]
Build Image
Never upload your NGINX App Protect WAF v5 images to a public container registry such as Docker Hub. Doing so violates your license agreement.
To build the image, execute the following command in the directory containing the nginx-repo.crt
, nginx-repo.key
, and Dockerfile
. Here, nginx-app-protect-5
is an example image tag.
sudo docker build --no-cache \
--secret id=nginx-crt,src=nginx-repo.crt \
--secret id=nginx-key,src=nginx-repo.key \
-t nginx-app-protect-5 .
Next, push it to your private image repository, ensuring it’s accessible to your Kubernetes cluster.
Pull the chart
Login to the registry:
helm registry login --username=<JWT Token> --password=none private-registry.nginx.com
Pull the chart:
helm pull oci://private-registry.nginx.com/nap/nginx-app-protect --version <release-version> --untar
Change your working directory to nginx-app-protect:
cd nginx-app-protect
Deployment
-
Set NGINX Docker Image and Tag
Update the appprotect.nginx.image.repository and appprotect.nginx.image.tag in values.yaml with your built NGINX image.
-
Set NGINX JWT License
Update the appprotect.config.nginxJWT in values.yaml with your JWT License Token.
-
Set Docker Registry Credentials
In values.yaml, update the dockerConfigJson to contain the base64 encoded Docker registration credentials
echo '{ "auths": { "private-registry.nginx.com": { "username": "<JWT Token>", "password": "none" } } }' | base64 -w 0
OR create the secret using the following command:
kubectl create secret docker-registry regcred -n <namespace> \ --docker-server=private-registry.nginx.com \ --docker-username=<JWT Token> \ --docker-password=none
-
Deploy the Helm Chart
Use the following command to deploy the Helm chart:
helm install <release-name> .
Replace
<release-name>
with your desired release name. -
Verify the Deployment
Use the following commands to verify the deployment:
kubectl get pods -n <namespace> kubectl get svc -n <namespace>
Replace
with the namespace specified in the values.yaml.
Use compiled Policy and Logging Profile bundles in NGINX
In this setup, copy your compiled policy and logging profile bundles to /mnt/nap5_bundles_pv_data
on a cluster node. Make sure that input files are accessible to UID 101. Then, in your NGINX configuration, refer to these files from /etc/app_protect/bundles
.
For example, to apply custom_policy.tgz
that you’ve placed in /mnt/nap5_bundles_pv_data/
, use:
app_protect_policy_file "/etc/app_protect/bundles/custom_policy.tgz";
The NGINX configuration is found in the values.yaml file appprotect.config.nginxConf
.
The bundles path and the host path can be configured in appprotect.storage
.
Configuration
This table lists the configurable parameters of the NGINX App Protect chart and their default values.
It should help you quickly understand the referenced configuration settings in the values.yaml
file.
To use the mTLS Configuration options, read the Secure Traffic Between NGINX and App Protect Enforcer using mTLS topic.
Section | Key | Description | Default Value |
---|---|---|---|
Namespace | namespace | The target Kubernetes namespace where the Helm chart will be deployed. | N/A |
App Protect Configuration | appprotect.replicas | The number of replicas of the Nginx App Protect deployment. | 1 |
appprotect.readOnlyRootFilesystem | Specifies if the root filesystem is read-only. | false | |
appprotect.annotations | Custom annotations for the deployment. | {} | |
NGINX Configuration | appprotect.nginx.image.repository | Docker image repository for NGINX. | <your-private-registry>/nginx-app-protect-5 |
appprotect.nginx.image.tag | Docker image tag for NGINX. | latest | |
appprotect.nginx.imagePullPolicy | Image pull policy. | IfNotPresent | |
appprotect.nginx.resources | The resources of the NGINX container. | requests: cpu=10m,memory=16Mi | |
WAF Config Manager | appprotect.wafConfigMgr.image.repository | Docker image repository for the WAF Configuration Manager. | private-registry.nginx.com/nap/waf-config-mgr |
appprotect.wafConfigMgr.image.tag | Docker image tag for the WAF Configuration Manager. | 5.6.0 | |
appprotect.wafConfigMgr.imagePullPolicy | Image pull policy. | IfNotPresent | |
appprotect.wafConfigMgr.resources | The resources of the WAF Config Manager container. | requests: cpu=10m,memory=16Mi | |
WAF Enforcer | appprotect.wafEnforcer.image.repository | Docker image repository for the WAF Enforcer. | private-registry.nginx.com/nap/waf-enforcer |
appprotect.wafEnforcer.image.tag | Docker image tag for the WAF Enforcer. | 5.6.0 | |
appprotect.wafEnforcer.imagePullPolicy | Image pull policy. | IfNotPresent | |
appprotect.wafEnforcer.env.enforcerPort | Port for the WAF Enforcer. | 50000 | |
appprotect.wafEnforcer.resources | The resources of the WAF Enforcer container. | requests: cpu=20m,memory=256Mi | |
Config | appprotect.config.name | The name of the ConfigMap used by the NGINX container. | nginx-config |
appprotect.config.annotations | The annotations of the ConfigMap. | {} | |
appprotect.config.nginxJWT | JWT license for NGINX. | "" | |
appprotect.config.nginxConf | NGINX configuration file content. | See values.yaml | |
appprotect.config.nginxDefault | Default server block configuration for NGINX. | {} | |
appprotect.config.entries | Extra entries of the ConfigMap for customizing NGINX configuration. | {} | |
mTLS Configuration | appprotect.mTLS.serverCert | The base64-encoded TLS certificate for the App Protect Enforcer (server). | "" |
appprotect.mTLS.serverKey | The base64-encoded TLS key for the App Protect Enforcer (server). | "" | |
appprotect.mTLS.serverCACert | The base64-encoded TLS CA certificate for the App Protect Enforcer (server). | "" | |
appprotect.mTLS.clientCert | The base64-encoded TLS certificate for the NGINX (client). | "" | |
appprotect.mTLS.clientKey | The base64-encoded TLS key for the NGINX (client). | "" | |
appprotect.mTLS.clientCACert | The base64-encoded TLS CA certificate for the NGINX (client). | "" | |
Extra Volumes | appprotect.volumes | The extra volumes of the NGINX container. | [] |
Extra Volume Mounts | appprotect.volumeMounts | The extra volume mounts of the NGINX container. | [] |
Service | appprotect.service.nginx.ports.port | Service port. | 80 |
appprotect.service.nginx.ports.protocol | Protocol used. | TCP | |
appprotect.service.nginx.ports.targetPort | Target port inside the container. | 80 | |
appprotect.service.nginx.type | Service type. | NodePort | |
Storage Configuration | appprotect.storage.bundlesPath.name | Bundles volume name used by WAF Config Manager container for storing policy bundles | app-protect-bundles |
appprotect.storage.bundlesPath.mountPath | Bundles mount path used by WAF Config Manager container, which is the path to the app_protect_policy_file in nginx.conf. | /etc/app_protect/bundles | |
appprotect.storage.pv.hostPath | Host path for persistent volume. | /mnt/nap5_bundles_pv_data | |
appprotect.storage.pvc.bundlesPvc.storageClass | Storage class for PVC. | manual | |
appprotect.storage.pvc.bundlesPvc.storageRequest | Storage request size. | 2Gi | |
Docker Configuration | dockerConfigJson | A base64-encoded string representing the Docker registry credentials in JSON format. | N/A |
Upgrade the chart
To upgrade the release <release-name>
:
helm upgrade <release-name> .
Uninstall the chart
To uninstall/delete the release <release-name>
:
helm uninstall <release-name>