Kubernetes
This page describes how to install F5 WAF for NGINX using Kubernetes.
It explains the common steps necessary for any Kubernetes-based deployment, then provides details specific to Helm or Manifests.
To complete this guide, you will need the following pre-requisites:
- A functional Kubernetes cluster
- An active F5 WAF for NGINX subscription (Purchased or trial)
- Docker
You will need Helm installed for a Helm-based deployment.
You should read the IP intelligence and Secure traffic using mTLS topics for additional set-up configuration if you want to use them immediately.
There is another optional topic to Add a read-only filesystem for Kubernetes
To review supported operating systems, read the Technical specifications topic.
- Log in to MyF5.
- Go to My Products & Plans > Subscriptions to see your active subscriptions.
- Find your NGINX subscription, and select the Subscription ID for details.
- Download the SSL Certificate and Private Key files from the subscription page.
In the same folder as your credential files, create a Dockerfile based on your desired operating system image using an example from the following sections.
Alternatively, you may want make your own image based on a Dockerfile using the official NGINX image:
Dockerfile based on official image
This example uses NGINX Open Source as a base: it requires NGINX to be installed as a package from the official repository, instead of being compiled from source.
# syntax=docker/dockerfile:1
# Base image
FROM nginx:1.25.5-bookworm
# Install F5 WAF for NGINX 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
If you are not using usingcustom_log_format.json
or the IP intelligence feature, you should remove any references to them from your 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 F5 WAF for NGINX 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
# 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 F5 WAF for NGINX 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:2023
# Install NGINX OSS and F5 WAF for NGINX 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 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/amzn/2023/\$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-oss.repo \
&& echo "name=nginx-app-protect repo" >> /etc/yum.repos.d/app-protect-oss.repo \
&& echo "baseurl=https://pkgs.nginx.com/app-protect-x-oss/amzn/2023/\$basearch/" >> /etc/yum.repos.d/app-protect-oss.repo \
&& echo "sslclientcert=/etc/ssl/nginx/nginx-repo.crt" >> /etc/yum.repos.d/app-protect-oss.repo \
&& echo "sslclientkey=/etc/ssl/nginx/nginx-repo.key" >> /etc/yum.repos.d/app-protect-oss.repo \
&& echo "gpgcheck=0" >> /etc/yum.repos.d/app-protect-oss.repo \
&& echo "enabled=1" >> /etc/yum.repos.d/app-protect-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 amazonlinux:2023
# Install NGINX Plus and F5 WAF for NGINX v5 module
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.cert,mode=0644 \
--mount=type=secret,id=nginx-key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \
yum -y install wget ca-certificates shadow-utils \
&& wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/plus-amazonlinux2023.repo \
&& echo "[app-protect-x-plus]" > /etc/yum.repos.d/app-protect-plus.repo \
&& echo "name=nginx-app-protect repo" >> /etc/yum.repos.d/app-protect-plus.repo \
&& echo "baseurl=https://pkgs.nginx.com/app-protect-x-plus/amzn/2023/\$basearch/" >> /etc/yum.repos.d/app-protect-plus.repo \
&& echo "sslclientcert=/etc/ssl/nginx/nginx-repo.cert" >> /etc/yum.repos.d/app-protect-plus.repo \
&& echo "sslclientkey=/etc/ssl/nginx/nginx-repo.key" >> /etc/yum.repos.d/app-protect-plus.repo \
&& echo "gpgcheck=0" >> /etc/yum.repos.d/app-protect-plus.repo \
&& echo "enabled=1" >> /etc/yum.repos.d/app-protect-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
# Supported OS_CODENAME's are: bullseye/bookworm
ARG OS_CODENAME=bookworm
# Base image
FROM debian:${OS_CODENAME}
# Install NGINX OSS and F5 WAF for NGINX 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
# Supported OS_CODENAME's are: bullseye/bookworm
ARG OS_CODENAME=bookworm
# Base image
FROM debian:${OS_CODENAME}
# Install NGINX OSS and F5 WAF for NGINX 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 F5 WAF for NGINX 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
# Base image
FROM oraclelinux:8
# Install NGINX Plus and F5 WAF for NGINX v5 module
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.cert,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.cert" >> /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=8
# 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 F5 WAF for NGINX 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 UBI_VERSION's are 7/8/9
ARG UBI_VERSION=8
# 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 F5 WAF for NGINX v5 module
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.cert,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.cert" >> /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 UBI_VERSION's are 7/8/9
ARG UBI_VERSION=8
# 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 F5 WAF for NGINX 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
# Base Image
FROM rockylinux:9
# Install NGINX Plus and F5 WAF for NGINX v5 module
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.cert,mode=0644 \
--mount=type=secret,id=nginx-key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \
dnf -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.cert" >> /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 \
&& dnf clean all \
&& dnf install -y 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
# Base Image
FROM rockylinux:9
# Install NGINX OSS and F5 WAF for NGINX 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/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 \
&& dnf clean all \
&& dnf install -y 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
# Base Image
FROM rockylinux:9
# Install NGINX Plus and F5 WAF for NGINX v5 module
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.cert,mode=0644 \
--mount=type=secret,id=nginx-key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \
dnf -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.cert" >> /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 \
&& dnf clean all \
&& dnf install -y 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 OS_CODENAME's are: focal/jammy
ARG OS_CODENAME=jammy
# Base image
FROM ubuntu:${OS_CODENAME}
# Install NGINX OSS and F5 WAF for NGINX 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;"]
# 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 F5 WAF for NGINX v5 module
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.cert,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;"]
Your folder should contain the following files:
- nginx-repo.cert
- nginx-repo.key
- Dockerfile
To build an image, use the following command, replacing <your-image-name>
as appropriate:
sudo docker build --no-cache --platform linux/amd64 \
--secret id=nginx-crt,src=nginx-repo.crt \
--secret id=nginx-key,src=nginx-repo.key \
-t <your-image-name> .
Once you have built the image, push it to your private image repository, which should be accessible to your Kubernetes cluster.
From this point, the steps change based on your installation method:
- Log in to MyF5.
- Go to My Products & Plans > Subscriptions to see your active subscriptions.
- Find your NGINX subscription, and select the Subscription ID for details.
- Download the JSON Web Token file from the subscription page.
To get the Helm chart, first configure Docker for the F5 Container Registry.
Create a directory and copy your certificate and key to this directory:
mkdir -p /etc/docker/certs.d/private-registry.nginx.com
cp <path-to-your-nginx-repo.crt> /etc/docker/certs.d/private-registry.nginx.com/client.cert
cp <path-to-your-nginx-repo.key> /etc/docker/certs.d/private-registry.nginx.com/client.key
Then use helm pull
to get the chart, replacing <release-version>
:
helm pull oci://private-registry.nginx.com/nap/nginx-app-protect --version <release-version> --untar
Change the working directory afterwards:
cd nginx-app-protect
You will need to edit the values.yaml
file for a few changes:
- Update appprotect.nginx.image.repository and appprotect.nginx.image.tag with the image name chosen during when building the Docker image.
- Update appprotect.config.nginxJWT with your JSON web token
- Update dockerConfigJson to contain the base64 encoded Docker registration credentials
You can encode your credentials with the following command:
echo '{
"auths": {
"private-registry.nginx.com": {
"username": "<JWT Token>",
"password": "none"
}
}
}' | base64 -w 0```
Alternatively, you can use kubectl
to create a secret:
kubectl create secret docker-registry regcred -n <namespace> \
--docker-server=private-registry.nginx.com \
--docker-username=<JWT Token> \
--docker-password=none
The <JWT Token>
argument should be the contents of the file, not the file itself. Ensure there are no additional characters such as extra whitespace.
Once you have updated values.yaml
, you can install F5 WAF for NGINX using helm install
:
helm install <release-name> .
You can verify the deployment is successful with kubectl get
, replacing namespace
accordingly:
kubectl get pods -n <namespace>
kubectl get svc -n <namespace>
At this stage, you have finished deploying F5 WAF for NGINX and can look at Post-installation checks.
This table lists the configurable parameters of the F5 WAF for NGINX Helm chart and their default values.
To understand the mTLS Configuration options, view the Secure traffic using mTLS topic.
Topic | Parameter | Description | Default value |
---|---|---|---|
Namespace | namespace | The target Kubernetes namespace where the Helm chart will be deployed. | N/A |
F5 WAF for NGINX Configuration | appprotect.replicas | The number of replicas for the F5 WAF for NGINX 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 | |
WAF IP Intelligence | _appprotect.wafIpIntelligence.enable | Enable or disable the use of the IP intelligence container | false |
appprotect.wafIpIntelligence.image.repository | Docker image repository for the WAF IP Intelligence. | private-registry.nginx.com/nap/waf-ip-intelligence | |
appprotect.wafIpIntelligence.image.tag | Docker image tag for the WAF Enforcer. | 5.6.0 | |
appprotect.wafIpIntelligence.imagePullPolicy | Image pull policy. | IfNotPresent | |
appprotect.wafIpIntelligence.resources | The resources of the WAF Enforcer container. | requests: cpu=10m,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 |
Once you have installed F5 WAF for NGINX, you must load it as a module in the main context of your NGINX configuration.
load_module modules/ngx_http_app_protect_module.so;
The Enforcer address must be added at the http context:
app_protect_enforcer_address 127.0.0.1:50000;
And finally, F5 WAF for NGINX can enabled on a http, server or location context:
app_protect_enable on;
You should only enable F5 WAF for NGINX on proxy_pass and grpc_pass locations.
Here are two examples of how these additions could look in configuration files:
Before you can start the Manifest deployment, you need a Kubernetes secret for the Docker registry.
You can create the secret using kubectl create
:
kubectl create secret docker-registry regcred --docker-server=private-registry.nginx.com --docker-username=<JWT Token> --docker-password=none
The <JWT Token>
argument should be the contents of the file, not the file itself. Ensure there are no additional characters such as extra whitespace.
The default configuration provided creates two replicas, each hosting NGINX and WAF services together in a single Kubernetes pod.
Create all of these files in a single folder (Such as /manifests
).
In each file, replace <your-private-registry>/waf:<your-tag>
with your actual image tag.
This configuration uses a hostPath backed persistent volume claim.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nap5-deployment
spec:
selector:
matchLabels:
app: nap5
replicas: 2
template:
metadata:
labels:
app: nap5
spec:
imagePullSecrets:
- name: regcred
containers:
- name: nginx
image: <your-private-registry>/waf:<your-tag>
imagePullPolicy: IfNotPresent
volumeMounts:
- name: app-protect-bd-config
mountPath: /opt/app_protect/bd_config
- name: app-protect-config
mountPath: /opt/app_protect/config
- name: waf-enforcer
image: private-registry.nginx.com/nap/waf-enforcer:<version-tag>
imagePullPolicy: IfNotPresent
env:
- name: ENFORCER_PORT
value: "50000"
volumeMounts:
- name: app-protect-bd-config
mountPath: /opt/app_protect/bd_config
- name: waf-config-mgr
image: private-registry.nginx.com/nap/waf-config-mgr:<version-tag>
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- all
volumeMounts:
- name: app-protect-bd-config
mountPath: /opt/app_protect/bd_config
- name: app-protect-config
mountPath: /opt/app_protect/config
- name: app-protect-bundles
mountPath: /etc/app_protect/bundles
volumes:
- name: app-protect-bd-config
emptyDir: {}
- name: app-protect-config
emptyDir: {}
- name: app-protect-bundles
persistentVolumeClaim:
claimName: nap5-bundles-pvc
apiVersion: apps/v1
kind: Deployment
metadata:
name: nap5-deployment
spec:
selector:
matchLabels:
app: nap5
replicas: 2
template:
metadata:
labels:
app: nap5
spec:
imagePullSecrets:
- name: regcred
containers:
- name: nginx
image: <your-private-registry>/waf:<your-tag>
imagePullPolicy: IfNotPresent
volumeMounts:
- name: app-protect-bd-config
mountPath: /opt/app_protect/bd_config
- name: app-protect-config
mountPath: /opt/app_protect/config
- name: waf-enforcer
image: private-registry.nginx.com/nap/waf-enforcer:<version-tag>
imagePullPolicy: IfNotPresent
env:
- name: ENFORCER_PORT
value: "50000"
volumeMounts:
- name: app-protect-bd-config
mountPath: /opt/app_protect/bd_config
- name: waf-config-mgr
image: private-registry.nginx.com/nap/waf-config-mgr:<version-tag>
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- all
volumeMounts:
- name: app-protect-bd-config
mountPath: /opt/app_protect/bd_config
- name: app-protect-config
mountPath: /opt/app_protect/config
- name: app-protect-bundles
mountPath: /etc/app_protect/bundles
volumes:
- name: app-protect-bd-config
emptyDir: {}
- name: app-protect-config
emptyDir: {}
- name: app-protect-bundles
persistentVolumeClaim:
claimName: nap5-bundles-pvc
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
selector:
app: nap5
ports:
- protocol: TCP
port: 80
targetPort: 80
type: NodePort
From the folder containing the YAML files from the previous step (Suggested as /manifests
), deploy F5 WAF for NGINX using kubectl
:
kubectl apply -f manifests/
It will apply all the configuration defined in the files to your Kubernetes cluster.
You can then check the status of the deployment with kubectl get
:
kubectl get deployments
kubectl get pods
kubectl get services
You should see output similar to the following:
deployment.apps/nap5-deployment created
service/nginx created
persistentvolume/nap5-bundles-pv created
persistentvolumeclaim/nap5-bundles-pvc created
At this stage, you have finished deploying F5 WAF for NGINX and can look at Post-installation checks.
The following steps check that F5 WAF for NGINX enforcement is operational.
They should be ran in the environment with the WAF components.
Check that the three processes for F5 WAF for NGINX are running using ps aux
:
- bd-socket-plugin
- nginx: master process
- nginx: worker process
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 8 1.3 2.4 3486948 399092 ? Sl 09:11 0:02 /usr/share/ts/bin/bd-socket-plugin tmm_count 4 proc_cpuinfo_cpu_mhz 2000000 total_xml_memory 307200000 total_umu_max_size 3129344 sys_max_account_id 1024 no_static_config
root 14 0.0 0.1 71060 26680 ? S 09:11 0:00 nginx: master process /usr/sbin/nginx -c /tmp/policy/test_nginx.conf -g daemon off;
root 26 0.0 0.3 99236 52092 ? S 09:12 0:00 nginx: worker process
root 28 0.0 0.0 11788 2920 pts/0 Ss 09:12 0:00 bash
root 43 0.0 0.0 47460 3412 pts/0 R+ 09:14 0:00 ps aux
Verify there are no errors in the file /var/log/nginx/error.log
and that the policy compiled successfully:
2020/05/10 13:21:04 [notice] 402#402: APP_PROTECT { "event": "configuration_load_start", "configSetFile": "/opt/f5waf/config/config_set.json" }
2020/05/10 13:21:04 [notice] 402#402: APP_PROTECT policy 'app_protect_default_policy' from: /etc/app_protect/conf/NginxDefaultPolicy.json compiled successfully
2020/05/10 13:21:04 [notice] 402#402: APP_PROTECT { "event": "configuration_load_success", "software_version": "1.1.1", "attack_signatures_package":{"revision_datetime":"2019-07-16T12:21:31Z"},"completed_successfully":true}
2020/05/10 13:21:04 [notice] 402#402: using the "epoll" event method
2020/05/10 13:21:04 [notice] 402#402: nginx/1.17.6 (nginx-plus-r20)
2020/05/10 13:21:04 [notice] 402#402: built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
2020/05/10 13:21:04 [notice] 402#402: OS: Linux 3.10.0-957.27.2.el7.x86_64
2020/05/10 13:21:04 [notice] 402#402: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2020/05/10 13:21:04 [notice] 406#406: start worker processes
2020/05/10 13:21:04 [notice] 406#406: start worker process 407
Check that sending an attack signature in a request returns a response block page containing a support ID:
Request:
http://10.240.185.211/?a=<script>
Response:
The requested URL was rejected. Please consult with your administrator.
Your support ID is: 9847191526422998597
[Go Back]
If your policy includes JSON/XML profiles, check /var/log/app_protect/bd-socket-plugin.log
for possible errors:
grep '|ERR' /var/log/app_protect/bd-socket-plugin.log
Verify that Enforcement functionality is working by checking the following request is rejected:
curl "localhost/<script>"
Or from an external host:
curl "<node-external-ip>:<node-port>/<script>"
Once you have successfully installed F5 WAF for NGINX, there are some topics you may want to follow afterwards:
- Configure NGINX features with F5 WAF, to see common configurations
- Configure policies, to begin customizing your deployment
- Converter tools, to convert existing resources from a BIG-IP environment
- Changelog, to view information from the latest releases