From c735847b44de49f86e8a83da4a7fde98f34a945b Mon Sep 17 00:00:00 2001 From: Raanan <59834489+rnitzan@users.noreply.github.com> Date: Wed, 26 Nov 2025 11:42:48 +0200 Subject: [PATCH 1/4] Create alpine-plus.md for Dockerfile configuration Add Dockerfile for Alpine Plus with NGINX support --- content/includes/dos/dockerfiles/alpine-plus.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 content/includes/dos/dockerfiles/alpine-plus.md diff --git a/content/includes/dos/dockerfiles/alpine-plus.md b/content/includes/dos/dockerfiles/alpine-plus.md new file mode 100644 index 000000000..736689084 --- /dev/null +++ b/content/includes/dos/dockerfiles/alpine-plus.md @@ -0,0 +1,16 @@ +--- +--- + +```dockerfile +# syntax=docker/dockerfile:1 + +# Supported OS_VER's are 3.21/3.22 +ARG OS_VER="3.22" + +# Base image +FROM alpine:${OS_VER} + +# Install NGINX Plus and F5 DOS for NGINX + + +``` From f5a3f2e093cbaf3e1a8f39cb629d72a2cd93bac5 Mon Sep 17 00:00:00 2001 From: "r.nitzan@f5.com" Date: Wed, 26 Nov 2025 15:03:04 +0200 Subject: [PATCH 2/4] add k8s to dos --- ...{alpine-plus.md => alpine-plus-dos-waf.md} | 0 .../dos/dockerfiles/alpine-plus-dos.md | 38 ++ .../dos/dockerfiles/amazon-plus-dos-waf.md | 0 .../dos/dockerfiles/amazon-plus-dos.md | 34 ++ .../dos/dockerfiles/debian-plus-dos-waf.md | 0 .../dos/dockerfiles/debian-plus-dos.md | 37 ++ .../dos/dockerfiles/rhel8-plus-dos-waf.md | 0 .../dos/dockerfiles/rhel8-plus-dos.md | 44 ++ .../dos/dockerfiles/rhel9-plus-dos-waf.md | 0 .../dos/dockerfiles/rhel9-plus-dos.md | 44 ++ .../dos/dockerfiles/rocky9-plus-dos-waf.md | 0 .../dos/dockerfiles/rocky9-plus-dos.md | 36 ++ .../dos/dockerfiles/ubuntu-plus-dos-waf.md | 0 .../dos/dockerfiles/ubuntu-plus-dos.md | 40 ++ .../nap-dos/deployment-guide/kubernetes.md | 505 ++++++++++++++++++ 15 files changed, 778 insertions(+) rename content/includes/dos/dockerfiles/{alpine-plus.md => alpine-plus-dos-waf.md} (100%) create mode 100644 content/includes/dos/dockerfiles/alpine-plus-dos.md create mode 100644 content/includes/dos/dockerfiles/amazon-plus-dos-waf.md create mode 100644 content/includes/dos/dockerfiles/amazon-plus-dos.md create mode 100644 content/includes/dos/dockerfiles/debian-plus-dos-waf.md create mode 100644 content/includes/dos/dockerfiles/debian-plus-dos.md create mode 100644 content/includes/dos/dockerfiles/rhel8-plus-dos-waf.md create mode 100644 content/includes/dos/dockerfiles/rhel8-plus-dos.md create mode 100644 content/includes/dos/dockerfiles/rhel9-plus-dos-waf.md create mode 100644 content/includes/dos/dockerfiles/rhel9-plus-dos.md create mode 100644 content/includes/dos/dockerfiles/rocky9-plus-dos-waf.md create mode 100644 content/includes/dos/dockerfiles/rocky9-plus-dos.md create mode 100644 content/includes/dos/dockerfiles/ubuntu-plus-dos-waf.md create mode 100644 content/includes/dos/dockerfiles/ubuntu-plus-dos.md create mode 100644 content/nap-dos/deployment-guide/kubernetes.md diff --git a/content/includes/dos/dockerfiles/alpine-plus.md b/content/includes/dos/dockerfiles/alpine-plus-dos-waf.md similarity index 100% rename from content/includes/dos/dockerfiles/alpine-plus.md rename to content/includes/dos/dockerfiles/alpine-plus-dos-waf.md diff --git a/content/includes/dos/dockerfiles/alpine-plus-dos.md b/content/includes/dos/dockerfiles/alpine-plus-dos.md new file mode 100644 index 000000000..df18076e3 --- /dev/null +++ b/content/includes/dos/dockerfiles/alpine-plus-dos.md @@ -0,0 +1,38 @@ +--- +--- + +```dockerfile +# syntax=docker/dockerfile:1 + +# Supported OS_VER's are 3.21/3.22 +ARG OS_VER="3.22" + +# Base image +FROM alpine:${OS_VER} + +# Install F5 DoS for NGINX +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 \ + --mount=type=secret,id=license-jwt,dst=license.jwt,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-dos/alpine/v`egrep -o '^[0-9]+\.[0-9]+' /etc/alpine-release`/main\n" | tee -a /etc/apk/repositories \ + && apk update \ + && apk add app-protect-dos \ + && cat license.jwt > /etc/nginx/license.jwt \ + && ln -sf /dev/stdout /var/log/nginx/access.log \ + && ln -sf /dev/stderr /var/log/nginx/error.log \ + && rm -rf /var/cache/apk/* + +# Copy configuration files: +COPY nginx.conf custom_log_format.json /etc/nginx/ +COPY entrypoint.sh /root/ +RUN chmod +x /root/entrypoint.sh + +EXPOSE 80 + +STOPSIGNAL SIGQUIT + +CMD ["sh", "/root/entrypoint.sh"] + +``` \ No newline at end of file diff --git a/content/includes/dos/dockerfiles/amazon-plus-dos-waf.md b/content/includes/dos/dockerfiles/amazon-plus-dos-waf.md new file mode 100644 index 000000000..e69de29bb diff --git a/content/includes/dos/dockerfiles/amazon-plus-dos.md b/content/includes/dos/dockerfiles/amazon-plus-dos.md new file mode 100644 index 000000000..aeff507ad --- /dev/null +++ b/content/includes/dos/dockerfiles/amazon-plus-dos.md @@ -0,0 +1,34 @@ +--- +--- + +```dockerfile + +# For AmazonLinux 2023: +FROM amazonlinux:2023 + +# Install F5 DoS for NGINX +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 \ + --mount=type=secret,id=license-jwt,dst=license.jwt,mode=0644 \ + dnf -y install ca-certificates \ + && curl -o /etc/yum.repos.d/plus-amazonlinux2023.repo https://cs.nginx.com/static/files/plus-amazonlinux2023.repo \ + && curl -o /etc/yum.repos.d/app-protect-dos-amazonlinux2023.repo https://cs.nginx.com/static/files/app-protect-dos-amazonlinux2023.repo \ + && dnf install -y app-protect-dos \ + && cat license.jwt > /etc/nginx/license.jwt \ + && 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 + +# Copy configuration files: +COPY nginx.conf custom_log_format.json /etc/nginx/ +COPY entrypoint.sh /root/ +RUN chmod +x /root/entrypoint.sh + +EXPOSE 80 + +STOPSIGNAL SIGQUIT + +CMD ["sh", "/root/entrypoint.sh"] + +``` \ No newline at end of file diff --git a/content/includes/dos/dockerfiles/debian-plus-dos-waf.md b/content/includes/dos/dockerfiles/debian-plus-dos-waf.md new file mode 100644 index 000000000..e69de29bb diff --git a/content/includes/dos/dockerfiles/debian-plus-dos.md b/content/includes/dos/dockerfiles/debian-plus-dos.md new file mode 100644 index 000000000..2f544d367 --- /dev/null +++ b/content/includes/dos/dockerfiles/debian-plus-dos.md @@ -0,0 +1,37 @@ +--- +--- + +```dockerfile + +# Where can be bullseye/bookworm +FROM debian:bullseye + +# Install F5 DoS for NGINX +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 \ + --mount=type=secret,id=license-jwt,dst=license.jwt,mode=0644 \ + apt-get update \ + && DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends apt-transport-https lsb-release ca-certificates wget gnupg2 debian-archive-keyring \ + && mkdir -p /etc/ssl/nginx/ /etc/nginx/ \ + && wget -qO - https://cs.nginx.com/static/keys/nginx_signing.key | gpg --dearmor | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null \ + && printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/plus/debian $(lsb_release -cs) nginx-plus\n" > /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-dos/debian $(lsb_release -cs) nginx-plus\n" > /etc/apt/sources.list.d/nginx-app-protect-dos.list \ + && wget -P /etc/apt/apt.conf.d https://cs.nginx.com/static/files/90pkgs-nginx \ + && DEBIAN_FRONTEND="noninteractive" apt-get install -y app-protect-dos \ + && cat license.jwt > /etc/nginx/license.jwt \ + && apt-get remove --purge --auto-remove -y \ + && rm -rf /var/lib/apt/lists/* \ + && ln -sf /dev/stdout /var/log/nginx/access.log \ + && ln -sf /dev/stderr /var/log/nginx/error.log + +COPY nginx.conf /etc/nginx/ +COPY entrypoint.sh /root/ +RUN chmod +x /root/entrypoint.sh + +EXPOSE 80 + +STOPSIGNAL SIGQUIT + +CMD ["sh", "/root/entrypoint.sh"] + +``` \ No newline at end of file diff --git a/content/includes/dos/dockerfiles/rhel8-plus-dos-waf.md b/content/includes/dos/dockerfiles/rhel8-plus-dos-waf.md new file mode 100644 index 000000000..e69de29bb diff --git a/content/includes/dos/dockerfiles/rhel8-plus-dos.md b/content/includes/dos/dockerfiles/rhel8-plus-dos.md new file mode 100644 index 000000000..12be0b12c --- /dev/null +++ b/content/includes/dos/dockerfiles/rhel8-plus-dos.md @@ -0,0 +1,44 @@ +--- +--- + +```dockerfile +# For UBI 8 +FROM registry.access.redhat.com/ubi8 + +ARG RHEL_ORG +ARG RHEL_ACTIVATION_KEY + +# Install F5 DoS for NGINX +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 \ + --mount=type=secret,id=license-jwt,dst=license.jwt,mode=0644 \ + subscription-manager register --org=${RHEL_ORG} --activationkey=${RHEL_ACTIVATION_KEY} \ + && subscription-manager refresh \ + && subscription-manager attach --auto || true \ + && subscription-manager repos --enable=rhel-8-for-x86_64-baseos-rpms \ + && subscription-manager repos --enable=rhel-8-for-x86_64-appstream-rpms \ + && dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm \ + && dnf -y install ca-certificates \ + && curl -o /etc/yum.repos.d/plus-8.repo https://cs.nginx.com/static/files/plus-8.repo \ + && curl -o /etc/yum.repos.d/app-protect-dos-8.repo https://cs.nginx.com/static/files/app-protect-dos-8.repo \ + && dnf -y install app-protect-dos \ + && cat license.jwt > /etc/nginx/license.jwt \ + && rm /etc/yum.repos.d/plus-8.repo \ + && rm /etc/yum.repos.d/app-protect-dos-8.repo \ + && dnf 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 + +# Copy configuration files: +COPY nginx.conf custom_log_format.json /etc/nginx/ +COPY entrypoint.sh /root/ +RUN chmod +x /root/entrypoint.sh + +EXPOSE 80 + +STOPSIGNAL SIGQUIT + +CMD ["sh", "/root/entrypoint.sh"] + +``` \ No newline at end of file diff --git a/content/includes/dos/dockerfiles/rhel9-plus-dos-waf.md b/content/includes/dos/dockerfiles/rhel9-plus-dos-waf.md new file mode 100644 index 000000000..e69de29bb diff --git a/content/includes/dos/dockerfiles/rhel9-plus-dos.md b/content/includes/dos/dockerfiles/rhel9-plus-dos.md new file mode 100644 index 000000000..f9bd2550d --- /dev/null +++ b/content/includes/dos/dockerfiles/rhel9-plus-dos.md @@ -0,0 +1,44 @@ +--- +--- + +```dockerfile +# For UBI 9 +FROM registry.access.redhat.com/ubi9 + +ARG RHEL_ORG +ARG RHEL_ACTIVATION_KEY + +# Install F5 DoS for NGINX +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 \ + --mount=type=secret,id=license-jwt,dst=license.jwt,mode=0644 \ + subscription-manager register --org=${RHEL_ORG} --activationkey=${RHEL_ACTIVATION_KEY} \ + && subscription-manager refresh \ + && subscription-manager attach --auto || true \ + && subscription-manager repos --enable=rhel-9-for-x86_64-baseos-rpms \ + && subscription-manager repos --enable=rhel-9-for-x86_64-appstream-rpms \ + && dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm \ + && dnf -y install ca-certificates \ + && curl -o /etc/yum.repos.d/plus-9.repo https://cs.nginx.com/static/files/plus-9.repo \ + && curl -o /etc/yum.repos.d/app-protect-dos-9.repo https://cs.nginx.com/static/files/app-protect-dos-9.repo \ + && dnf -y install app-protect-dos \ + && cat license.jwt > /etc/nginx/license.jwt \ + && rm /etc/yum.repos.d/plus-9.repo \ + && rm /etc/yum.repos.d/app-protect-dos-9.repo \ + && dnf 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 + +# Copy configuration files: +COPY nginx.conf custom_log_format.json /etc/nginx/ +COPY entrypoint.sh /root/ +RUN chmod +x /root/entrypoint.sh + +EXPOSE 80 + +STOPSIGNAL SIGQUIT + +CMD ["sh", "/root/entrypoint.sh"] + +``` \ No newline at end of file diff --git a/content/includes/dos/dockerfiles/rocky9-plus-dos-waf.md b/content/includes/dos/dockerfiles/rocky9-plus-dos-waf.md new file mode 100644 index 000000000..e69de29bb diff --git a/content/includes/dos/dockerfiles/rocky9-plus-dos.md b/content/includes/dos/dockerfiles/rocky9-plus-dos.md new file mode 100644 index 000000000..b779713b2 --- /dev/null +++ b/content/includes/dos/dockerfiles/rocky9-plus-dos.md @@ -0,0 +1,36 @@ +--- +--- + +```dockerfile + +# syntax=docker/dockerfile:1 +# For Rocky Linux 9 +FROM rockylinux:9 + +# Install F5 DoS for NGINX: +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 \ + --mount=type=secret,id=license-jwt,dst=license.jwt,mode=0644 \ + dnf -y install ca-certificates epel-release 'dnf-command(config-manager)' \ + && curl -o /etc/yum.repos.d/plus-9.repo https://cs.nginx.com/static/files/plus-9.repo \ + && curl -o /etc/yum.repos.d/app-protect-dos-9.repo https://cs.nginx.com/static/files/app-protect-dos-9.repo \ + && dnf config-manager --set-enabled crb \ + && dnf install -y app-protect-dos \ + && cat license.jwt > /etc/nginx/license.jwt \ + && 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 + +# Copy configuration files: +COPY nginx.conf custom_log_format.json /etc/nginx/ +COPY entrypoint.sh /root/ +RUN chmod +x /root/entrypoint.sh + +EXPOSE 80 + +STOPSIGNAL SIGQUIT + +CMD ["sh", "/root/entrypoint.sh"] + +``` \ No newline at end of file diff --git a/content/includes/dos/dockerfiles/ubuntu-plus-dos-waf.md b/content/includes/dos/dockerfiles/ubuntu-plus-dos-waf.md new file mode 100644 index 000000000..e69de29bb diff --git a/content/includes/dos/dockerfiles/ubuntu-plus-dos.md b/content/includes/dos/dockerfiles/ubuntu-plus-dos.md new file mode 100644 index 000000000..90db16e60 --- /dev/null +++ b/content/includes/dos/dockerfiles/ubuntu-plus-dos.md @@ -0,0 +1,40 @@ +--- +--- + +```dockerfile + +# syntax=docker/dockerfile:1 +# For Ubuntu + +# Where version can be: jammy/noble +FROM ubuntu:noble + +# Setup repository keys +RUN apt-get update && \ + +# Install F5 DoS for NGINX +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 \ + --mount=type=secret,id=license-jwt,dst=license.jwt,mode=0644 \ + apt-get update \ + && apt-get install -y --no-install-recommends 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 \ + && printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/plus/ubuntu $(lsb_release -cs) nginx-plus\n" > /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-dos/ubuntu $(lsb_release -cs) nginx-plus\n" > /etc/apt/sources.list.d/nginx-app-protect-dos.list \ + && wget -P /etc/apt/apt.conf.d https://cs.nginx.com/static/files/90pkgs-nginx \ + && DEBIAN_FRONTEND="noninteractive" apt-get install -y app-protect-dos \ + && cat license.jwt > /etc/nginx/license.jwt \ + && apt-get remove --purge --auto-remove -y && rm -rf /var/lib/apt/lists/* \ + && ln -sf /dev/stdout /var/log/nginx/access.log \ + && ln -sf /dev/stderr /var/log/nginx/error.log + +COPY nginx.conf /etc/nginx/ +COPY entrypoint.sh /root/ +RUN chmod +x /root/entrypoint.sh + +EXPOSE 80 + +STOPSIGNAL SIGQUIT + +CMD ["sh", "/root/entrypoint.sh"] +``` \ No newline at end of file diff --git a/content/nap-dos/deployment-guide/kubernetes.md b/content/nap-dos/deployment-guide/kubernetes.md new file mode 100644 index 000000000..5df9c78d0 --- /dev/null +++ b/content/nap-dos/deployment-guide/kubernetes.md @@ -0,0 +1,505 @@ +--- +# We use sentence case and present imperative tone +title: "Kubernetes" +# Weights are assigned in increments of 100: determines sorting order +weight: 200 +# Creates a table of contents and sidebar, useful for large documents +toc: true +# Types have a 1:1 relationship with Hugo archetypes, so you shouldn't need to change this +nd-content-type: how-to +nd-product: WAF +--- + +This page describes how to install F5 DOS for NGINX using Kubernetes. + +It explains the common steps necessary for any Kubernetes-based deployment, then provides details specific to Helm or Manifests. + +## Before you begin + +To complete this guide, you will need the following pre-requisites: + +- A functional Kubernetes cluster +- An active F5 DIS for NGINX subscription (Purchased or trial) +- [Docker](https://docs.docker.com/get-started/get-docker/) + +To review supported operating systems, read the [Releases]({{< ref "/nap-dos/releases" >}}) topic. + +## Download your subscription credentials + +{{< include "licensing-and-reporting/download-certificates-from-myf5.md" >}} + +## Create a Dockerfile + +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. + +### Alpine Linux + +{{< tabs name="alpine-instructions" >}} + +{{% tab name="NGINX Plus" %}} + +{{< include "/dos/dockerfiles/alpine-plus-dos.md" >}} + +{{% /tab %}} + +{{< /tabs >}} + +### Amazon Linux + +{{< tabs name="amazon-instructions" >}} + +{{% tab name="NGINX Plus" %}} + +{{< include "/dos/dockerfiles/amazon-plus-dos.md" >}} + +{{% /tab %}} + +{{< /tabs >}} + +### Debian + +{{< tabs name="debian-instructions" >}} + +{{% tab name="NGINX Plus" %}} + +{{< include "/dos/dockerfiles/debian-plus-dos.md" >}} + +{{% /tab %}} + +{{< /tabs >}} + +### RHEL 8 + +{{< tabs name="rhel8-instructions" >}} + +{{% tab name="NGINX Plus" %}} + +{{< include "/dos/dockerfiles/rhel8-plus-dos.md" >}} + +{{% /tab %}} + +{{< /tabs >}} + +### RHEL 9 + +{{< tabs name="rhel9-instructions" >}} + +{{% tab name="NGINX Plus" %}} + +{{< include "/dos/dockerfiles/rhel9-plus-dos.md" >}} + +{{% /tab %}} + +{{< /tabs >}} + +### Rocky Linux 9 + +{{< tabs name="rocky-instructions" >}} + +{{% tab name="NGINX Plus" %}} + +{{< include "/dos/dockerfiles/rocky9-plus-dos.md" >}} + +{{% /tab %}} + +{{< /tabs >}} + +### Ubuntu + +{{< tabs name="ubuntu-instructions" >}} + +{{% tab name="NGINX Plus" %}} + +{{< include "/dos/dockerfiles/ubuntu-plus-dos.md" >}} + +{{% /tab %}} + +{{< /tabs >}} + +## Build the Docker image + +Your folder should contain the following files: + +- _nginx-repo.crt_ +- _nginx-repo.key_ +- _Dockerfile_ + +To build an image, use the following command, replacing `` as appropriate: + +```shell +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 . +``` + +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: + +- [Use Helm to install F5 WAF for NGINX](#use-helm-to-install-f5-waf-for-nginx) +- [Use Manifests to install F5 WAF for NGINX](#use-manifests-to-install-f5-waf-for-nginx) + +## Use Helm to install F5 WAF for NGINX + +### Download your JSON web token + +{{< include "licensing-and-reporting/download-jwt-from-myf5.md" >}} + +### Get the Helm chart + +To get the Helm chart, first configure Docker for the F5 Container Registry. + +{{< include "waf/install-services-registry.md" >}} + +Then use `helm pull` to get the chart, replacing ``: + +```shell +helm pull oci://private-registry.nginx.com/nap/nginx-app-protect --version --untar +``` + +Change the working directory afterwards: + +```shell +cd nginx-app-protect +``` + +### Deploy the Helm chart + +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](#build-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: + +```shell +echo '{ + "auths": { + "private-registry.nginx.com": { + "username": "", + "password": "none" + } + } +}' | base64 -w 0``` +``` + +Alternatively, you can use `kubectl` to create a secret: + +```shell +kubectl create secret docker-registry regcred -n \ + --docker-server=private-registry.nginx.com \ + --docker-username= \ + --docker-password=none +``` + +The `` 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`: + +```shell +helm install . +``` + +You can verify the deployment is successful with `kubectl get`, replacing `namespace` accordingly: + +```shell +kubectl get pods -n +kubectl get svc -n +``` + +{{< call-out "note" >}} + +At this stage, you have finished deploying F5 WAF for NGINX and can look at [Post-installation checks](#post-installation-checks). + +{{< /call-out >}} + +### Helm Chart parameters + +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]({{< ref "/waf/configure/secure-mtls.md" >}}) topic. + +{{< table >}} + +| **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. | \/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. | {{< version-waf-config-mgr >}} | +| | _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. | {{< version-waf-enforcer >}} | +| | _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. | {{< version-waf-ip-intelligence >}} | +| | _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 | + +{{< /table >}} + +## Use Manifests to install F5 WAF for NGINX + +### Update configuration files + +{{< include "waf/install-update-configuration.md" >}} + +### Create a Secret + +Before you can start the Manifest deployment, you need a Kubernetes secret for the Docker registry. + +You can create the secret using `kubectl create`: + +```shell +kubectl create secret docker-registry regcred --docker-server=private-registry.nginx.com --docker-username= --docker-password=none +``` + +The `` argument should be the _contents_ of the file, not the file itself. Ensure there are no additional characters such as extra whitespace. + +### Create Manifest files + +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 `/waf:` with your actual image tag. + +{{< tabs name="manifest-files" >}} + +{{% tab name="waf-storage.yaml" %}} + +{{< call-out "note" >}} + +This configuration uses a _hostPath_ backed persistent volume claim. + +{{< /call-out >}} + +```yaml +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: /waf: + 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: + 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: + 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 +``` + +{{% /tab %}} + +{{% tab name="waf-deployment.yaml" %}} + +```yaml +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: /waf: + 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: + 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: + 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 +``` + +{{% /tab %}} + +{{% tab name="waf-service.yaml" %}} + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: nginx +spec: + selector: + app: nap5 + ports: + - protocol: TCP + port: 80 + targetPort: 80 + type: NodePort +``` + +{{% /tab %}} + +{{< /tabs >}} + +### Start the Manifest deployment + +From the folder containing the YAML files from the previous step (Suggested as `/manifests`), deploy F5 WAF for NGINX using `kubectl`: + +```shell +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`: + +```shell +kubectl get deployments +kubectl get pods +kubectl get services +``` + +You should see output similar to the following: + +```text +deployment.apps/nap5-deployment created +service/nginx created +persistentvolume/nap5-bundles-pv created +persistentvolumeclaim/nap5-bundles-pvc created +``` + +{{< call-out "note" >}} + +At this stage, you have finished deploying F5 WAF for NGINX and can look at [Post-installation checks](#post-installation-checks). + +{{< /call-out >}} + +## Post-installation checks + +{{< include "waf/install-post-checks.md" >}} + +Or from an external host: + +```shell +curl ":/