diff --git a/content/includes/dos/dockerfiles/alpine-ebpf-manager.md b/content/includes/dos/dockerfiles/alpine-ebpf-manager.md
new file mode 100644
index 0000000000..0174515b51
--- /dev/null
+++ b/content/includes/dos/dockerfiles/alpine-ebpf-manager.md
@@ -0,0 +1,29 @@
+---
+---
+
+```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 ebpf manager for NGINX and create required nginx user
+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 \
+ set -x \
+ # Create nginx user/group first, to be consistent throughout Docker variants \
+ && addgroup -S -g 101 nginx \
+ && adduser -S -u 101 -G nginx -h /nonexistent -s /sbin/nologin nginx \
+ && 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-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-ebpf-manager \
+ && rm -rf /var/cache/apk/*
+
+STOPSIGNAL SIGQUIT
+
+CMD ["bash", "-c", "/usr/bin/ebpf_manager_dos 2>&1 | tee /shared/ebpf_dos.log"]
+```
\ No newline at end of file
diff --git a/content/includes/dos/dockerfiles/amazon-ebpf-manager.md b/content/includes/dos/dockerfiles/amazon-ebpf-manager.md
new file mode 100644
index 0000000000..25e1ac7fbd
--- /dev/null
+++ b/content/includes/dos/dockerfiles/amazon-ebpf-manager.md
@@ -0,0 +1,23 @@
+---
+---
+
+```dockerfile
+# For AmazonLinux 2023:
+FROM amazonlinux:2023
+
+# Install F5 DoS ebpf manager for NGINX and create required nginx user
+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 \
+ set -x \
+ && dnf -y install ca-certificates shadow-utils \
+ && groupadd --system --gid 101 nginx \
+ && useradd --system --gid nginx --no-create-home --home /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \
+ && 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-ebpf-manager \
+ && dnf clean all \
+ && rm -rf /var/cache/dnf
+
+STOPSIGNAL SIGQUIT
+
+CMD ["bash", "-c", "/usr/bin/ebpf_manager_dos 2>&1 | tee /shared/ebpf_dos.log"]
+```
\ 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 0000000000..490707482e
--- /dev/null
+++ b/content/includes/dos/dockerfiles/amazon-plus-dos-waf.md
@@ -0,0 +1,45 @@
+---
+---
+
+```dockerfile
+# syntax=docker/dockerfile:1
+FROM amazonlinux:2023
+
+# Install prerequisite packages:
+RUN dnf -y install ca-certificates
+
+# Add NGINX/NAP WAF/NAP DOS repositories:
+RUN 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 && \
+ curl -o /etc/yum.repos.d/app-protect-amazonlinux2023.repo https://cs.nginx.com/static/files/app-protect-amazonlinux2023.repo && \
+ curl -o /etc/yum.repos.d/dependencies.amazonlinux2023.repo https://cs.nginx.com/static/files/dependencies.amazonlinux2023.repo
+
+# Update the repository and install the most recent versions of the F5 WAF and F5 DoS for NGINX packages (which include NGINX Plus):
+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 \
+ set -x \
+ && dnf -y install ca-certificates shadow-utils \
+ && groupadd --system --gid 101 nginx \
+ && useradd --system --gid nginx --no-create-home --home /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \
+ && dnf -y install app-protect app-protect-dos \
+ && rm /etc/yum.repos.d/plus-amazonlinux2023.repo \
+ && rm /etc/yum.repos.d/app-protect-dos-amazonlinux2023.repo \
+ && dnf clean all \
+ && rm -rf /var/cache/dnf \
+ && rm -rf /var/cache/yum \
+ && ln -sf /dev/stdout /var/log/nginx/access.log \
+ && ln -sf /dev/stderr /var/log/nginx/error.log
+
+RUN nginx -v && admd -v
+RUN echo "RELEASE:" && cat /opt/app_protect/RELEASE && echo "VERSION:" && cat /opt/app_protect/VERSION
+
+# Copy configuration files:
+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-ebpf-manager.md b/content/includes/dos/dockerfiles/debian-ebpf-manager.md
new file mode 100644
index 0000000000..e07085279a
--- /dev/null
+++ b/content/includes/dos/dockerfiles/debian-ebpf-manager.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 \
+ set -x \
+ # Create nginx user/group first, to be consistent throughout Docker variants \
+ && groupadd --system --gid 101 nginx \
+ && useradd --system --gid nginx --no-create-home --home /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \
+ && DEBIAN_FRONTEND=noninteractive 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 \
+ && wget -qO - https://cs.nginx.com/static/keys/nginx_signing.key \
+ | gpg --dearmor \
+ | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null \
+ && echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/app-protect-dos/debian $(lsb_release -cs) nginx-plus" \
+ > /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 update \
+ && DEBIAN_FRONTEND=noninteractive apt-get install -y app-protect-dos-ebpf-manager \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/*
+
+STOPSIGNAL SIGQUIT
+
+CMD ["bash", "-c", "/usr/bin/ebpf_manager_dos 2>&1 | tee /shared/ebpf_dos.log"]
+```
\ 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 0000000000..36bcd75b40
--- /dev/null
+++ b/content/includes/dos/dockerfiles/debian-plus-dos-waf.md
@@ -0,0 +1,48 @@
+---
+---
+
+```dockerfile
+# Where version can be: bullseye/bookworm
+FROM debian:bullseye
+
+# Install prerequisite packages:
+RUN DEBIAN_FRONTEND=noninteractive 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 && \
+ wget -qO - https://cs.nginx.com/static/keys/nginx_signing.key | gpg --dearmor | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null && \
+ wget -qO - https://cs.nginx.com/static/keys/app-protect-security-updates.key | gpg --dearmor | tee /usr/share/keyrings/app-protect-security-updates.gpg > /dev/null
+
+# Add NGINX Plus, NGINX App Protect and F5 DoS for NGINX repository:
+RUN 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-dos/debian `lsb_release -cs` nginx-plus\n" | tee /etc/apt/sources.list.d/nginx-app-protect-dos.list \
+ && printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/app-protect/debian `lsb_release -cs` nginx-plus\n" | tee /etc/apt/sources.list.d/nginx-app-protect.list \
+ && printf "deb [signed-by=/usr/share/keyrings/app-protect-security-updates.gpg] https://pkgs.nginx.com/app-protect-security-updates/debian `lsb_release -cs` nginx-plus\n" | tee /etc/apt/sources.list.d/app-protect-security-updates.list
+
+# Download the apt configuration to `/etc/apt/apt.conf.d`:
+RUN wget -P /etc/apt/apt.conf.d https://cs.nginx.com/static/files/90pkgs-nginx
+
+# Update the repository and install the most recent versions of the F5 WAF and F5 DoS for NGINX packages (which includes NGINX Plus):
+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 \
+ set -x \
+ # Create nginx user/group first, to be consistent throughout Docker variants \
+ && groupadd --system --gid 101 nginx \
+ && useradd --system --gid nginx --no-create-home --home /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \
+ && DEBIAN_FRONTEND=noninteractive apt-get update \
+ && DEBIAN_FRONTEND=noninteractive apt-get install -y app-protect app-protect-dos \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/* \
+ && ln -sf /dev/stdout /var/log/nginx/access.log \
+ && ln -sf /dev/stderr /var/log/nginx/error.log
+
+RUN nginx -v && admd -v
+RUN echo "RELEASE:" && cat /opt/app_protect/RELEASE && echo "VERSION:" && cat /opt/app_protect/VERSION
+
+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.md b/content/includes/dos/dockerfiles/debian-plus-dos.md
index f94c4eb9e1..f6e18824c0 100644
--- a/content/includes/dos/dockerfiles/debian-plus-dos.md
+++ b/content/includes/dos/dockerfiles/debian-plus-dos.md
@@ -4,7 +4,7 @@ nd-product: F5DOSN
```dockerfile
-# Where can be bullseye/bookworm
+# Where can be bullseye/bookworm/trixie
FROM debian:bullseye
# Install F5 DoS for NGINX
diff --git a/content/includes/dos/dockerfiles/rhel10-ebpf-manager.md b/content/includes/dos/dockerfiles/rhel10-ebpf-manager.md
new file mode 100644
index 0000000000..6ccff4cdbe
--- /dev/null
+++ b/content/includes/dos/dockerfiles/rhel10-ebpf-manager.md
@@ -0,0 +1,30 @@
+---
+---
+
+```dockerfile
+# For UBI 10
+FROM registry.access.redhat.com/ubi10
+
+ARG RHEL_ORG
+ARG RHEL_ACTIVATION_KEY
+
+# Install F5 DoS ebpf manager for NGINX and create required nginx user
+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 \
+ set -x \
+ # Create nginx user/group first, to be consistent throughout Docker variants \
+ && groupadd --system --gid 101 nginx \
+ && useradd --system --gid nginx --no-create-home --home /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \
+ && dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-10.noarch.rpm \
+ && dnf -y install ca-certificates \
+ && curl -o /etc/yum.repos.d/app-protect-dos-10.repo https://cs.nginx.com/static/files/app-protect-dos-10.repo \
+ && dnf -y install app-protect-dos-ebpf-manager \
+ && rm /etc/yum.repos.d/app-protect-dos-10.repo \
+ && dnf clean all \
+ && rm -rf /var/cache/yum
+
+STOPSIGNAL SIGQUIT
+
+CMD ["bash", "-c", "/usr/bin/ebpf_manager_dos 2>&1 | tee /shared/ebpf_dos.log"]
+```
+
diff --git a/content/includes/dos/dockerfiles/rhel10-plus-dos.md b/content/includes/dos/dockerfiles/rhel10-plus-dos.md
new file mode 100644
index 0000000000..f0b4a3d515
--- /dev/null
+++ b/content/includes/dos/dockerfiles/rhel10-plus-dos.md
@@ -0,0 +1,46 @@
+---
+nd-product: F5DOSN
+---
+
+```dockerfile
+# For UBI 10
+FROM registry.access.redhat.com/ubi10
+
+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-10-for-x86_64-baseos-rpms \
+ && subscription-manager repos --enable=rhel-10-for-x86_64-appstream-rpms \
+ && dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-10.noarch.rpm \
+ && dnf -y install ca-certificates \
+ && curl -o /etc/yum.repos.d/plus-10.repo https://cs.nginx.com/static/files/plus-10.repo \
+ && curl -o /etc/yum.repos.d/app-protect-dos-10.repo https://cs.nginx.com/static/files/app-protect-dos-10.repo \
+ && dnf -y install app-protect-dos \
+ && cat license.jwt > /etc/nginx/license.jwt \
+ && rm /etc/yum.repos.d/plus-10.repo \
+ && rm /etc/yum.repos.d/app-protect-dos-10.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"]
+
+```
+
diff --git a/content/includes/dos/dockerfiles/rhel8-ebpf-manager.md b/content/includes/dos/dockerfiles/rhel8-ebpf-manager.md
new file mode 100644
index 0000000000..bf316a7592
--- /dev/null
+++ b/content/includes/dos/dockerfiles/rhel8-ebpf-manager.md
@@ -0,0 +1,29 @@
+---
+---
+
+```dockerfile
+# For UBI 8
+FROM registry.access.redhat.com/ubi8
+
+ARG RHEL_ORG
+ARG RHEL_ACTIVATION_KEY
+
+# Install F5 DoS ebpf manager for NGINX and create required nginx user
+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 \
+ set -x \
+ # Create nginx user/group first, to be consistent throughout Docker variants \
+ && groupadd --system --gid 101 nginx \
+ && useradd --system --gid nginx --no-create-home --home /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \
+ && 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/app-protect-dos-8.repo https://cs.nginx.com/static/files/app-protect-dos-8.repo \
+ && dnf -y install app-protect-dos-ebpf-manager \
+ && rm /etc/yum.repos.d/app-protect-dos-8.repo \
+ && dnf clean all \
+ && rm -rf /var/cache/yum
+
+STOPSIGNAL SIGQUIT
+
+CMD ["bash", "-c", "/usr/bin/ebpf_manager_dos 2>&1 | tee /shared/ebpf_dos.log"]
+```
\ No newline at end of file
diff --git a/content/includes/dos/dockerfiles/rhel9-ebpf-manager.md b/content/includes/dos/dockerfiles/rhel9-ebpf-manager.md
new file mode 100644
index 0000000000..640b585272
--- /dev/null
+++ b/content/includes/dos/dockerfiles/rhel9-ebpf-manager.md
@@ -0,0 +1,29 @@
+---
+---
+
+```dockerfile
+# For UBI 9
+FROM registry.access.redhat.com/ubi9
+
+ARG RHEL_ORG
+ARG RHEL_ACTIVATION_KEY
+
+# Install F5 DoS ebpf manager for NGINX and create required nginx user
+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 \
+ set -x \
+ # Create nginx user/group first, to be consistent throughout Docker variants \
+ && groupadd --system --gid 101 nginx \
+ && useradd --system --gid nginx --no-create-home --home /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \
+ && 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/app-protect-dos-9.repo https://cs.nginx.com/static/files/app-protect-dos-9.repo \
+ && dnf -y install app-protect-dos-ebpf-manager \
+ && rm /etc/yum.repos.d/app-protect-dos-9.repo \
+ && dnf clean all \
+ && rm -rf /var/cache/yum
+
+STOPSIGNAL SIGQUIT
+
+CMD ["bash", "-c", "/usr/bin/ebpf_manager_dos 2>&1 | tee /shared/ebpf_dos.log"]
+```
\ 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
deleted file mode 100644
index ba8f61085d..0000000000
--- a/content/includes/dos/dockerfiles/rhel9-plus-dos-waf.md
+++ /dev/null
@@ -1,3 +0,0 @@
----
-nd-product: F5DOSN
----
\ No newline at end of file
diff --git a/content/includes/dos/dockerfiles/rocky9-ebpf-manager.md b/content/includes/dos/dockerfiles/rocky9-ebpf-manager.md
new file mode 100644
index 0000000000..4aaad1d121
--- /dev/null
+++ b/content/includes/dos/dockerfiles/rocky9-ebpf-manager.md
@@ -0,0 +1,26 @@
+---
+---
+
+```dockerfile
+# syntax=docker/dockerfile:1
+# For Rocky Linux 9
+FROM rockylinux:9
+
+# Install F5 DoS ebpf manager for NGINX and create required nginx user
+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 \
+ set -x \
+ # Create nginx user/group first, to be consistent throughout Docker variants \
+ && groupadd --system --gid 101 nginx \
+ && useradd --system --gid nginx --no-create-home --home /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \
+ && dnf -y install ca-certificates epel-release 'dnf-command(config-manager)' \
+ && 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-ebpf-manager \
+ && dnf clean all \
+ && rm -rf /var/cache/dnf
+
+STOPSIGNAL SIGQUIT
+
+CMD ["bash", "-c", "/usr/bin/ebpf_manager_dos 2>&1 | tee /shared/ebpf_dos.log"]
+```
\ No newline at end of file
diff --git a/content/includes/dos/dockerfiles/ubuntu-ebpf-manager.md b/content/includes/dos/dockerfiles/ubuntu-ebpf-manager.md
new file mode 100644
index 0000000000..9db04c03f4
--- /dev/null
+++ b/content/includes/dos/dockerfiles/ubuntu-ebpf-manager.md
@@ -0,0 +1,41 @@
+---
+---
+
+```dockerfile
+# syntax=docker/dockerfile:1
+# For Ubuntu
+
+# Where version can be: jammy/noble
+FROM ubuntu:noble
+
+# Install F5 DoS ebpf manager for NGINX and create required nginx user
+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 \
+ set -x \
+ # Create nginx user/group first, to be consistent throughout Docker variants \
+ && groupadd --system --gid 101 nginx \
+ && useradd --system --gid nginx --no-create-home --home /nonexistent --comment "nginx user" --shell /bin/false --uid 101 nginx \
+ && DEBIAN_FRONTEND=noninteractive apt-get update \
+ && DEBIAN_FRONTEND=noninteractive 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 \
+ && echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/app-protect-dos/ubuntu $(lsb_release -cs) nginx-plus" \
+ > /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 update \
+ && DEBIAN_FRONTEND=noninteractive apt-get install -y app-protect-dos-ebpf-manager \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/*
+
+STOPSIGNAL SIGQUIT
+
+# Idle forever
+CMD ["bash", "-c", "/usr/bin/ebpf_manager_dos 2>&1 | tee /shared/ebpf_dos.log"]
+```
\ No newline at end of file
diff --git a/content/includes/dos/dos-arbitrator.md b/content/includes/dos/dos-arbitrator.md
new file mode 100644
index 0000000000..8981917a17
--- /dev/null
+++ b/content/includes/dos/dos-arbitrator.md
@@ -0,0 +1,57 @@
+---
+nd-docs: null
+nd-files:
+- content/nap-dos/deployment-guide/kubernetes.md
+- content/nap-dos/deployment-guide/kubernetes-with-L4-accelerated-mitigation..md
+---
+## F5 DoS for NGINX Arbitrator
+
+### Overview
+
+F5 DoS for NGINX arbitrator orchestrates all the running F5 DoS for NGINX instances to synchronize local/global attack start/stop.
+
+F5 DoS for NGINX arbitrator serves as a central coordinating component for managing multiple instances of App Protect DoS in a network. It is needed when there are more than one F5 DoS for NGINX instances. Its primary function is to ensure that all instances are aware of and share the same state for each protected object. Here's a clearer breakdown of how it works and why it's necessary:
+
+How F5 DoS for NGINX Arbitrator Works:
+
+- **Collecting State Periodically**: The arbitrator regularly collects the state information from all running instances of App Protect DoS. This collection occurs at set intervals, typically every 10 seconds.
+- **State Initialization for New Instances**: When a new App Protect DoS instance is created, it doesn't start with a blank or uninitialized state for a protected object. Instead, it retrieves the initial state for the protected object from the arbitrator.
+- **Updating State in Case of an Attack**: If an attack is detected by one of the App Protect DoS instances, that instance sends an attack notification to the arbitrator. The arbitrator then updates the state of the affected protected object to indicate that it is under attack. Importantly, this updated state is propagated to all other instances.
+
+### Why F5 DoS for NGINX Arbitrator is Necessary
+
+F5 DoS for NGINX Arbitrator is essential for several reasons:
+
+- **Global State Management**: Without the arbitrator, each individual instance of App Protect DoS would manage its own isolated state for each protected object. This isolation could lead to inconsistencies. For example, if instance A declared an attack on a protected object named "PO-Example," instance B would remain unaware of this attack, potentially leaving the object vulnerable.
+- **Uniform Attack Detection**: With the arbitrator in place, when instance A detects an attack on "PO-Example" and reports it to the arbitrator, the state of "PO-Example" is immediately updated to indicate an attack. This means that all instances, including instance B, are aware of the attack and can take appropriate measures to mitigate it.
+
+In summary, F5 DoS for NGINX Arbitrator acts as a central coordinator to maintain a consistent and up-to-date global state for protected objects across multiple instances of App Protect DoS. This coordination helps ensure that attacks are properly detected and mitigated, and that knowledge gained by one instance is efficiently shared with others, enhancing the overall security of the network.
+
+
+### F5 DoS for NGINX Arbitrator Deployment
+
+1. Pull the official F5 DoS for NGINX Arbitrator image with the command:
+
+ ```shell
+ docker pull docker-registry.nginx.com/nap-dos/app_protect_dos_arb:latest
+ ```
+
+2. Create a container based on this image, for example, `app-protect-dos-arb` container:
+
+ ```shell
+ docker run --name app_protect_dos_arb -p 3000:3000 -d docker-registry.nginx.com/nap-dos/app_protect_dos_arb
+ ```
+
+3. Verify that the `app-protect-dos-arb` container is up and running with the `docker ps` command.
+
+4. DNS records are required for F5 DoS for NGINX Arbitrator to work properly and be accessible by F5 DoS for NGINX servers. Ensure that the `svc-appprotect-dos-arb` or configured Arbitrator FQDN (with `app_protect_dos_arb_fqdn` directive) has a valid DNS resolution.
+ This step is necessary only for VM/Docker deployments with arbitrator. When the arbitrator is in the same Kubernetes namespace as F5 DoS for NGINX, this step is not needed.
+
+### Multi-VM Deployment
+
+The Arbitrator service is standalone. Once it is down, it can be seamlessly re-started. It will immediately recover all the needed information from F5 DoS for NGINX instances that communicate to it every 10 sec. It’s downtime is around 10-20 seconds which will not affect the F5 DoS for NGINX working.
+
+F5 DoS for NGINX Arbitrator service connects to port 3000 and can be seen under App Protect DoS instances. All modules try to connect to this service automatically. If it’s not accessible, each instance works in standalone mode.
+
+There is no such option for authentications between F5 DoS for NGINX servers and Arbitrator service like MTLS or password . Currently Arbitrator service is not exposed outside of the namespace. It is customers responsibility to isolate it from outside. It is applicable to any deployment of Arbitrator, not only to multi-VM.
+
diff --git a/content/includes/dos/dos-entrypoint.md b/content/includes/dos/dos-entrypoint.md
new file mode 100644
index 0000000000..8650cdffeb
--- /dev/null
+++ b/content/includes/dos/dos-entrypoint.md
@@ -0,0 +1,24 @@
+---
+nd-docs: null
+nd-files:
+- content/nap-dos/deployment-guide/learn-about-deployment.md
+- content/nap-dos/deployment-guide/kubernetes.md
+- content/nap-dos/deployment-guide/kubernetes-with-L4-accelerated-mitigation..md
+---
+
+```shell
+ #!/usr/bin/env bash
+
+ USER=nginx
+ LOGDIR=/var/log/adm
+
+ # prepare environment
+ mkdir -p /var/run/adm /tmp/cores ${LOGDIR}
+ chmod 755 /var/run/adm /tmp/cores ${LOGDIR}
+ chown ${USER}:${USER} /var/run/adm /tmp/cores ${LOGDIR}
+
+ # run processes
+ /bin/su -s /bin/bash -c "/usr/bin/adminstall > ${LOGDIR}/adminstall.log 2>&1" ${USER}
+ /bin/su -s /bin/bash -c "/usr/bin/admd -d --log info > ${LOGDIR}/admd.log 2>&1 &" ${USER}
+ /usr/sbin/nginx -g 'daemon off;'
+```
\ No newline at end of file
diff --git a/content/includes/dos/dos-waf-entrypoint.md b/content/includes/dos/dos-waf-entrypoint.md
new file mode 100644
index 0000000000..593bca48c7
--- /dev/null
+++ b/content/includes/dos/dos-waf-entrypoint.md
@@ -0,0 +1,26 @@
+---
+nd-docs: null
+nd-files:
+- content/nap-dos/deployment-guide/learn-about-deployment.md
+- content/nap-dos/deployment-guide/kubernetes.md
+- content/nap-dos/deployment-guide/kubernetes-with-L4-accelerated-mitigation..md
+---
+
+
+```shell
+ #!/usr/bin/env bash
+ USER=nginx
+ LOGDIR=/var/log/adm
+
+ # prepare environment
+ mkdir -p /var/run/adm /tmp/cores ${LOGDIR}
+ chmod 755 /var/run/adm /tmp/cores ${LOGDIR}
+ chown ${USER}:${USER} /var/run/adm /tmp/cores ${LOGDIR}
+
+ # run processes
+ /bin/su -s /bin/bash -c "/usr/bin/adminstall > ${LOGDIR}/adminstall.log 2>&1" ${USER}
+ /bin/su -s /bin/bash -c "/opt/app_protect/bin/bd_agent &" ${USER}
+ /bin/su -s /bin/bash -c "/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 2>&1 > /var/log/app_protect/bd-socket-plugin.log &" ${USER}
+ /bin/su -s /bin/bash -c "/usr/bin/admd -d --log info > ${LOGDIR}/admd.log 2>&1 &" ${USER}
+ /usr/sbin/nginx -g 'daemon off;'
+```
\ No newline at end of file
diff --git a/content/includes/dos/install-post-checks.md b/content/includes/dos/install-post-checks.md
new file mode 100644
index 0000000000..690da4e047
--- /dev/null
+++ b/content/includes/dos/install-post-checks.md
@@ -0,0 +1,91 @@
+---
+nd-docs: null
+nd-files:
+- content/nap-dos/deployment-guide/learn-about-deployment.md
+- content/nap-dos/deployment-guide/kubernetes.md
+- content/nap-dos/deployment-guide/kubernetes-with-L4-accelerated-mitigation..md
+---
+
+You can run the following commands to ensure that F5 DoS for NGINX enforcement is operational.
+
+1. Check that the three processes needed for F5 DoS for NGINX are running using `ps aux`:
+
+ - admd
+ - nginx: master process
+ - nginx: worker process
+
+ ```shell
+ USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
+ nginx 7759 0.0 0.0 113120 1200 ? Ss Sep06 0:00 /bin/sh -c /usr/bin/admd -d --log info > /var/log/adm/admd.log 2>&1
+ root 7765 0.0 0.0 87964 1464 ? Ss Sep06 0:00 nginx: master process /usr/sbin/nginx -g daemon off;
+ nginx 7767 0.0 0.1 615868 8188 ? Sl Sep06 0:04 nginx: worker process
+ ```
+
+2. Verify that there are no NGINX errors in the `/var/log/nginx/error.log` and that the policy compiled successfully:
+
+ ```shell
+ 2025/12/07 09:14:34 [notice] 675#675: APP_PROTECT_DOS { "event": "shared_memory_connected", "worker_pid": 675, "mode": "operational", "mode_changed": true }
+ 2025/12/07 09:14:34 [notice] 675#675: using the "epoll" event method
+ 2025/12/07 09:14:34 [notice] 675#675: APP_PROTECT_DOS { "event": "configuration_load_success", "software_version": "36+4.8.3-1.el8.ngx"}
+ 2025/12/07 09:14:34 [notice] 675#675: nginx/1.29.3 (nginx-plus-r36)
+ 2025/12/07 09:14:34 [notice] 675#675: built by gcc 8.5.0 20210514 (Red Hat 8.5.0-28) (GCC)
+ 2025/12/07 09:14:34 [notice] 675#675: OS: Linux 6.8.0-88-generic
+ 2025/12/07 09:14:34 [notice] 675#675: getrlimit(RLIMIT_NOFILE): 1048576:1048576
+ 2025/12/07 09:14:34 [notice] 675#675: start worker processes
+ 2025/12/07 09:14:34 [notice] 675#675: start worker process 679
+ 2025/12/07 09:14:34 [notice] 679#679: APP_PROTECT_DOS { "event": "shared_memory_connected", "worker_pid": 679, "mode": "operational", "mode_changed": true }
+ ```
+
+3. Check that by applying an attack, the attacker IP addresses are blocked while the good traffic pass through:
+
+ a. Simulate good traffic:
+
+ ```shell
+ echo "Start Good Traffic 2"
+ while true; do
+ curl ${VS}/good1 &
+ curl ${VS}/good2 &
+ curl ${VS}/good3 &
+ curl ${VS}/good4
+ sleep 0.1
+ done &
+ ```
+
+ b. After 7 minutes start the attack:
+
+ ```shell
+ while [ true ]
+ do
+ ab -B ${BAD_IP1} -l -r -n 1000000 -c 150 -d -H "Host: evil.net" -H "Pragma: no-cache" -H "Cache-Control: no-cache" -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" -H "Upgrade-Insecure-Requests: 1" -H "User-Agent: WireXBot" -H "x-requested-with:" -H "Referer: http://10.0.2.1/none.html" -H "Accept-Encoding: gzip, deflate" -H "Accept-Language: en-US" http://${VS}/ &
+ ab -B ${BAD_IP2} -l -r -n 1000000 -c 150 -d -H "Host: evil.net" -H "Pragma: no-cache" -H "Cache-Control: no-cache" -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" -H "Upgrade-Insecure-Requests: 1" -H "User-Agent: WireXBot" -H "x-requested-with:" -H "Referer: http://10.0.2.1/none.html" -H "Accept-Encoding: gzip, deflate" -H "Accept-Language: en-US" http://${VS}/ &
+ ab -B ${BAD_IP3} -l -r -n 1000000 -c 150 -d -s 10 -H "Host: evil.net" -H "Pragma: no-cache" -H "Cache-Control: no-cache" -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" -H "Upgrade-Insecure-Requests: 1" -H "User-Agent: WireXBot" -H "x-requested-with:" -H "Referer: http://10.0.2.1/none.html" -H "Accept-Encoding: gzip, deflate" -H "Accept-Language: en-US" http://${VS}/
+
+ killall ab
+ done
+ ```
+
+ c. See that the good traffic continue as usual while the attackers receive denial of service.
+
+4. For DOS with L4 accelerated mitigation enabled
+
+Check that the ebpf_manager_dos process needed for F5 DoS for NGINX is running using `ps aux | grep /usr/bin/ebpf_manager_dos`:
+
+```
+root 1 0.0 0.0 4324 3072 ? Ss 19:32 0:00 bash -c /usr/bin/ebpf_manager_dos 2>&1 | tee /shared/ebpf_dos.log
+root 7 0.2 0.0 1722732 14208 ? Sl 19:32 0:01 /usr/bin/ebpf_manager_dos
+root 46 0.0 0.0 3528 1792 pts/0 S+ 19:44 0:00 grep --color=auto /usr/bin/ebpf_manager_dos
+```
+
+Verify that there are no errors in the `/shared/ebpf_dos.log` and that the XDP program uploaded successfully:
+
+```[2025-12-02 19:32:12] INFO: Uninstall old eBPF maps and XDP program
+[2025-12-02 19:32:13] INFO: Install eBPF maps and XDP program
+[2025-12-02 19:32:13] INFO: Start ebpf manager
+[2025-12-02 19:32:13] INFO: Version: 36+4.8.3-1~noble
+[2025-12-02 19:32:13] INFO: Start Periodic task for update time
+[2025-12-02 19:32:13] INFO: Owner of the UDS has been changed to user nginx and group nginx.
+[2025-12-02 19:32:13] INFO: Permissions of the UDS have been changed successfully for user nginx and group nginx.
+[2025-12-02 19:32:13] INFO: Async Callback Server listening on unix:/shared/ebpf_manager_dos_uds
+```
+
+To check F5 WAF for NGINX alongside F5 DoS for NGINX, just perform the normal tests as specified at [Admin Guide](https://docs.nginx.com/waf/install/virtual-environment/#post-installation-checks)
diff --git a/content/includes/dos/k8s_arbitrator/appprotect-dos-arb.md b/content/includes/dos/k8s_arbitrator/appprotect-dos-arb.md
new file mode 100644
index 0000000000..13d30c533c
--- /dev/null
+++ b/content/includes/dos/k8s_arbitrator/appprotect-dos-arb.md
@@ -0,0 +1,25 @@
+---
+---
+
+```appprotect-dos-arb.yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: app-protect-dos-arb
+ namespace: app-protect-dos
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: appprotect-dos-arb
+ template:
+ metadata:
+ labels:
+ app: appprotect-dos-arb
+ spec:
+ containers:
+ - name: arb-svc
+ image: docker-registry.nginx.com/nap-dos/app_protect_dos_arb:latest
+ ports:
+ - containerPort: 3000
+```
\ No newline at end of file
diff --git a/content/includes/dos/k8s_arbitrator/svc-appprotect-dos-arb.md b/content/includes/dos/k8s_arbitrator/svc-appprotect-dos-arb.md
new file mode 100644
index 0000000000..5938fb99bc
--- /dev/null
+++ b/content/includes/dos/k8s_arbitrator/svc-appprotect-dos-arb.md
@@ -0,0 +1,19 @@
+---
+---
+
+```svc-appprotect-dos-arb.yaml
+apiVersion: v1
+kind: Service
+metadata:
+ name: svc-appprotect-dos-arb
+ namespace: app-protect-dos
+spec:
+ selector:
+ app: appprotect-dos-arb
+ ports:
+ - name: arb
+ port: 3000
+ protocol: TCP
+ targetPort: 3000
+ clusterIP: None
+```
\ No newline at end of file
diff --git a/content/includes/dos/k8s_manifest/dos-deployment.md b/content/includes/dos/k8s_manifest/dos-deployment.md
new file mode 100644
index 0000000000..fb2956c090
--- /dev/null
+++ b/content/includes/dos/k8s_manifest/dos-deployment.md
@@ -0,0 +1,105 @@
+---
+---
+
+```dos-deployment.yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: app-protect-dos
+ namespace: app-protect-dos
+ labels:
+ app: app-protect-dos
+spec:
+ replicas: 1
+ revisionHistoryLimit: 10
+ selector:
+ matchLabels:
+ app: app-protect-dos
+ strategy:
+ type: RollingUpdate
+ rollingUpdate:
+ maxSurge: 2
+ maxUnavailable: 1
+ template:
+ metadata:
+ labels:
+ app: app-protect-dos
+ spec:
+ containers:
+ - name: nginx-app-protect-dos
+ image: ${DOS_IMAGE_REPOSITORY}:${DOS_IMAGE_TAG}
+ imagePullPolicy: Always
+
+ command: ["/bin/bash", "-c"]
+ args:
+ - |
+ /root/entrypoint.sh
+
+ resources:
+ requests:
+ cpu: "200m"
+ memory: "500Mi"
+ limits:
+ cpu: "900m"
+ memory: "800Mi"
+
+ ports:
+ - containerPort: 80
+ name: web
+ - containerPort: 8090
+ name: probe
+ - containerPort: 8091
+ name: probe500
+
+ livenessProbe:
+ httpGet:
+ path: /app_protect_dos_liveness
+ port: 8090
+ initialDelaySeconds: 5
+ periodSeconds: 10
+
+ readinessProbe:
+ httpGet:
+ path: /app_protect_dos_readiness
+ port: 8090
+ initialDelaySeconds: 5
+ periodSeconds: 10
+
+ volumeMounts:
+ - name: shared-dir
+ mountPath: /shared/
+ - name: conf
+ mountPath: /etc/nginx/nginx.conf
+ subPath: nginx.conf
+ - name: log-default
+ mountPath: /etc/app_protect_dos/log-default.json
+ subPath: log-default.json
+ - name: license-token-volume
+ mountPath: /etc/nginx/license.jwt
+ subPath: license.jwt
+ readOnly: true
+
+ volumes:
+ - name: shared-dir
+ emptyDir: { }
+ - name: conf
+ configMap:
+ name: dos-nginx-conf
+ items:
+ - key: nginx.conf
+ path: nginx.conf
+ - name: log-default
+ configMap:
+ name: dos-log-default
+ defaultMode: 0644
+ items:
+ - key: log-default.json
+ path: log-default.json
+ - name: license-token-volume
+ secret:
+ secretName: license-token
+ items:
+ - key: license.jwt
+ path: license.jwt
+
+```
\ No newline at end of file
diff --git a/content/includes/dos/k8s_manifest/dos-log-default-configmap.md b/content/includes/dos/k8s_manifest/dos-log-default-configmap.md
new file mode 100644
index 0000000000..7d1d4848d6
--- /dev/null
+++ b/content/includes/dos/k8s_manifest/dos-log-default-configmap.md
@@ -0,0 +1,19 @@
+---
+---
+
+```dos-log-default-configmap.yaml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: dos-log-default
+ namespace: app-protect-dos
+data:
+ log-default.json: |
+ {
+ "filter": {
+ "traffic-mitigation-stats": "all",
+ "bad-actors": "all",
+ "attack-signatures": "all"
+ }
+ }
+```
\ No newline at end of file
diff --git a/content/includes/dos/k8s_manifest/dos-namespace.md b/content/includes/dos/k8s_manifest/dos-namespace.md
new file mode 100644
index 0000000000..1e91798fc0
--- /dev/null
+++ b/content/includes/dos/k8s_manifest/dos-namespace.md
@@ -0,0 +1,9 @@
+---
+---
+
+```dos-namespace.yaml
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: app-protect-dos
+```
\ No newline at end of file
diff --git a/content/includes/dos/k8s_manifest/dos-nginx-conf-configmap.md b/content/includes/dos/k8s_manifest/dos-nginx-conf-configmap.md
new file mode 100644
index 0000000000..5dbc9407fa
--- /dev/null
+++ b/content/includes/dos/k8s_manifest/dos-nginx-conf-configmap.md
@@ -0,0 +1,84 @@
+---
+---
+
+```dos-nginx-conf-configmap.yaml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: dos-nginx-conf
+ namespace: app-protect-dos
+data:
+ nginx.conf: |
+
+ user nginx;
+ worker_processes auto;
+ error_log /var/log/nginx/error.log error;
+ worker_rlimit_nofile 65535;
+
+ load_module modules/ngx_http_app_protect_dos_module.so;
+
+ working_directory /tmp/cores;
+
+ events {
+ worker_connections 65535;
+ }
+
+ http {
+
+ app_protect_dos_arb_fqdn svc-appprotect-dos-arb.arb.svc.cluster.local;
+
+ sendfile on;
+ tcp_nopush on;
+ keepalive_timeout 65;
+
+ log_format log_dos
+ ', vs_name_al=$app_protect_dos_vs_name, ip=$remote_addr, tls_fp=$app_protect_dos_tls_fp, '
+ 'outcome=$app_protect_dos_outcome, reason=$app_protect_dos_outcome_reason, '
+ 'ip_tls=$remote_addr:$app_protect_dos_tls_fp, ';
+
+ # Health endpoints for probes
+ app_protect_dos_liveness on; # uri:/app_protect_dos_liveness port:8090
+ app_protect_dos_readiness on; # uri:/app_protect_dos_readiness port:8090
+
+ server {
+ listen 8090;
+ server_name probe;
+
+ location / {
+ proxy_pass http://localhost:8091;
+ }
+ }
+
+ server {
+ listen 8091;
+ return 503;
+ }
+
+ server {
+ listen 80 reuseport;
+ server_name serv;
+ proxy_http_version 1.1;
+
+ access_log /var/log/nginx/access.log log_dos if=$loggable;
+ app_protect_dos_security_log_enable on;
+ app_protect_dos_security_log "/etc/app_protect_dos/log-default.json" syslog:server=10.197.30.219:5261;
+ app_protect_dos_policy_file "/etc/app_protect_dos/BADOSDefaultPolicy.json";
+
+ location / {
+ app_protect_dos_enable on;
+ app_protect_dos_name "main_serv";
+ app_protect_dos_monitor uri=http://serv:80/ protocol=http1;
+ proxy_pass http://127.0.0.1/proxy$request_uri;
+ }
+
+ location /proxy {
+ app_protect_dos_enable off;
+ client_max_body_size 0;
+ default_type text/html;
+ return 200 "Hello! I got your URI request - $request_uri\n";
+ }
+
+ }
+ }
+
+```
\ No newline at end of file
diff --git a/content/includes/dos/k8s_manifest/dos-service.md b/content/includes/dos/k8s_manifest/dos-service.md
new file mode 100644
index 0000000000..65bfdedb00
--- /dev/null
+++ b/content/includes/dos/k8s_manifest/dos-service.md
@@ -0,0 +1,18 @@
+---
+---
+
+```dos-service.yaml
+apiVersion: v1
+kind: Service
+metadata:
+ name: nap-dos
+ namespace: app-protect-dos
+spec:
+ ports:
+ - name: app
+ port: 80
+ protocol: TCP
+ selector:
+ app: app-protect-dos
+ type: NodePort
+```
\ No newline at end of file
diff --git a/content/includes/dos/k8s_with_ebpf_manifest/dos-deployment.md b/content/includes/dos/k8s_with_ebpf_manifest/dos-deployment.md
new file mode 100644
index 0000000000..ac0101b493
--- /dev/null
+++ b/content/includes/dos/k8s_with_ebpf_manifest/dos-deployment.md
@@ -0,0 +1,125 @@
+---
+---
+
+```dos-deployment.yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: app-protect-dos
+ namespace: app-protect-dos
+ labels:
+ app: app-protect-dos
+spec:
+ replicas: 1
+ revisionHistoryLimit: 10
+ selector:
+ matchLabels:
+ app: app-protect-dos
+ strategy:
+ type: RollingUpdate
+ rollingUpdate:
+ maxSurge: 2
+ maxUnavailable: 1
+ template:
+ metadata:
+ labels:
+ app: app-protect-dos
+ spec:
+ containers:
+ - name: nginx-app-protect-dos
+ image: ${DOS_IMAGE_REPOSITORY}:${DOS_IMAGE_TAG}
+ imagePullPolicy: Always
+
+ command: ["/bin/bash", "-c"]
+ args:
+ - |
+ /root/entrypoint.sh
+
+ resources:
+ requests:
+ cpu: "200m"
+ memory: "500Mi"
+ limits:
+ cpu: "900m"
+ memory: "800Mi"
+
+ ports:
+ - containerPort: 80
+ name: web
+ - containerPort: 8090
+ name: probe
+ - containerPort: 8091
+ name: probe500
+
+ livenessProbe:
+ httpGet:
+ path: /app_protect_dos_liveness
+ port: 8090
+ initialDelaySeconds: 5
+ periodSeconds: 10
+
+ readinessProbe:
+ httpGet:
+ path: /app_protect_dos_readiness
+ port: 8090
+ initialDelaySeconds: 5
+ periodSeconds: 10
+
+ volumeMounts:
+ - name: shared-dir
+ mountPath: /shared/
+ - name: bpf
+ mountPath: /sys/fs/bpf
+ - name: conf
+ mountPath: /etc/nginx/nginx.conf
+ subPath: nginx.conf
+ - name: log-default
+ mountPath: /etc/app_protect_dos/log-default.json
+ subPath: log-default.json
+ - name: license-token-volume
+ mountPath: /etc/nginx/license.jwt
+ subPath: license.jwt
+ readOnly: true
+
+ - name: dos-ebpf-manager
+ image: ${EBPF_IMAGE_REPOSITORY}:${EBPF_IMAGE_TAG}
+ securityContext:
+ privileged: true
+ env:
+ - name: POD_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.name # This is unique for every Pod
+ volumeMounts:
+ - name: shared-dir
+ mountPath: /shared/
+ - name: bpf
+ mountPath: /sys/fs/bpf
+
+ volumes:
+ - name: shared-dir
+ emptyDir: {}
+ - name: bpf
+ hostPath:
+ path: /sys/fs/bpf
+ type: DirectoryOrCreate
+ - name: conf
+ configMap:
+ name: dos-nginx-conf
+ items:
+ - key: nginx.conf
+ path: nginx.conf
+ - name: log-default
+ configMap:
+ name: dos-log-default
+ defaultMode: 0644
+ items:
+ - key: log-default.json
+ path: log-default.json
+ - name: license-token-volume
+ secret:
+ secretName: license-token
+ items:
+ - key: license.jwt
+ path: license.jwt
+```
\ No newline at end of file
diff --git a/content/includes/dos/k8s_with_ebpf_manifest/dos-log-default-configmap.md b/content/includes/dos/k8s_with_ebpf_manifest/dos-log-default-configmap.md
new file mode 100644
index 0000000000..7d1d4848d6
--- /dev/null
+++ b/content/includes/dos/k8s_with_ebpf_manifest/dos-log-default-configmap.md
@@ -0,0 +1,19 @@
+---
+---
+
+```dos-log-default-configmap.yaml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: dos-log-default
+ namespace: app-protect-dos
+data:
+ log-default.json: |
+ {
+ "filter": {
+ "traffic-mitigation-stats": "all",
+ "bad-actors": "all",
+ "attack-signatures": "all"
+ }
+ }
+```
\ No newline at end of file
diff --git a/content/includes/dos/k8s_with_ebpf_manifest/dos-namespace.md b/content/includes/dos/k8s_with_ebpf_manifest/dos-namespace.md
new file mode 100644
index 0000000000..1e91798fc0
--- /dev/null
+++ b/content/includes/dos/k8s_with_ebpf_manifest/dos-namespace.md
@@ -0,0 +1,9 @@
+---
+---
+
+```dos-namespace.yaml
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: app-protect-dos
+```
\ No newline at end of file
diff --git a/content/includes/dos/k8s_with_ebpf_manifest/dos-nginx-conf-configmap.md b/content/includes/dos/k8s_with_ebpf_manifest/dos-nginx-conf-configmap.md
new file mode 100644
index 0000000000..83900f2871
--- /dev/null
+++ b/content/includes/dos/k8s_with_ebpf_manifest/dos-nginx-conf-configmap.md
@@ -0,0 +1,83 @@
+---
+---
+
+```dos-nginx-conf-configmap.yaml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: dos-nginx-conf
+ namespace: app-protect-dos
+data:
+ nginx.conf: |
+
+ user nginx;
+ worker_processes auto;
+ error_log /var/log/nginx/error.log error;
+ worker_rlimit_nofile 65535;
+
+ load_module modules/ngx_http_app_protect_dos_module.so;
+
+ working_directory /tmp/cores;
+
+ events {
+ worker_connections 65535;
+ }
+
+ http {
+
+ app_protect_dos_arb_fqdn svc-appprotect-dos-arb.arb.svc.cluster.local;
+
+ sendfile on;
+ tcp_nopush on;
+ keepalive_timeout 65;
+
+ log_format log_dos
+ ', vs_name_al=$app_protect_dos_vs_name, ip=$remote_addr, tls_fp=$app_protect_dos_tls_fp, '
+ 'outcome=$app_protect_dos_outcome, reason=$app_protect_dos_outcome_reason, '
+ 'ip_tls=$remote_addr:$app_protect_dos_tls_fp, ';
+
+ app_protect_dos_accelerated_mitigation on syn_drop=on;
+
+ # Health endpoints for probes
+ app_protect_dos_liveness on; # uri:/app_protect_dos_liveness port:8090
+ app_protect_dos_readiness on; # uri:/app_protect_dos_readiness port:8090
+
+ server {
+ listen 8090;
+ server_name probe;
+
+ location / {
+ proxy_pass http://localhost:8091;
+ }
+ }
+
+ server {
+ listen 8091;
+ return 503;
+ }
+
+ server {
+ listen 80 reuseport;
+ server_name serv;
+
+ access_log /var/log/nginx/access.log log_dos if=$loggable;
+ app_protect_dos_security_log_enable on;
+ app_protect_dos_security_log "/etc/app_protect_dos/log-default.json" syslog:server=10.197.30.219:5261;
+ app_protect_dos_policy_file "/etc/app_protect_dos/BADOSDefaultPolicy.json";
+
+ location / {
+ app_protect_dos_enable on;
+ app_protect_dos_name "main_serv";
+ app_protect_dos_monitor uri=http://serv:80/ protocol=http1;
+ proxy_pass http://127.0.0.1/proxy$request_uri;
+ }
+
+ location /proxy {
+ app_protect_dos_enable off;
+ client_max_body_size 0;
+ default_type text/html;
+ return 200 "Hello! I got your URI request - $request_uri\n";
+ }
+ }
+ }
+```
\ No newline at end of file
diff --git a/content/includes/dos/k8s_with_ebpf_manifest/dos-service.md b/content/includes/dos/k8s_with_ebpf_manifest/dos-service.md
new file mode 100644
index 0000000000..c7c7916fde
--- /dev/null
+++ b/content/includes/dos/k8s_with_ebpf_manifest/dos-service.md
@@ -0,0 +1,19 @@
+---
+---
+
+```dos-service.yaml
+apiVersion: v1
+kind: Service
+metadata:
+ name: nap-dos
+ namespace: app-protect-dos
+spec:
+ externalTrafficPolicy: Local
+ ports:
+ - name: app
+ port: 80
+ protocol: TCP
+ selector:
+ app: app-protect-dos
+ type: LoadBalancer
+```
\ No newline at end of file
diff --git a/content/nap-dos/deployment-guide/best-practices.md b/content/nap-dos/deployment-guide/best-practices.md
index 5c164f080d..ba1ef81888 100644
--- a/content/nap-dos/deployment-guide/best-practices.md
+++ b/content/nap-dos/deployment-guide/best-practices.md
@@ -3,7 +3,7 @@ description: F5 DoS for NGINX Best Practices Deployment.
nd-docs: DOCS-666
title: Best Practices
toc: true
-weight: 100
+weight: 130
nd-content-type: how-to
nd-product: F5DOSN
---
@@ -165,7 +165,7 @@ F5 DoS for NGINX provides a range of application monitoring tools:
A complete guide on configuring F5 DoS for NGINX Live Activity Monitoring be found here: [F5 DoS for NGINX Live Activity Monitoring](https://docs.nginx.com/nginx-app-protect-dos/monitoring/live-activity-monitoring/)
Below is an example configuration that limits API location access to the local network using the allow and deny directives, and uses HTTP Basic Authentication to restrict the PATCH, POST, and DELETE methods to specific users.
-To view the dashboard, enter its address in your browser’s address bar. For example, http://192.168.1.23/dashboard-dos.html displays the dashboard page located in `/usr/share/nginx/html`, as specified by the root directive.
+To view the dashboard, enter its address in your browser’s address bar.For example, http://192.168.1.23/dashboard-dos.html displays the dashboard page located in `/usr/share/nginx/html`, as specified by the root directive.
```nginx
http {
diff --git a/content/nap-dos/deployment-guide/installing-nginx-plus-with-dos-and-waf-on-amazon-web-services.md b/content/nap-dos/deployment-guide/installing-nginx-plus-with-dos-and-waf-on-amazon-web-services.md
index 6211ef16fe..8a4a89217a 100644
--- a/content/nap-dos/deployment-guide/installing-nginx-plus-with-dos-and-waf-on-amazon-web-services.md
+++ b/content/nap-dos/deployment-guide/installing-nginx-plus-with-dos-and-waf-on-amazon-web-services.md
@@ -6,7 +6,7 @@ description: Install F5 NGINX Plus, F5 WAF & DoS for NGINX Plus on Amazon Web Se
nd-docs: DOCS-1204
title: Installing F5 WAF & DoS for NGINX AMIs on Amazon EC2
toc: true
-weight: 110
+weight: 120
nd-content-type: how-to
nd-product: F5DOSN
---
diff --git a/content/nap-dos/deployment-guide/kubernetes-with-L4-accelerated-mitigation..md b/content/nap-dos/deployment-guide/kubernetes-with-L4-accelerated-mitigation..md
new file mode 100644
index 0000000000..cb38120920
--- /dev/null
+++ b/content/nap-dos/deployment-guide/kubernetes-with-L4-accelerated-mitigation..md
@@ -0,0 +1,435 @@
+---
+# We use sentence case and present imperative tone
+title: "Kubernetes with L4 accelerated mitigation"
+# Weights are assigned in increments of 100: determines sorting order
+weight: 110
+# 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: F5DOSN
+---
+
+This page describes how to install F5 DOS for NGINX using Kubernetes with L4 accelerated mitigation service.
+By enabling [accelerated-mitigation-directive-app_protect_dos_accelerated_mitigation](https://docs.nginx.com/nginx-app-protect-dos/directives-and-policy/learn-about-directives-and-policy/#accelerated-mitigation-directive-app_protect_dos_accelerated_mitigation)
+and running the [DOS EBPF Manager]() as a sidecar container alongside the NGINX container, you can offload Layer 4 DoS mitigation to eBPF programs running in the Linux kernel. This improves mitigation performance and reduces CPU usage on the NGINX container.
+
+Such with L4 accelerated mitigation require the NGINX and DOS containers to run with elevated privileges, as well as additional Linux capabilities. Therefore, this guide assumes you have a good understanding of Kubernetes security best practices and have taken the necessary steps to secure your cluster accordingly.
+The F5 Dos For NGINX require the service to run with [externalTrafficPolicy](https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip) set to Local in order to preserve the client source IP address for accurate DoS mitigation.
+```text
+spec:
+ externalTrafficPolicy: Local
+```
+
+
+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 DOS 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-jwt-crt-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 >}}
+
+{{< tabs name="alpine-instructions-ebpf" >}}
+
+{{% tab name="EBPF Manager" %}}
+
+{{< include "/dos/dockerfiles/alpine-ebpf-manager.md" >}}
+
+{{% /tab %}}
+
+{{< /tabs >}}
+
+### Amazon Linux
+
+{{< tabs name="amazon-instructions" >}}
+
+{{% tab name="NGINX Plus" %}}
+
+{{< include "/dos/dockerfiles/amazon-plus-dos.md" >}}
+
+{{% /tab %}}
+
+{{< /tabs >}}
+
+{{< tabs name="amazon-instructions-ebpf" >}}
+
+{{% tab name="EBPF Manager" %}}
+
+{{< include "/dos/dockerfiles/amazon-ebpf-manager.md" >}}
+
+{{% /tab %}}
+
+{{< /tabs >}}
+
+### Debian
+
+{{< tabs name="debian-instructions" >}}
+
+{{% tab name="NGINX Plus" %}}
+
+{{< include "/dos/dockerfiles/debian-plus-dos.md" >}}
+
+{{% /tab %}}
+
+{{< /tabs >}}
+
+{{< tabs name="debian-instructions-ebpf" >}}
+
+{{% tab name="EBPF Manager" %}}
+
+{{< include "/dos/dockerfiles/debian-ebpf-manager.md" >}}
+
+{{% /tab %}}
+
+{{< /tabs >}}
+
+### RHEL 8
+
+{{< tabs name="rhel8-instructions" >}}
+
+{{% tab name="NGINX Plus" %}}
+
+{{< include "/dos/dockerfiles/rhel8-plus-dos.md" >}}
+
+{{% /tab %}}
+
+{{< /tabs >}}
+
+{{< tabs name="rhel8-instructions-ebpf" >}}
+
+{{% tab name="EBPF Manager" %}}
+
+{{< include "/dos/dockerfiles/rhel8-ebpf-manager.md" >}}
+
+{{% /tab %}}
+
+{{< /tabs >}}
+
+### RHEL 9
+
+{{< tabs name="rhel9-instructions" >}}
+
+{{% tab name="NGINX Plus" %}}
+
+{{< include "/dos/dockerfiles/rhel9-plus-dos.md" >}}
+
+{{% /tab %}}
+
+{{< /tabs >}}
+
+{{< tabs name="rhel9-instructions-ebpf" >}}
+
+{{% tab name="EBPF Manager" %}}
+
+{{< include "/dos/dockerfiles/rhel9-ebpf-manager.md" >}}
+
+{{% /tab %}}
+
+{{< /tabs >}}
+
+### RHEL 10
+
+{{< tabs name="rhel10-instructions" >}}
+
+{{% tab name="NGINX Plus" %}}
+
+{{< include "/dos/dockerfiles/rhel10-plus-dos.md" >}}
+
+{{% /tab %}}
+
+{{< /tabs >}}
+
+{{< tabs name="rhel10-instructions-ebpf" >}}
+
+{{% tab name="EBPF Manager" %}}
+
+{{< include "/dos/dockerfiles/rhel10-ebpf-manager.md" >}}
+
+{{% /tab %}}
+
+{{< /tabs >}}
+
+### Rocky Linux 9
+
+{{< tabs name="rocky-instructions" >}}
+
+{{% tab name="NGINX Plus" %}}
+
+{{< include "/dos/dockerfiles/rocky9-plus-dos.md" >}}
+
+{{% /tab %}}
+
+{{< /tabs >}}
+
+{{< tabs name="rocky9-instructions-ebpf" >}}
+
+{{% tab name="EBPF Manager" %}}
+
+{{< include "/dos/dockerfiles/rocky9-ebpf-manager.md" >}}
+
+{{% /tab %}}
+
+{{< /tabs >}}
+
+### Ubuntu
+
+{{< tabs name="ubuntu-instructions" >}}
+
+{{% tab name="NGINX Plus" %}}
+
+{{< include "/dos/dockerfiles/ubuntu-plus-dos.md" >}}
+
+{{% /tab %}}
+
+{{< /tabs >}}
+
+{{< tabs name="ubuntu-instructions-ebpf" >}}
+
+{{% tab name="EBPF Manager" %}}
+
+{{< include "/dos/dockerfiles/ubuntu-ebpf-manager.md" >}}
+
+{{% /tab %}}
+
+{{< /tabs >}}
+
+## Create DOS entrypoint.sh
+Docker startup script which spins up all App Protect DoS processes, must have executable permissions
+
+{{< include "/dos/dos-entrypoint.md" >}}
+
+## Build the DOS Docker image
+
+Your folder should contain the following files:
+
+- _nginx-repo.crt_
+- _nginx-repo.key_
+- _license.jwt_
+- _entrypoint.sh_
+- _nginx.conf_
+- _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 .
+```
+
+## Build the EBPF Manager 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 DOS and EBPF images, push them 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 DOS for NGINX](#use-helm-to-install-f5-dos-for-nginx)
+- [Use Manifests to install F5 DOS for NGINX](#use-manifests-to-install-f5-dos-for-nginx)
+
+## Use Helm to install F5 DOS for NGINX
+
+You will need to edit the `values.yaml` file for a few changes:
+
+- Update _appprotectdos.nginxImage.repository_ and _appprotectdos.nginxImage.tag_ with the image name chosen during when [building the Docker image](#build-the-docker-image).
+
+The `` argument should be the _contents_ of the file, not the file itself. Ensure there are no additional characters such as extra whitespace.
+
+On helm deployment environment variables need to be set for image repository and tag.
+`set enviorment variable DOS_IMAGE_REPOSITORY` with your actual nginx-dos image anmae.
+`set enviorment variable DOS_IMAGE_TAG` with your actual nginx-dos image tag.
+`set enviorment variable EBPF_IMAGE_REPOSITORY` with your actual ebpf-manager image name.
+`set enviorment variable EBPF_IMAGE_TAG` with your actual ebpf-manager image tag.
+
+Once you have updated `values.yaml`, you can install F5 WAF for NGINX using `helm install`:
+
+```shell
+export DOS_IMAGE_REPOSITORY=
+export DOS_IMAGE_TAG=
+export EBPF_IMAGE_REPOSITORY=
+export EBPF_IMAGE_TAG=
+
+kubectl create namespace --dry-run=client -o yaml | kubectl apply -f -
+kubectl create secret generic license-token \
+ --from-file=license.jwt=${PWD}/license.jwt --type=nginx.com/license --namespace
+
+# Install DOS Arbitrator
+helm repo add nginx-stable https://helm.nginx.com/stable && helm repo update
+helm install dos-arbitrator nginx-stable/nginx-appprotect-dos-arbitrator --namespace
+
+# Install DOS with EBPF Manager
+# release-version example: 4.8.3
+helm pull oci://private-registry.nginx.com/nap-dos/nginx-app-protect-ebpf --version --untar
+cd nginx-app-protect-dos-ebpf
+
+helm install nginx-app-protect-dos-ebpf --namespace \
+ --set namespace.create=false --set service.type=NodePort \
+ --set appProtectDos.image.repository=${DOS_IMAGE_REPOSITORY} \
+ --set appProtectDos.image.tag=${DOS_IMAGE_TAG} \
+ --set appProtectDos.ebpfManagerImage.repository=$EBPF_IMAGE_REPOSITORY} \
+ --set appProtectDos.ebpfManagerImage.tag=${EBPF_IMAGE_TAG} .
+
+kubectl wait --for=condition=available --timeout=300s deployment/app-protect-dos -n
+```
+
+You can verify the deployment is successful with `kubectl get`, replacing `namespace` accordingly:
+
+```shell
+kubectl get pods --namespac
+kubectl get svc --namespac
+```
+
+{{< call-out "note" >}}
+
+At this stage, you have finished deploying F5 DOS for NGINX and can look at [Post-installation checks](#post-installation-checks).
+
+{{< /call-out >}}
+
+## Use Manifests to install F5 DOS for NGINX
+
+### Create Manifest files
+
+The default configuration provided creates two replicas, each hosting NGINX and DOS services together in a single Kubernetes pod.
+
+Create all of these files in a single folder (Such as `/manifests`).
+
+On manifest deployment environment variables need to be set for image repository and tag.
+ `set enviorment variable DOS_IMAGE_REPOSITORY` with your actual nginx-dos image anmae.
+ `set enviorment variable DOS_IMAGE_TAG` with your actual nginx-dos image tag.
+ `set enviorment variable EBPF_IMAGE_REPOSITORY` with your actual ebpf-manager image name.
+ `set enviorment variable EBPF_IMAGE_TAG` with your actual ebpf-manager image tag.
+
+{{< tabs name="manifest-files" >}}
+
+{{% tab name=dos-namespace.yaml %}}
+
+{{< include "dos/k8s_with_ebpf_manifest/dos-namespace.md" >}}
+
+{{% /tab %}}
+
+
+{{% tab name=dos-nginx-conf-configmap.yaml %}}
+
+{{< include "dos/k8s_with_ebpf_manifest/dos-nginx-conf-configmap.md" >}}
+
+{{% /tab %}}
+
+{{% tab name=dos-log-default-configmap.yaml %}}
+
+{{< include "dos/k8s_with_ebpf_manifest/dos-log-default-configmap.md" >}}
+
+{{% /tab %}}
+
+{{% tab name=dos-deployment.yaml %}}
+
+{{< include "dos/k8s_with_ebpf_manifest/dos-deployment.md" >}}
+
+{{% /tab %}}
+
+{{% tab name=dos-service.yaml %}}
+
+{{< include "dos/k8s_with_ebpf_manifest/dos-service.md" >}}
+
+{{% /tab %}}
+
+{{< /tabs >}}
+
+### Start the Manifest deployment
+
+From the folder containing the YAML files from the previous step (Suggested as `/manifests`), deploy F5 DOS for NGINX using `kubectl`:
+
+```shell
+export DOS_IMAGE_REPOSITORY=
+export DOS_IMAGE_TAG=
+export EBPF_IMAGE_REPOSITORY=
+export EBPF_IMAGE_TAG=
+kubectl apply -f manifests/dos-namespace.yaml
+kubectl apply -f manifests/dos-nginx-conf-configmap.yaml
+kubectl apply -f manifests/dos-log-default-configmap.yaml
+kubectl apply -f manifests/dos-deployment.yaml
+kubectl apply -f manifests/dos-service.yaml
+```
+
+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 -n app-protect-dos get deployments
+kubectl -n app-protect-dos get pods
+kubectl -n app-protect-dos get services
+```
+
+You should see output similar to the following:
+
+```text
+~$ kubectl -n app-protect-dos get deployments
+NAME READY UP-TO-DATE AVAILABLE AGE
+app-protect-dos 1/1 1 1 33s
+
+~$ kubectl -n app-protect-dos get pods
+NAME READY STATUS RESTARTS AGE
+app-protect-dos-7f9798654c-7ncbl 2/2 Running 0 68s
+
+$ kubectl -n app-protect-dos get pods -o jsonpath='{range .items[*]}Pod: {.metadata.name} -> Containers: {.spec.containers[*].name}{"\n"}{end}'
+Pod: app-protect-dos-7f9798654c-7ncbl -> Containers: dos-ebpf-manager nginx-app-protect-dos
+
+~$ kubectl -n app-protect-dos get services
+NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
+nap-dos LoadBalancer 10.43.212.232 80:32586/TCP 93s
+```
+## Post-Installation Checks
+At this stage, you have finished deploying F5 DOS for NGINX with EBPF L4 accelerated mitigation enabled
+You can login to dos-ebpf-manager container like following command
+```text
+kubectl exec -it app-protect-dos-586fb94947-8sjnc -n app-protect-dos -c nginx-app-protect-dos -- bash
+kubectl exec -it app-protect-dos-586fb94947-8sjnc -n app-protect-dos -c dos-ebpf-manager -- bash
+```
+and can look at .
+{{< include "dos/install-post-checks.md" >}}
+
+## F5 DoS for NGINX Arbitrator
+
+{{< include "/dos/dos-arbitrator.md" >}}
+
+## Next steps
diff --git a/content/nap-dos/deployment-guide/kubernetes.md b/content/nap-dos/deployment-guide/kubernetes.md
new file mode 100644
index 0000000000..c6fb634c71
--- /dev/null
+++ b/content/nap-dos/deployment-guide/kubernetes.md
@@ -0,0 +1,314 @@
+---
+# We use sentence case and present imperative tone
+title: "Kubernetes"
+# Weights are assigned in increments of 100: determines sorting order
+weight: 100
+# 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: F5DOSN
+---
+
+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 DOS 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-jwt-crt-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 >}}
+
+### RHEL 10
+
+{{< tabs name="rhel10-instructions" >}}
+
+{{% tab name="NGINX Plus" %}}
+
+{{< include "/dos/dockerfiles/rhel10-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 >}}
+
+## Create DOS entrypoint.sh
+Docker startup script which spins up all App Protect DoS processes, must have executable permissions
+
+{{< include "/dos/dos-entrypoint.md" >}}
+
+## Build the Docker image
+
+Your folder should contain the following files:
+
+- _nginx-repo.crt_
+- _nginx-repo.key_
+- _entrypoint.sh_
+- _nginx.conf_
+- _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 DOS for NGINX](#use-helm-to-install-f5-dos-for-nginx)
+- [Use Manifests to install F5 DOS for NGINX](#use-manifests-to-install-f5-dos-for-nginx)
+
+## Use Helm to install F5 DOS for NGINX
+
+You will need to edit the `values.yaml` file for a few changes:
+
+- Update _appprotectdos.image.repository_ and _appprotectdos.image.tag_ with the image name chosen during when [building the Docker image](#build-the-docker-image).
+
+The `` argument should be the _contents_ of the file, not the file itself. Ensure there are no additional characters such as extra whitespace.
+
+On helm deployment environment variables need to be set for image repository and tag.
+`set enviorment variable DOS_IMAGE_REPOSITORY` with your actual nginx-dos image anmae.
+`set enviorment variable DOS_IMAGE_TAG` with your actual nginx-dos image tag.
+
+Once you have updated `values.yaml`, you can install F5 WAF for NGINX using `helm install`:
+
+```shell
+export DOS_IMAGE_REPOSITORY=
+export DOS_IMAGE_TAG=
+
+kubectl create namespace --dry-run=client -o yaml | kubectl apply -f -
+kubectl create secret generic license-token \
+ --from-file=license.jwt=${PWD}/license.jwt --type=nginx.com/license --namespace
+
+# Install DOS Arbitrator
+helm repo add nginx-stable https://helm.nginx.com/stable && helm repo update
+helm install dos-arbitrator nginx-stable/nginx-appprotect-dos-arbitrator --namespace
+
+# Install DOS for NGINX
+# release-version example: 4.8.3
+helm pull oci://private-registry.nginx.com/nap-dos/nginx-app-protect --version --untar
+cd nginx-app-protect-dos
+
+helm install nginx-app-protect-dos --namespace \
+ --set namespace.create=false --set service.type=NodePort \
+ --set appProtectDos.image.repository=${DOS_IMAGE_REPOSITORY} \
+ --set appProtectDos.image.tag=${DOS_IMAGE_TAG} .
+
+kubectl wait --for=condition=available --timeout=300s deployment/app-protect-dos -n
+```
+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 DOS for NGINX and can look at [Post-installation checks](#post-installation-checks).
+
+{{< /call-out >}}
+
+## Use Manifests to install F5 DOS for NGINX
+
+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 DOS services together in a single Kubernetes pod.
+
+Create all of these files in a single folder (Such as `/manifests`).
+
+On manifest deployment environment variables need to be set for image repository and tag.
+`set enviorment variable DOS_IMAGE_REPOSITORY` with your actual nginx-dos image anmae.
+`set enviorment variable DOS_IMAGE_TAG` with your actual nginx-dos image tag.
+
+{{< tabs name="manifest-files" >}}
+
+{{% tab name=dos-namespace.yaml %}}
+
+{{< include "dos/k8s_manifest/dos-namespace.md" >}}
+
+{{% /tab %}}
+
+{{% tab name=dos-nginx-conf-configmap.yaml %}}
+
+{{< include "dos/k8s_manifest/dos-nginx-conf-configmap.md" >}}
+
+{{% /tab %}}
+
+{{% tab name=dos-log-default-configmap.yaml %}}
+
+{{< include "dos/k8s_manifest/dos-log-default-configmap.md" >}}
+
+{{% /tab %}}
+
+{{% tab name=dos-deployment.yaml %}}
+
+{{< include "dos/k8s_manifest/dos-deployment.md" >}}
+
+{{% /tab %}}
+
+{{% tab name=dos-service.yaml %}}
+
+{{< include "dos/k8s_manifest/dos-service.md" >}}
+
+{{% /tab %}}
+
+{{< /tabs >}}
+
+### Start the Manifest deployment
+
+From the folder containing the YAML files from the previous step (Suggested as `/manifests`), deploy F5 DOS for NGINX using `kubectl`:
+
+```shell
+export DOS_IMAGE_REPOSITORY=
+export DOS_IMAGE_TAG=
+kubectl apply -f manifests/dos-namespace.yaml
+kubectl create secret generic license-token --from-file=license.jwt=license.jwt --type=nginx.com/license --namespace app-protect-dos
+kubectl apply -f dos-manifest/dos-log-default-configmap.yaml
+kubectl apply -f dos-manifest/dos-nginx-conf-configmap.yaml
+kubectl apply -f manifests/dos-deployment.yaml
+kubectl apply -f manifests/dos-service.yaml
+```
+
+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 --namespace app-protect-dos get deployments
+kubectl --namespace app-protect-dos get pods
+kubectl --namespace app-protect-dos get services
+```
+
+You should see output similar to the following:
+
+```text
+~$ kubectl --namespace app-protect-dos get deployments
+NAME READY UP-TO-DATE AVAILABLE AGE
+app-protect-dos 1/1 1 1 1m
+
+~$ kubectl --namespace app-protect-dos get pods
+NAME READY STATUS RESTARTS AGE
+app-protect-dos-586fb94947-8sjnc 1/1 Running 0 1m
+
+~$ kubectl --namespace app-protect-dos get services
+NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
+nap-dos LoadBalancer 10.43.83.225 80:30307/TCP 1m
+```
+## Post-Installation Checks
+At this stage, you have finished deploying F5 DOS for NGINX.
+You csn login to app-protect-dos pod like following command
+```text
+kubectl exec -it app-protect-dos-586fb94947-8sjnc -n app-protect-dos -c nginx-app-protect-dos -- bash
+```
+and can look at .
+{{< include "dos/install-post-checks.md" >}}
+
+## F5 DoS for NGINX Arbitrator
+
+{{< include "/dos/dos-arbitrator.md" >}}
+
+## Next steps
diff --git a/content/nap-dos/deployment-guide/learn-about-deployment.md b/content/nap-dos/deployment-guide/learn-about-deployment.md
index eb6abc9040..dc5f3a02fd 100644
--- a/content/nap-dos/deployment-guide/learn-about-deployment.md
+++ b/content/nap-dos/deployment-guide/learn-about-deployment.md
@@ -1,7 +1,7 @@
---
description: Learn about F5 DoS for NGINX Deployment.
nd-docs: DOCS-666
-title: Deployment
+title: Virtual Machine and Docker
toc: true
weight: 90
nd-content-type: how-to
@@ -23,8 +23,10 @@ F5 DoS for NGINX supports the following operating systems:
- [RHEL 8.1+ / Rocky Linux 8](#rhel-8--rocky-linux-8-installation)
- [RHEL 9.0+ / Rocky Linux 9](#rhel-9--rocky-linux-9-installation)
+- [RHEL 10.0+](#rhel-10-installation)
- [Debian 11 (Bullseye)](#debian--ubuntu-installation)
- [Debian 12 (Bookworm)](#debian--ubuntu-installation)
+- [Debian 13 (Trixie)](#debian--ubuntu-installation)
- [Ubuntu 22.04 (Jammy)](#debian--ubuntu-installation)
- [Ubuntu 24.04 (Noble)](#debian--ubuntu-installation)
- [Alpine 3.21](#alpine-installation)
@@ -262,7 +264,7 @@ When deploying App Protect DoS on NGINX Plus take the following precautions to s
sudo systemctl start nginx
```
-18. L4 mitigation
+18. L4 accelerated mitigation
To enable the `app-protect-dos-ebpf-manager` service to start at boot, run the command:
```shell
@@ -479,7 +481,217 @@ When deploying App Protect DoS on NGINX Plus take the following precautions to s
sudo systemctl start nginx
```
-18. L4 mitigation
+18. L4 accelerated mitigation
+
+ To enable the `app-protect-dos-ebpf-manager` service to start at boot, run the command:
+ ```shell
+ sudo systemctl enable nginx.service
+ ```
+ Start the `app-protect-dos-ebpf-manager` service:
+ ```
+ sudo systemctl start app-protect-dos-ebpf-manager
+ ```
+
+
+### RHEL 10 installation
+
+1. If you already have NGINX packages on your system, back up your configs and logs:
+
+ ```shell
+ sudo cp -a /etc/nginx /etc/nginx-plus-backup
+ sudo cp -a /var/log/nginx /var/log/nginx-plus-backup
+ ```
+
+1. {{< include "nginx-plus/install/create-dir-for-crt-key.md" >}}
+
+1. {{< include "nginx-plus/install/create-dir-for-jwt.md" >}}
+
+1. {{< include "licensing-and-reporting/download-jwt-crt-from-myf5.md" >}}
+
+1. {{< include "nginx-plus/install/copy-crt-and-key.md" >}}
+
+1. {{< include "nginx-plus/install/copy-jwt-to-etc-nginx-dir.md" >}}
+
+5. Install prerequisite packages:
+
+ ```shell
+ sudo dnf install ca-certificates wget
+ ```
+
+6. Enable the yum repositories to pull F5 DoS for NGINX dependencies:
+
+ ```shell
+ sudo subscription-manager repos --enable=rhel-10-for-x86_64-baseos-rpms
+ sudo subscription-manager repos --enable=rhel-10-for-x86_64-appstream-rpms
+ sudo dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-10.noarch.rpm
+ ```
+
+7. Add the NGINX Plus and NGINX App Protect DoS repositories:
+
+ ```shell
+ sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/plus-10.repo
+ sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/app-protect-dos-10.repo
+ ```
+
+8. If you are performing a fresh installation, update the repository and install the most recent version of the NGINX Plus App Protect DoS package (which includes NGINX Plus):
+
+ ```shell
+ sudo dnf install app-protect-dos
+ ```
+
+ For L4 accelerated mitigation feature (RHEL 10):
+
+ ```shell
+ sudo dnf install app-protect-dos-ebpf-manager
+ ```
+
+ {{< call-out "note" >}}
+ L4 accelerated mitigation feature (RHEL 10):
+ - `app-protect-dos-ebpf-manager` run with root privileges.
+ {{< /call-out >}}
+
+ Alternatively, you can use the following command to list available versions:
+
+ ```shell
+ sudo dnf --showduplicates list app-protect-dos
+ ```
+
+ Then, install a specific version from the output of command above. For example:
+
+ ```shell
+ sudo dnf install app-protect-dos-35+4.7.3
+ ```
+
+9. If you are upgrading from a previously installed NGINX Plus App Protect DoS package (which includes NGINX Plus):
+
+ ```shell
+ sudo dnf remove nginx-plus
+ sudo dnf install app-protect-dos
+ sudo systemctl start nginx
+ ```
+
+ {{< call-out "note" >}} Make sure to restore configuration from `/etc/nginx-plus-backup` back to `/etc/nginx-plus`.{{< /call-out >}}
+
+10. Check the NGINX binary version to ensure that you have NGINX Plus installed correctly:
+
+ ```shell
+ sudo nginx -v
+ ```
+
+11. Check the App Protect DoS binary version to ensure that you have the right version installed correctly:
+
+ ```shell
+ sudo admd -v
+ ```
+
+12. Load the F5 DoS for NGINX module on the main context in the `nginx.conf`:
+
+ ```nginx
+ load_module modules/ngx_http_app_protect_dos_module.so;
+ ```
+
+13. Enable F5 DoS for NGINX on an `http/server/location` context in the `nginx.conf` file:
+
+ ```nginx
+ app_protect_dos_enable on;
+ app_protect_dos_name "App1";
+ app_protect_dos_monitor uri=serv:80/; # Assuming server_name "serv" on port 80, with the root path "/"
+ ```
+
+14. Enable the L4 accelerated mitigation feature (RHEL 10) in the `http` context of the `nginx.conf` file:
+
+ ```nginx
+ app_protect_dos_accelerated_mitigation on;
+ ```
+
+15. Configure SELinux to allow App Protect DoS:
+
+ a. Using the vi editor, create a file:
+
+ ```shell
+ vi app-protect-dos.te
+ ```
+
+ b. Insert the following contents into the file created above:
+
+ ```shell
+ module app-protect-dos 2.0;
+ require {
+ type unconfined_t;
+ type unconfined_service_t;
+ type httpd_t;
+ type tmpfs_t;
+ type initrc_t;
+ type initrc_state_t;
+ class capability sys_resource;
+ class shm { associate read unix_read unix_write write };
+ class file { read write };
+ }
+ allow httpd_t initrc_state_t:file { read write };
+ allow httpd_t self:capability sys_resource;
+ allow httpd_t tmpfs_t:file { read write };
+ allow httpd_t unconfined_service_t:shm { associate read unix_read unix_write write };
+ allow httpd_t unconfined_t:shm { associate read write unix_read unix_write };
+ allow httpd_t initrc_t:shm { associate read unix_read unix_write write };
+ ```
+
+ c. Run the following chain of commands:
+
+ ```shell
+ sudo checkmodule -M -m -o app-protect-dos.mod app-protect-dos.te && \
+ sudo semodule_package -o app-protect-dos.pp -m app-protect-dos.mod && \
+ sudo semodule -i app-protect-dos.pp;
+ ```
+
+ For L4 accelerated mitigation feature:
+ a. Using the vi editor, create a file:
+
+ ```shell
+ vi app-protect-dos-ebpf-manager.te
+ ```
+
+ b. Insert the following contents into the file created above:
+
+ ```shell
+ module app-protect-dos-ebpf-manager 1.0;
+ require {
+ type root_t;
+ type httpd_t;
+ type unconfined_service_t;
+ class sock_file write;
+ class unix_stream_socket connectto;
+ class shm { unix_read unix_write };
+ }
+ allow httpd_t root_t:sock_file write;
+ allow httpd_t unconfined_service_t:shm { unix_read unix_write };
+ allow httpd_t unconfined_service_t:unix_stream_socket connectto;
+ ```
+
+ c. Run the following chain of commands:
+
+ ```shell
+ sudo checkmodule -M -m -o app-protect-dos-ebpf-manager.mod app-protect-dos-ebpf-manager.te && \
+ sudo semodule_package -o app-protect-dos-ebpf-manager.pp -m app-protect-dos-ebpf-manager.mod && \
+ sudo semodule -i app-protect-dos-ebpf-manager.pp;
+ ```
+
+ If you encounter any issues, refer to the [Troubleshooting Guide]({{< ref "/nap-dos/troubleshooting/how-to-troubleshoot.md" >}}).
+
+ {{< call-out "note" >}}Additional SELinux configuration may be required to allow NGINX Plus to listen on specific network ports, connect to upstreams, and send syslog entries to remote systems. Refer to the practices outlined in the [Using NGINX and NGINX Plus with SELinux](https://www.f5.com/company/blog/nginx/using-nginx-plus-with-selinux/) article for details.{{< /call-out >}}
+
+16. To enable the NGINX/App-Protect-DoS service to start at boot, run the command:
+
+ ```shell
+ sudo systemctl enable nginx.service
+ ```
+
+17. Start the NGINX service:
+
+ ```shell
+ sudo systemctl start nginx
+ ```
+
+18. L4 accelerated mitigation
To enable the `app-protect-dos-ebpf-manager` service to start at boot, run the command:
```shell
@@ -565,14 +777,14 @@ When deploying App Protect DoS on NGINX Plus take the following precautions to s
sudo apt-get install app-protect-dos
```
- For L4 accelerated mitigation feature (Debian 11 / Debian 12 / Ubuntu 22.04 / Ubuntu 24.04):
+ For L4 accelerated mitigation feature (Debian 11, 12, and 13 / Ubuntu 22.04 and 24.04):
```shell
sudo apt-get install app-protect-dos-ebpf-manager
```
{{< call-out "note" >}}
- L4 accelerated mitigation feature (Debian 11 / Debian 12 / Ubuntu 22.04 / Ubuntu 24.04):
+ L4 accelerated mitigation feature (Debian 11, 12, and 13 / Ubuntu 22.04 and 24.04):
- `app-protect-dos-ebpf-manager` run with root privileges.
{{< /call-out >}}
@@ -597,6 +809,12 @@ When deploying App Protect DoS on NGINX Plus take the following precautions to s
sudo apt-get install app-protect-dos=35+4.7.3-1~bookworm nginx-plus-module-appprotectdos=35+4.7.3-1~bookworm
```
+ For example, for Debian 13:
+
+ ```shell
+ sudo apt-get install app-protect-dos=35+4.7.3-1~trixie nginx-plus-module-appprotectdos=35+4.7.3-1~trixie
+ ```
+
For example for Ubuntu 22.04:
```shell
@@ -644,7 +862,7 @@ When deploying App Protect DoS on NGINX Plus take the following precautions to s
app_protect_dos_monitor uri=serv:80/; # Assuming server_name "serv" on port 80, with the root path "/"
```
-15. Enable the L4 accelerated mitigation feature (Debian 11 / Debian 12 / Ubuntu 22.04 / Ubuntu 24.04) on the `http` context of the `nginx.conf` file:
+15. Enable the L4 accelerated mitigation feature (Debian 11, 12, and 13 / Ubuntu 22.04 and 24.04) on the `http` context of the `nginx.conf` file:
```nginx
app_protect_dos_accelerated_mitigation on;
@@ -908,7 +1126,7 @@ When deploying App Protect DoS on NGINX Plus take the following precautions to s
sudo systemctl start nginx
```
-16. L4 mitigation
+16. L4 accelerated mitigation
To enable the `app-protect-dos-ebpf-manager` service to start at boot, run the command:
```shell
@@ -933,7 +1151,7 @@ You need root permissions to execute the following steps.
- `license.jwt`: JWT license file for NGINX Plus license management
- `nginx.conf`: User defined `nginx.conf` with `app-protect-dos` enabled
- `entrypoint.sh`: Docker startup script which spins up all App Protect DoS processes, must have executable permissions
- - custom_log_format.json: Optional user-defined security log format file (if not used - remove its references from the nginx.conf and Dockerfile)
+ - `custom_log_format.json`: Optional user-defined security log format file (if not used - remove its references from the nginx.conf and Dockerfile)
2. Log in to NGINX Plus Customer Portal and download your `nginx-repo.crt`, `nginx-repo.key` and `license.jwt` files.
@@ -1025,35 +1243,20 @@ You need root permissions to execute the following steps.
5. In the same directory create an `entrypoint.sh` file with executable permissions, with the following content:
- ```shell
- #!/usr/bin/env bash
-
- USER=nginx
- LOGDIR=/var/log/adm
-
- # prepare environment
- mkdir -p /var/run/adm /tmp/cores ${LOGDIR}
- chmod 755 /var/run/adm /tmp/cores ${LOGDIR}
- chown ${USER}:${USER} /var/run/adm /tmp/cores ${LOGDIR}
-
- # run processes
- /bin/su -s /bin/bash -c "/usr/bin/adminstall > ${LOGDIR}/adminstall.log 2>&1" ${USER}
- /bin/su -s /bin/bash -c "/usr/bin/admd -d --log info > ${LOGDIR}/admd.log 2>&1 &" ${USER}
- /usr/sbin/nginx -g 'daemon off;'
- ```
+ {{< include "/dos/dos-entrypoint.md" >}}
6. Create a Docker image:
```shell
- DOCKER_BUILDKIT=1 docker build --no-cache --platform linux/amd64 --secret id=nginx-crt,src=nginx-repo.crt --secret id=nginx-key,src=nginx-repo.key --secret id=license-jwt,src=./license.jwt -t app-protect-dos .
+ DOCKER_BUILDKIT=1 docker build --no-cache --platform linux/amd64 --secret id=nginx-crt,src=nginx-repo.crt --secret id=nginx-key,src=nginx-repo.key -t app-protect-dos .
```
The `--no-cache` option tells Docker to build the image from scratch and ensures the installation of the latest version of NGINX Plus and F5 DoS for NGINX. If the Dockerfile was previously used to build an image without the `--no-cache` option, the new image uses versions from the previously built image from the Docker cache.
- For RHEL8/9 with subctiption manager setup add build arguments:
+ For RHEL 8/9/10 with subscription manager setup add build arguments:
```shell
- DOCKER_BUILDKIT=1 docker build --build-arg RHEL_ORG=... --build-arg RHEL_ACTIVATION_KEY=... --no-cache --platform linux/amd64 --secret id=nginx-crt,src=nginx-repo.crt --secret id=nginx-key,src=nginx-repo.key --secret id=license-jwt,src=./license.jwt -t app-protect-dos .
+ DOCKER_BUILDKIT=1 docker build --build-arg RHEL_ORG=... --build-arg RHEL_ACTIVATION_KEY=... --no-cache --platform linux/amd64 --secret id=nginx-crt,src=nginx-repo.crt --secret id=nginx-key,src=nginx-repo.key -t app-protect-dos .
```
8. Verify that the `app-protect-dos` image was created successfully with the docker images command:
@@ -1065,7 +1268,7 @@ You need root permissions to execute the following steps.
9. Create a container based on this image, for example, `my-app-protect-dos` container:
```shell
- docker run --name my-app-protect-dos -p 80:80 -d app-protect-dos
+ docker run --name my-app-protect-dos -p 80:80 -v $(PWD)/license.jwt:/etc/nginx/license.jwt -d app-protect-dos
```
10. Verify that the `my-app-protect-dos` container is up and running with the `docker ps` command:
@@ -1082,7 +1285,7 @@ You need root permissions to execute the following steps.
mkdir /shared
```
This folder will be used to share data between containers.
- Modify the `entrypoint.sh` to run the L4 mitigation:
+ Modify the `entrypoint.sh` to run the L4 accelerated mitigation:
```shell
# run processes
@@ -1096,17 +1299,17 @@ You need root permissions to execute the following steps.
Create and run the main `app-protect-dos` container:
```shell
- docker run --name my-app-protect-dos -v /shared:/shared -p 80:80 -d app-protect-dos
+ docker run --name my-app-protect-dos -v /shared:/shared -p 80:80 -v $(PWD)/license.jwt:/etc/nginx/license.jwt -d app-protect-dos
```
2. Deploy Directly on the Host.
To run L4 mitigation directly on the host:
- 1. Install the L4 mitigation on the host, as described in the OS-specific instructions.
+ 1. Install the L4 accelerated mitigation on the host, as described in the OS-specific instructions.
2. Run the app-protect-dos container:
```shell
- docker run --name my-app-protect-dos -v /shared:/shared -p 80:80 -d app-protect-dos
+ docker run --name my-app-protect-dos -v /shared:/shared -p 80:80 -v $(PWD)/license.jwt:/etc/nginx/license.jwt -d app-protect-dos
```
- 3. Run L4 Mitigation Inside the Same Container as `app-protect-dos`.
- To run both L4 mitigation and the main application within the same container:
+ 3. Run L4 Accelerated Mitigation Inside the Same Container as `app-protect-dos`.
+ To run both L4 accelerated mitigation and the main application within the same container:
1. Modify the `entrypoint.sh`:
```shell
...
@@ -1116,7 +1319,7 @@ You need root permissions to execute the following steps.
```
2. run the container:
```shell
- docker run --name my-app-protect-dos -p 80:80 -d app-protect-dos
+ docker run --name my-app-protect-dos -p 80:80 -v $(PWD)/license.jwt:/etc/nginx/license.jwt -d app-protect-dos
```
{{< call-out "note" >}}
@@ -1127,251 +1330,35 @@ You need root permissions to execute the following steps.
### Alpine Docker Deployment Example
-```Dockerfile
-# syntax=docker/dockerfile:1
-# For Alpine 3.22:
-FROM alpine:3.22
-
-# Download and add the NGINX signing keys:
-RUN wget -O /etc/apk/keys/nginx_signing.rsa.pub https://cs.nginx.com/static/keys/nginx_signing.rsa.pub
-
-# Add NGINX Plus/F5 DoS for NGINX repository:
-RUN 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
-
-# Update the repository and install the most recent version of the F5 DoS for NGINX package (which includes NGINX Plus):
-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 \
- apk update && apk add app-protect-dos && \
- cat license.jwt > /etc/nginx/license.jwt
-
-# Forward request logs to Docker log collector:
-RUN ln -sf /dev/stdout /var/log/nginx/access.log && \
- ln -sf /dev/stderr /var/log/nginx/error.log
-
-# Forward request logs to Docker log collector:
-RUN 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"]
-```
+{{< include "/dos/dockerfiles/alpine-plus-dos.md" >}}
### AmazonLinux 2023 Docker Deployment Example
-```Dockerfile
-# For AmazonLinux 2023:
-FROM amazonlinux:2023
-
-# Install prerequisite packages:
-RUN dnf -y install ca-certificates
-
-# Add NGINX Plus/F5 DoS for NGINX repository:
-RUN 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
-
-# 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 install -y app-protect-dos && \
- cat license.jwt > /etc/nginx/license.jwt && \
- rm /etc/yum.repos.d/plus-amazonlinux2023.repo && \
- rm /etc/yum.repos.d/app-protect-dos-amazonlinux2023.repo && \
- dnf clean all && \
- rm -rf /var/cache/dnf
-
-# Forward request logs to Docker log collector:
-RUN 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
+{{< include "/dos/dockerfiles/amazon-plus-dos.md" >}}
-EXPOSE 80
+### Debian 11, 12, and 13 Docker deployment example
-STOPSIGNAL SIGQUIT
-
-CMD ["sh", "/root/entrypoint.sh"]
-```
-
-### Debian 11 (Bullseye) / Debian 12 (Bookworm) Docker Deployment Example
-
-```Dockerfile
-# Where can be bullseye/bookworm
-FROM debian:bullseye
-
-# Setup repository keys
-RUN mkdir -p /etc/ssl/nginx/ /etc/nginx/ && \
- apt-get update && \
- apt-get install -y --no-install-recommends 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 && \
- 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
-
-# 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 app-protect-dos && \
- cat license.jwt > /etc/nginx/license.jwt && \
- apt-get remove --purge --auto-remove -y && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx-plus.list /etc/apt/sources.list.d/nginx-app-protect-dos.list && \
- rm -rf /etc/apt/apt.conf.d/90nginx /var/lib/apt/lists/*
-
-# Forward request logs to Docker log collector:
-RUN 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"]
-```
+{{< include "/dos/dockerfiles/debian-plus-dos.md" >}}
### Ubuntu 22.04 (Jammy) / 24.04 (Noble) Docker Deployment Example
-```Dockerfile
-# Where version can be: jammy/noble
-FROM ubuntu:noble
-
-# Setup repository keys
-RUN 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
-
-# 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 app-protect-dos && \
- cat license.jwt > /etc/nginx/license.jwt && \
- apt-get remove --purge --auto-remove -y && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx-plus.list /etc/apt/sources.list.d/nginx-app-protect-dos.list && \
- rm -rf /etc/apt/apt.conf.d/90nginx /var/lib/apt/lists/*
+{{< include "/dos/dockerfiles/ubuntu-plus-dos.md" >}}
-# Forward request logs to Docker log collector:
-RUN 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
+### RHEL 8 Docker Deployment Example
-EXPOSE 80
+{{< include "/dos/dockerfiles/rhel8-plus-dos.md" >}}
-STOPSIGNAL SIGQUIT
+### RHEL 9 Docker Deployment Example
-CMD ["sh", "/root/entrypoint.sh"]
-```
+{{< include "/dos/dockerfiles/rhel9-plus-dos.md" >}}
-### RHEL 8 Docker Deployment Example
+### RHEL 10 Docker deployment example
-```Dockerfile
-# For UBI 8
-FROM registry.access.redhat.com/ubi8
-
-ARG RHEL_ORG
-ARG RHEL_ACTIVATION_KEY
-
-# Setup repository keys
-RUN 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
-
-# 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 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
-
-# Forward request logs to Docker log collector:
-RUN 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"]
-```
+{{< include "/dos/dockerfiles/rhel10-plus-dos.md" >}}
### Rocky Linux 9 Docker Deployment Example
-```Dockerfile
-# syntax=docker/dockerfile:1
-# For Rocky Linux 9:
-FROM rockylinux:9
-
-# Install prerequisite packages:
-RUN dnf -y install ca-certificates epel-release 'dnf-command(config-manager)'
-
-# Add NGINX App-protect-DoS & NGINX Plus repo to Yum:
-RUN 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 clean all
-
-# 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 install -y 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/dnf
-
-# Forward request logs to Docker log collector:
-RUN 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"]
-```
+{{< include "/dos/dockerfiles/rocky9-plus-dos.md" >}}
## Docker Deployment with NGINX App Protect
@@ -1509,38 +1496,22 @@ Make sure to replace upstream and proxy pass directives in this example with rel
7. In the same directory create an `entrypoint.sh` file with executable permissions, with the following content:
- For Alpine / Debian / Ubuntu / UBI 8 / UBI 9:
+ For Alpine /AmazonLinux 2023/ Debian / Ubuntu / UBI 8/ UBI 9:
+
+{{< include "/dos/dos-waf-entrypoint.md" >}}
- ```shell
- #!/usr/bin/env bash
- USER=nginx
- LOGDIR=/var/log/adm
-
- # prepare environment
- mkdir -p /var/run/adm /tmp/cores ${LOGDIR}
- chmod 755 /var/run/adm /tmp/cores ${LOGDIR}
- chown ${USER}:${USER} /var/run/adm /tmp/cores ${LOGDIR}
-
- # run processes
- /bin/su -s /bin/bash -c "/usr/bin/adminstall > ${LOGDIR}/adminstall.log 2>&1" ${USER}
- /bin/su -s /bin/bash -c "/opt/app_protect/bin/bd_agent &" ${USER}
- /bin/su -s /bin/bash -c "/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 2>&1 > /var/log/app_protect/bd-socket-plugin.log &" ${USER}
- /bin/su -s /bin/bash -c "/usr/bin/admd -d --log info > ${LOGDIR}/admd.log 2>&1 &" ${USER}
- /usr/sbin/nginx -g 'daemon off;'
- ```
-
8. Create a Docker image:
For Debian/Ubuntu/Alpine/Amazon Linux:
```shell
- DOCKER_BUILDKIT=1 docker build --no-cache --platform linux/amd64 --secret id=nginx-crt,src=nginx-repo.crt --secret id=nginx-key,src=nginx-repo.key --secret id=license-jwt,src=./license.jwt -t app-protect-dos .
+ DOCKER_BUILDKIT=1 docker build --no-cache --platform linux/amd64 --secret id=nginx-crt,src=nginx-repo.crt --secret id=nginx-key,src=nginx-repo.key -t app-protect-dos .
```
For RHEL:
```shell
- DOCKER_BUILDKIT=1 docker build --build-arg RHEL_ORG=... --build-arg RHEL_ACTIVATION_KEY=... --no-cache --platform linux/amd64 --secret id=nginx-crt,src=nginx-repo.crt --secret id=nginx-key,src=nginx-repo.key --secret id=license-jwt,src=./license.jwt -t app-protect-dos .
+ DOCKER_BUILDKIT=1 docker build --build-arg RHEL_ORG=... --build-arg RHEL_ACTIVATION_KEY=... --no-cache --platform linux/amd64 --secret id=nginx-crt,src=nginx-repo.crt --secret id=nginx-key,src=nginx-repo.key -t app-protect-dos .
```
**Notes:**
@@ -1557,7 +1528,7 @@ Make sure to replace upstream and proxy pass directives in this example with rel
10. Create a container based on this image, for example, `my-app-protect-dos` container:
```shell
- docker run --name my-app-protect-dos -p 80:80 -d app-protect-dos
+ docker run --name my-app-protect-dos -p 80:80 -v $(PWD)/license.jwt:/etc/nginx/license.jwt -d app-protect-dos
```
11. Verify that the `my-app-protect-dos` container is up and running with the `docker ps` command:
@@ -1568,293 +1539,27 @@ Make sure to replace upstream and proxy pass directives in this example with rel
### Alpine Dockerfile example
-```dockerfile
-# syntax=docker/dockerfile:1
-# For Alpine 3.22:
-FROM alpine:3.22
-
-# Download and add the NGINX signing keys:
-RUN wget -O /etc/apk/keys/nginx_signing.rsa.pub https://cs.nginx.com/static/keys/nginx_signing.rsa.pub && \
- wget -O /etc/apk/keys/app-protect-security-updates.rsa.pub https://cs.nginx.com/static/keys/app-protect-security-updates.rsa.pub
-
-# Add NGINX Plus repository:
-RUN printf "https://pkgs.nginx.com/plus/alpine/v`egrep -o '^[0-9]+\.[0-9]+' /etc/alpine-release`/main\n" | tee -a /etc/apk/repositories
-
-# Add F5 WAF for NGINX & Dos repositories:
-RUN 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 && \
- printf "https://pkgs.nginx.com/app-protect/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-security-updates/alpine/v`egrep -o '^[0-9]+\.[0-9]+' /etc/alpine-release`/main\n" | tee -a /etc/apk/repositories
-
-# Update the repository and install the most recent versions of the F5 WAF and F5 DoS for NGINX packages (which include NGINX Plus):
-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 \
- apk update && apk add app-protect app-protect-dos && \
- cat license.jwt > /etc/nginx/license.jwt
-
-# Forward request logs to Docker log collector:
-RUN ln -sf /dev/stdout /var/log/nginx/access.log && \
- ln -sf /dev/stderr /var/log/nginx/error.log
-
-# Forward request logs to Docker log collector:
-RUN 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"]
-```
+{{< include "/dos/dockerfiles/alpine-plus-dos-waf.md" >}}
### Amazon Linux Dockerfile example
-```dockerfile
-# syntax=docker/dockerfile:1
-FROM amazonlinux:2023
-
-# Install prerequisite packages:
-RUN dnf -y install ca-certificates
-
-# Add NGINX/NAP WAF/NAP DOS repositories:
-RUN 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 && \
- curl -o /etc/yum.repos.d/app-protect-amazonlinux2023.repo https://cs.nginx.com/static/files/app-protect-amazonlinux2023.repo && \
- curl -o /etc/yum.repos.d/dependencies.amazonlinux2023.repo https://cs.nginx.com/static/files/dependencies.amazonlinux2023.repo
-
-# Update the repository and install the most recent versions of the F5 WAF and F5 DoS for NGINX packages (which include NGINX Plus):
-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 app-protect app-protect-dos && \
- cat license.jwt > /etc/nginx/license.jwt && \
- rm /etc/yum.repos.d/plus-amazonlinux2023.repo && \
- rm /etc/yum.repos.d/app-protect-dos-amazonlinux2023.repo && \
- dnf clean all && \
- rm -rf /var/cache/dnf && \
- rm -rf /var/cache/yum
-
-# Forward request logs to Docker log collector:
-RUN 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"]
-```
+{{< include "/dos/dockerfiles/amazon-plus-dos-waf.md" >}}
### Debian Docker Deployment Example
-```Dockerfile
-# Where version can be: bullseye/bookworm
-FROM debian:bullseye
-
-# Install prerequisite packages:
-RUN apt-get update && \
- apt-get install -y --no-install-recommends 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 && \
- wget -qO - https://cs.nginx.com/static/keys/app-protect-security-updates.key | gpg --dearmor | tee /usr/share/keyrings/app-protect-security-updates.gpg > /dev/null
-
-# Add NGINX Plus, NGINX App Protect and F5 DoS for NGINX repository:
-RUN 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-dos/debian `lsb_release -cs` nginx-plus\n" | tee /etc/apt/sources.list.d/nginx-app-protect-dos.list \
- && printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/app-protect/debian `lsb_release -cs` nginx-plus\n" | tee /etc/apt/sources.list.d/nginx-app-protect.list \
- && printf "deb [signed-by=/usr/share/keyrings/app-protect-security-updates.gpg] https://pkgs.nginx.com/app-protect-security-updates/debian `lsb_release -cs` nginx-plus\n" | tee /etc/apt/sources.list.d/app-protect-security-updates.list
-
-# Download the apt configuration to `/etc/apt/apt.conf.d`:
-RUN wget -P /etc/apt/apt.conf.d https://cs.nginx.com/static/files/90pkgs-nginx
-
-# Update the repository and install the most recent versions of the F5 WAF and F5 DoS for NGINX packages (which includes NGINX Plus):
-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 app-protect app-protect-dos && \
- cat license.jwt > /etc/nginx/license.jwt && \
- apt-get remove --purge --auto-remove -y && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx-plus.list /etc/apt/sources.list.d/nginx-app-protect.list /etc/apt/sources.list.d/nginx-app-protect-dos.list && \
- rm -rf /etc/apt/apt.conf.d/90nginx /var/lib/apt/lists/*
-
-# Forward request logs to Docker log collector:
-RUN 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"]
-```
+{{< include "/dos/dockerfiles/debian-plus-dos-waf.md" >}}
### Ubuntu Docker Deployment Example
-```Dockerfile
-# Where version can be:jammy/noble
-FROM ubuntu:noble
-
-# Install prerequisite packages:
-RUN 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 && \
- wget -qO - https://cs.nginx.com/static/keys/app-protect-security-updates.key | gpg --dearmor | tee /usr/share/keyrings/app-protect-security-updates.gpg > /dev/null
-
-# Add NGINX Plus, NGINX App Protect and F5 DoS for NGINX repository:
-RUN 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-dos/ubuntu `lsb_release -cs` nginx-plus\n" | tee /etc/apt/sources.list.d/nginx-app-protect-dos.list \
- && printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/app-protect/ubuntu `lsb_release -cs` nginx-plus\n" | tee /etc/apt/sources.list.d/nginx-app-protect.list \
- && printf "deb [signed-by=/usr/share/keyrings/app-protect-security-updates.gpg] https://pkgs.nginx.com/app-protect-security-updates/debian `lsb_release -cs` nginx-plus\n" | tee /etc/apt/sources.list.d/app-protect-security-updates.list
-
-# Download the apt configuration to `/etc/apt/apt.conf.d`:
-RUN wget -P /etc/apt/apt.conf.d https://cs.nginx.com/static/files/90pkgs-nginx
-
-# Update the repository and install the most recent versions of the F5 WAF and F5 DoS for NGINX packages (which include NGINX Plus):
-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 app-protect app-protect-dos && \
- cat license.jwt > /etc/nginx/license.jwt && \
- apt-get remove --purge --auto-remove -y && rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx-plus.list /etc/apt/sources.list.d/nginx-app-protect.list /etc/apt/sources.list.d/nginx-app-protect-dos.list && \
- rm -rf /etc/apt/apt.conf.d/90nginx /var/lib/apt/lists/*
-
-# Forward request logs to Docker log collector:
-RUN 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"]
-```
+{{< include "/dos/dockerfiles/ubuntu-plus-dos-waf.md" >}}
## F5 DoS for NGINX Arbitrator
-### Overview
-
-F5 DoS for NGINX arbitrator orchestrates all the running F5 DoS for NGINX instances to synchronize local/global attack start/stop.
-
-F5 DoS for NGINX arbitrator serves as a central coordinating component for managing multiple instances of App Protect DoS in a network. It is needed when there are more than one F5 DoS for NGINX instances. Its primary function is to ensure that all instances are aware of and share the same state for each protected object. Here's a clearer breakdown of how it works and why it's necessary:
-
-How F5 DoS for NGINX Arbitrator Works:
-
-- **Collecting State Periodically**: The arbitrator regularly collects the state information from all running instances of App Protect DoS. This collection occurs at set intervals, typically every 10 seconds.
-- **State Initialization for New Instances**: When a new App Protect DoS instance is created, it doesn't start with a blank or uninitialized state for a protected object. Instead, it retrieves the initial state for the protected object from the arbitrator.
-- **Updating State in Case of an Attack**: If an attack is detected by one of the App Protect DoS instances, that instance sends an attack notification to the arbitrator. The arbitrator then updates the state of the affected protected object to indicate that it is under attack. Importantly, this updated state is propagated to all other instances.
-
-### Why F5 DoS for NGINX Arbitrator is Necessary
-
-F5 DoS for NGINX Arbitrator is essential for several reasons:
-
-- **Global State Management**: Without the arbitrator, each individual instance of App Protect DoS would manage its own isolated state for each protected object. This isolation could lead to inconsistencies. For example, if instance A declared an attack on a protected object named "PO-Example," instance B would remain unaware of this attack, potentially leaving the object vulnerable.
-- **Uniform Attack Detection**: With the arbitrator in place, when instance A detects an attack on "PO-Example" and reports it to the arbitrator, the state of "PO-Example" is immediately updated to indicate an attack. This means that all instances, including instance B, are aware of the attack and can take appropriate measures to mitigate it.
-
-In summary, F5 DoS for NGINX Arbitrator acts as a central coordinator to maintain a consistent and up-to-date global state for protected objects across multiple instances of App Protect DoS. This coordination helps ensure that attacks are properly detected and mitigated, and that knowledge gained by one instance is efficiently shared with others, enhancing the overall security of the network.
-
-
-### F5 DoS for NGINX Arbitrator Deployment
-
-1. Pull the official F5 DoS for NGINX Arbitrator image with the command:
-
- ```shell
- docker pull docker-registry.nginx.com/nap-dos/app_protect_dos_arb:latest
- ```
-
-2. Create a container based on this image, for example, `app-protect-dos-arb` container:
-
- ```shell
- docker run --name app_protect_dos_arb -p 3000:3000 -d docker-registry.nginx.com/nap-dos/app_protect_dos_arb
- ```
-
-3. Verify that the `app-protect-dos-arb` container is up and running with the `docker ps` command.
-
-4. DNS records are required for F5 DoS for NGINX Arbitrator to work properly and be accessible by F5 DoS for NGINX servers. Ensure that the `svc-appprotect-dos-arb` or configured Arbitrator FQDN (with `app_protect_dos_arb_fqdn` directive) has a valid DNS resolution.
-This step is necessary only for VM/Docker deployments with arbitrator. When the arbitrator is in the same Kubernetes namespace as F5 DoS for NGINX, this step is not needed.
-
-### Multi-VM Deployment
-
-The Arbitrator service is standalone. Once it is down, it can be seamlessly re-started. It will immediately recover all the needed information from F5 DoS for NGINX instances that communicate to it every 10 sec. It’s downtime is around 10-20 seconds which will not affect the F5 DoS for NGINX working.
-
-F5 DoS for NGINX Arbitrator service connects to port 3000 and can be seen under App Protect DoS instances. All modules try to connect to this service automatically. If it’s not accessible, each instance works in standalone mode.
-
-There is no such option for authentications between F5 DoS for NGINX servers and Arbitrator service like MTLS or password . Currently Arbitrator service is not exposed outside of the namespace. It is customers responsibility to isolate it from outside. It is applicable to any deployment of Arbitrator, not only to multi-VM.
-
+{{< include "/dos/dos-arbitrator.md" >}}
+
## Post-Installation Checks
-You can run the following commands to ensure that F5 DoS for NGINX enforcement is operational.
-
-1. Check that the three processes needed for F5 DoS for NGINX are running using `ps aux`:
-
- - admd
- - nginx: master process
- - nginx: worker process
-
- ```shell
- USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
- nginx 7759 0.0 0.0 113120 1200 ? Ss Sep06 0:00 /bin/sh -c /usr/bin/admd -d --log info > /var/log/adm/admd.log 2>&1
- root 7765 0.0 0.0 87964 1464 ? Ss Sep06 0:00 nginx: master process /usr/sbin/nginx -g daemon off;
- nginx 7767 0.0 0.1 615868 8188 ? Sl Sep06 0:04 nginx: worker process
- ```
-
-2. Verify that there are no NGINX errors in the `/var/log/nginx/error.log` and that the policy compiled successfully:
-
- ```shell
- 2020/09/07 15:33:44 [notice] 9307#9307: using the "epoll" event method
- 2020/09/07 15:33:44 [notice] 9307#9307: nginx/1.19.0 (nginx-plus-r22)
- 2020/09/07 15:33:44 [notice] 9307#9307: built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
- 2020/09/07 15:33:44 [notice] 9307#9307: OS: Linux 3.10.0-327.28.3.el7.x86_64
- 2020/09/07 15:33:44 [notice] 9307#9307: getrlimit(RLIMIT_NOFILE): 1024:4096
- 2020/09/07 15:33:44 [notice] 9310#9310: start worker processes
- 2020/09/07 15:33:44 [notice] 9310#9310: start worker process 9311
- PID <9311>, WORKER <0>, Function adm_ngx_init_process, line 684, version: 22+1.19.4-1.el7.ngx
- ```
-
-3. Check that by applying an attack, the attacker IP addresses are blocked while the good traffic pass through:
-
- a. Simulate good traffic:
-
- ```shell
- echo "Start Good Traffic 2"
- while true; do
- curl ${VS}/good1 &
- curl ${VS}/good2 &
- curl ${VS}/good3 &
- curl ${VS}/good4
- sleep 0.1
- done &
- ```
-
- b. After 7 minutes start the attack:
-
- ```shell
- while [ true ]
- do
- ab -B ${BAD_IP1} -l -r -n 1000000 -c 150 -d -H "Host: evil.net" -H "Pragma: no-cache" -H "Cache-Control: no-cache" -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" -H "Upgrade-Insecure-Requests: 1" -H "User-Agent: WireXBot" -H "x-requested-with:" -H "Referer: http://10.0.2.1/none.html" -H "Accept-Encoding: gzip, deflate" -H "Accept-Language: en-US" http://${VS}/ &
- ab -B ${BAD_IP2} -l -r -n 1000000 -c 150 -d -H "Host: evil.net" -H "Pragma: no-cache" -H "Cache-Control: no-cache" -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" -H "Upgrade-Insecure-Requests: 1" -H "User-Agent: WireXBot" -H "x-requested-with:" -H "Referer: http://10.0.2.1/none.html" -H "Accept-Encoding: gzip, deflate" -H "Accept-Language: en-US" http://${VS}/ &
- ab -B ${BAD_IP3} -l -r -n 1000000 -c 150 -d -s 10 -H "Host: evil.net" -H "Pragma: no-cache" -H "Cache-Control: no-cache" -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" -H "Upgrade-Insecure-Requests: 1" -H "User-Agent: WireXBot" -H "x-requested-with:" -H "Referer: http://10.0.2.1/none.html" -H "Accept-Encoding: gzip, deflate" -H "Accept-Language: en-US" http://${VS}/
-
- killall ab
- done
- ```
-
- c. See that the good traffic continue as usual while the attackers receive denial of service.
+{{< include "dos/install-post-checks.md" >}}
To check F5 WAF for NGINX alongside F5 DoS for NGINX, just perform the normal tests as specified at [Admin Guide](https://docs.nginx.com/waf/install/virtual-environment/#post-installation-checks)
@@ -1897,315 +1602,6 @@ Review the syslog ports by entering the following command:
semanage port -l | grep syslog
```
-## Kubernetes Deployment Examples
-
-### App Protect DoS
-
-`appprotect-dos.yaml`:
-
-```yaml
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: appprotect-dos
- namespace: appprotect-dos-wp-diff
- labels:
- app: appprotect-dos
-spec:
- replicas: 1
- revisionHistoryLimit: 10
- selector:
- matchLabels:
- app: appprotect-dos
- strategy:
- type: RollingUpdate
- rollingUpdate:
- maxSurge: 2
- maxUnavailable: 1
- template:
- metadata:
- labels:
- app: appprotect-dos
- spec:
- containers:
- - name: ubuntu-bados
- image: example.com/ubuntu_app_protect_dos_r36:latest
- imagePullPolicy: Always
- resources:
- requests:
- cpu: "200m"
- memory: "500Mi"
- limits:
- cpu: "900m"
- memory: "800Mi"
- ports:
- - containerPort: 80
- name: web
- - containerPort: 8090
- name: probe
- - containerPort: 8091
- name: probe500
- livenessProbe:
- httpGet:
- path: /app_protect_dos_liveness
- port: 8090
- initialDelaySeconds: 0
- periodSeconds: 10
- readinessProbe:
- httpGet:
- path: /app_protect_dos_readiness
- port: 8090
- initialDelaySeconds: 0
- periodSeconds: 10
- volumeMounts:
- - name: shared
- mountPath: /shared/
- - name: conf
- mountPath: /etc/nginx/nginx.conf
- subPath: nginx.conf
- - name: root-script
- mountPath: /root/entrypoint.sh
- subPath: entrypoint.sh
- - name: log-default
- mountPath: /etc/app_protect_dos/log-default.json
- subPath: log-default.json
- volumes:
- - name: shared
- persistentVolumeClaim:
- claimName: pvc-appprotect-dos-shared
- - name: conf
- configMap:
- name: cm-appprotect-dos-nginx
- items:
- - key: nginx.conf
- path: nginx.conf
- - name: root-script
- configMap:
- name: cm-appprotect-dos-entry
- defaultMode: 0755
- items:
- - key: entrypoint.sh
- path: entrypoint.sh
- - name: log-default
- configMap:
- name: cm-appprotect-dos-log-default
- defaultMode: 0755
- items:
- - key: log-default.json
- path: log-default.json
-```
-
-`svc-appprotect-dos.yaml`:
-
-```yaml
-apiVersion: v1
-kind: Service
-metadata:
- name: svc-appprotect-dos
- namespace: appprotect-dos-wp-diff
- labels:
- app: appprotect-dos
-spec:
- ports:
- - name: app
- port: 80
- protocol: TCP
- nodePort: 80
- selector:
- app: appprotect-dos
- type: NodePort
-```
-
-`log-default.json`:
-
-```json
-{
- "filter": {
- "traffic-mitigation-stats": "all",
- "bad-actors": "all",
- "attack-signatures": "all"
- }
-}
-```
-
-`entrypoint.sh`:
-
-```shell
-#!/usr/bin/env bash
-USER=nginx
-LOGDIR=/var/log/adm
-
-# prepare environment
-mkdir -p /var/run/adm /tmp/cores ${LOGDIR}
-chmod 755 /var/run/adm /tmp/cores ${LOGDIR}
-chown ${USER}:${USER} /var/run/adm /tmp/cores ${LOGDIR}
-
-# run processes
-/bin/su -s /bin/bash -c "/usr/bin/adminstall > ${LOGDIR}/adminstall.log 2>&1" ${USER}
-/usr/sbin/nginx -g 'daemon off;' &
-/bin/su -s /bin/bash -c "/usr/bin/admd -d --log info > ${LOGDIR}/admd.log 2>&1 &" ${USER}
-```
-
-`install.sh`:
-
-```shell
-#!/bin/bash
-set -ex
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
-kubectl -n appprotect-dos-wp-diff create cm cm-appprotect-dos-nginx --from-file ${DIR}/nginx.conf
-kubectl -n appprotect-dos-wp-diff create cm cm-appprotect-dos-entry --from-file ${DIR}/entrypoint.sh
-kubectl -n appprotect-dos-wp-diff create cm cm-appprotect-dos-log-default --from-file ${DIR}/log-default.json
-kubectl create -f ${DIR}/appprotect-dos.yaml
-#kubectl create -f ${DIR}/svc-appprotect-dos.yaml
-```
-
-`nginx.conf`:
-
-```nginx
-user nginx;
-worker_processes 1;
-error_log /var/log/nginx/error.log debug;
-worker_rlimit_nofile 65535;
-working_directory /tmp/cores;
-
-load_module modules/ngx_http_app_protect_dos_module.so;
-
-events {
- worker_connections 65535;
-}
-http {
- include /etc/nginx/mime.types;
- default_type application/octet-stream;
-
- log_format log_napd ', vs_name_al=$app_protect_dos_vs_name, ip=$remote_addr, tls_fp=$app_protect_dos_tls_fp, '
- 'outcome=$app_protect_dos_outcome, reason=$app_protect_dos_outcome_reason, '
- 'ip_tls=$remote_addr:$app_protect_dos_tls_fp, ';
-
- app_protect_dos_security_log_enable on;
- app_protect_dos_security_log "/etc/app_protect_dos/log-default.json" /var/log/adm/logger.log;
- # app_protect_dos_security_log "/etc/app_protect_dos/log-default.json" syslog:server=1.2.3.4:5261;
-
- app_protect_dos_liveness on; # uri:/app_protect_dos_liveness port:8090
- app_protect_dos_readiness on; # uri:/app_protect_dos_readiness port:8090
-
- server {
- listen 80 reuseport;
- server_name serv;
-
- set $loggable '0';
- access_log /var/log/nginx/access.log log_napd if=$loggable;
- # access_log syslog:server=1.1.1.1:5561 log_napd if=$loggable;
-
- app_protect_dos_policy_file "/etc/app_protect_dos/BADOSDefaultPolicy.json";
-
- location / {
- app_protect_dos_enable on;
- app_protect_dos_name "App1";
- app_protect_dos_monitor uri=http://serv:80/ protocol=http1;
- proxy_pass http://1.2.3.4:80;
- }
- }
-
- server {
- listen 8090;
- server_name probe;
-
- location / {
- proxy_pass http://localhost:8091;
- }
- }
-
- server {
- listen 8091;
- return 503;
- }
-
- sendfile on;
- tcp_nopush on;
- keepalive_timeout 65;
-}
-```
-
-### App Protect DoS Arbitrator
-
-Arbitrator (arb) is an internal service that is essential for the scaling scenarios. The arbitrator service should be deployed in the same namespace as F5 DoS for NGINX.
-
-`appprotect-dos-arb.yaml`:
-
-```yaml
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: appprotect-dos-arb
- namespace: appprotect-dos-wp-diff
-spec:
- replicas: 1
- selector:
- matchLabels:
- app: appprotect-dos-arb
- template:
- metadata:
- labels:
- app: appprotect-dos-arb
- spec:
- containers:
- - name: arb-svc
- image: example.com/app_protect_dos_arb:latest
- resources:
- requests:
- cpu: "200m"
- memory: "500Mi"
- limits:
- cpu: "900m"
- memory: "800Mi"
- ports:
- - containerPort: 3000
-```
-
-`svc-appprotect-dos-arb.yaml`:
-
-```yaml
-apiVersion: v1
-kind: Service
-metadata:
- name: svc-appprotect-dos-arb
- namespace: appprotect-dos-wp-diff
-spec:
- selector:
- app: appprotect-dos-arb
- ports:
- - name: arb
- port: 3000
- protocol: TCP
- targetPort: 3000
- clusterIP: None
-```
-
-`install_appprotect-arb.sh`:
-
-```shell
-#!/bin/bash
-
-set -ex
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
-kubectl -n appprotect-dos-wp-diff apply -f ${DIR}/appprotect-dos-arb.yaml
-kubectl -n appprotect-dos-wp-diff apply -f ${DIR}/svc-appprotect-dos-arb.yaml
-```
-
-`install F5 DoS for NGINX with ARB service`:
-
-```shell
-#!/bin/bash
-
-set -ex
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
-kubectl create ns appprotect-dos-wp-diff
-${DIR}/appprotect-dos/install.sh
-${DIR}/appprotect-dos-arb/install_appprotect-dos-arb.sh
-```
-
----
-
## App Protect DoS eBPF manager
### Overview
diff --git a/content/nap-dos/directives-and-policy/learn-about-directives-and-policy.md b/content/nap-dos/directives-and-policy/learn-about-directives-and-policy.md
index 39dffc953b..397e6ebabe 100644
--- a/content/nap-dos/directives-and-policy/learn-about-directives-and-policy.md
+++ b/content/nap-dos/directives-and-policy/learn-about-directives-and-policy.md
@@ -343,7 +343,24 @@ Any other response will indicate that our NGINX module (F5 DoS for NGINX) has no
**Example:**
```nginx
-app_protect_dos_liveness on uri:/liveness port:8090;
+http {
+
+ app_protect_dos_readiness on uri:/liveness port:8090;
+
+ server {
+ listen 8090;
+ server_name probe;
+
+ location / {
+ proxy_pass http://localhost:8091;
+ }
+ }
+
+ server {
+ listen 8091;
+ return 503;
+ }
+}
```
### Readiness probe directive (`app_protect_dos_readiness`)
@@ -375,7 +392,24 @@ RC 200 "Ready" will occur if two conditions are met:
**Example:**
```nginx
-app_protect_dos_readiness on uri:/readiness port:8090;
+http {
+
+ app_protect_dos_readiness on uri:/readiness port:8090;
+
+ server {
+ listen 8090;
+ server_name probe;
+
+ location / {
+ proxy_pass http://localhost:8091;
+ }
+ }
+
+ server {
+ listen 8091;
+ return 503;
+ }
+}
```
### Arbitrator FQDN directive (`app_protect_dos_arb_fqdn`)
diff --git a/content/nap-dos/monitoring/types-of-logs.md b/content/nap-dos/monitoring/types-of-logs.md
index eea14621c6..3a1d9de4d6 100644
--- a/content/nap-dos/monitoring/types-of-logs.md
+++ b/content/nap-dos/monitoring/types-of-logs.md
@@ -12,8 +12,8 @@ There are 4 types of logs corresponding to App Protect DoS:
- [Security Log](#security-log): The general picture of the site and how App Protect DoS processed it, including anomalies and signatures found.
- [Operation Log](#operation-log): Events such as configuration errors or warnings.
-- [Debug Logs](#debug-log): Technical messages at different levels of severity used to debug and resolve incidents and error behaviors.
- [Request Logging](#request-log): F5 DoS for NGINX adds information to each request logged to NGINX's access logging mechanism.
+- [Debug Logs](#debug-log): Technical messages at different levels of severity used to debug and resolve incidents and error behaviors.
{{< call-out "note" >}}
NGINX does not have audit logs in the sense of *"**who** did **what**"*. This can be done either from the orchestration system controlling NGINX (such as NGINX Controller) or by tracking the configuration files and the systemd invocations using Linux tools.
@@ -48,7 +48,7 @@ This directive determines the destination of the `access_log` and the name of th
### App Protect DoS Variables
These are the variables added to Access Log. They are a subset of the Security log attributes. The Security log names are prefixed with `$app_protect_dos`.
For more information refer to [F5 DoS for NGINX Access Log]({{< ref "/nap-dos/monitoring/access-log.md" >}})
-## Debug Log - F5 DoS for NGINX
+## Debug Log
The F5 DoS for NGINX Debug log is used to troubleshoot the functionality of the product.
The path of the log is at a fixed location: `/var/log/adm/admd.log`.
diff --git a/content/nap-dos/releases/about-4.9.md b/content/nap-dos/releases/about-4.9.md
new file mode 100644
index 0000000000..ab5eddacdc
--- /dev/null
+++ b/content/nap-dos/releases/about-4.9.md
@@ -0,0 +1,40 @@
+---
+title: F5 DoS for NGINX 4.9
+toc: true
+weight: 30
+nd-docs: DOCS-1783
+nd-content-type: reference
+nd-product: F5DOSN
+---
+
+Here you can find the release information for F5 DoS for NGINX v4.9
+
+F5 DoS for NGINX provides behavioral protection against Denial of Service (DoS) for your web applications.
+
+## Release 4.9
+
+December 1, 2025
+
+### New features
+
+- R37 support
+- Add support for Debian 13 (Trixie)
+- Add support for RHEL 10 and Rocky Linux 10
+- Bugs fixing
+
+### Supported packages
+
+| Distribution name | Package file |
+|--------------------------|------------------------------------------------------|
+| Alpine 3.21 | _app-protect-dos-37+4.9.5-r1.apk_ |
+| Alpine 3.22 | _app-protect-dos-37+4.9.5-r1.apk_ |
+| Amazon Linux 2023 | _app-protect-dos-37+4.9.5-1.amzn2023.ngx.x86_64.rpm_ |
+| RHEL 8 and Rocky Linux 8 | _app-protect-dos-37+4.9.5-1.el8.ngx.x86_64.rpm_ |
+| RHEL 9 and Rocky Linux 9 | _app-protect-dos-37+4.9.5-1.el9.ngx.x86_64.rpm_ |
+| RHEL 10 and Rocky Linux 10 | _app-protect-dos-37+4.9.5-1.el10.ngx.x86_64.rpm_ |
+| Debian 11 | _app-protect-dos_37+4.9.5-1\~bullseye_amd64.deb_ |
+| Debian 12 | _app-protect-dos_37+4.9.5-1\~bookworm_amd64.deb_ |
+| Debian 13 (Trixie) | _app-protect-dos_37+4.9.5-1\~trixie_amd64.deb_ |
+| Ubuntu 22.04 | _app-protect-dos_37+4.9.5-1\~jammy_amd64.deb_ |
+| Ubuntu 24.04 | _app-protect-dos_37+4.9.5-1\~noble_amd64.deb_ |
+| NGINX Plus | _NGINX Plus R37_ |
diff --git a/content/nap-dos/troubleshooting/how-to-troubleshoot.md b/content/nap-dos/troubleshooting/how-to-troubleshoot.md
index 019de886ed..123f805227 100644
--- a/content/nap-dos/troubleshooting/how-to-troubleshoot.md
+++ b/content/nap-dos/troubleshooting/how-to-troubleshoot.md
@@ -28,7 +28,7 @@ This Troubleshooting Guide is intended to provide guidance to customers in the d
| More protected objects than expected | The `app_protect_dos_enable` directive is inherited by all server and location blocks beneath it, each block will be a protected object.
Consider moving this directive from outer to inner block.
Refer to: [F5 DoS for NGINX - Directives and Policy]({{< ref "/nap-dos/directives-and-policy/learn-about-directives-and-policy.md" >}}) |
| `No DOS protection for ngx_worker at idx X` warning message | There are more nginx processes than allowed.
Either decrease the number of nginx processes (ngx_processes directive in `nginx.conf` file) or increase the number of supported workers for F5 DoS for NGINX using the flag `--max-workers NUM` for `/usr/bin/adminstall`. |
| `unknown directive 'app_protect_dos_xxx'` error message | App Protect DOS module is not loaded. Add this line to the main (global) context of nginx.conf:
`load_module "/etc/nginx/modules/ngx_http_app_protect_dos_module.so";` |
-| NGINX struggles handling a high rate of incoming connections | Linux machine should be tuned for optimal performance.
Refer to [Tuning NGINX for Performance](https://www.nginx.com/blog/tuning-nginx/) |
+| NGINX struggles handling a high rate of incoming connections | Linux machine should be tuned for optimal performance.
Refer to [Tuning NGINX for Performance](https://www.f5.com/company/blog/nginx/tuning-nginx) |
| Error in `adminstall` process, such as `Failed to allocate` | Insufficient memory to allocate all the required resources.
Increase the `--memory` size or decrease the number of nginx workers (`--max_workers`) if not all of them are going to be in use.
Use the `--help` flag for more info. |
{{}}
diff --git a/content/nginx-one-console/waf-integration/waf-security-dashboard/_index.md b/content/nginx-one-console/waf-integration/waf-security-dashboard/_index.md
index 09958ef21f..629a34bdfb 100644
--- a/content/nginx-one-console/waf-integration/waf-security-dashboard/_index.md
+++ b/content/nginx-one-console/waf-integration/waf-security-dashboard/_index.md
@@ -12,6 +12,7 @@ This section covers:
- [Security monitoring overview]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/security-monitoring-overview.md" >}}) — what the security dashboard is, the data pipeline behind it, and what you can do with it.
- [secops_dashboard log profile]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/default-log-profile.md" >}}) — the immutable, pre-compiled log profile the dashboard depends on.
- [Set up security monitoring]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/set-up-security-monitoring.md" >}}) — install F5 WAF for NGINX, configure the log profile, and forward events through NGINX Agent.
+- [Troubleshoot security monitoring on the local data plane]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/local-dataplane-troubleshooting.md" >}}) — verify the embedded OpenTelemetry Collector log, the generated collector pipeline, and debug forwarding on the data plane.
- [Security dashboard reference]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/dashboard-metrics-reference.md" >}}) — dashboard tabs, global controls, and how each widget maps to an underlying dimension.
- [Find a security event by Support ID]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/find-event-by-support-id.md" >}}) — look up a single security event by its Support ID for quick triage.
- [Query security events through the API]({{< ref "/nginx-one-console/api/query-events-api.md" >}}) — list events and run analytics queries programmatically.
diff --git a/content/nginx-one-console/waf-integration/waf-security-dashboard/local-dataplane-troubleshooting.md b/content/nginx-one-console/waf-integration/waf-security-dashboard/local-dataplane-troubleshooting.md
new file mode 100644
index 0000000000..bd0ccaf4d7
--- /dev/null
+++ b/content/nginx-one-console/waf-integration/waf-security-dashboard/local-dataplane-troubleshooting.md
@@ -0,0 +1,180 @@
+---
+nd-content-type: how-to
+nd-docs: DOCS-000
+nd-product: NONECO
+title: Troubleshoot security monitoring on the local data plane
+description: "Check the local NGINX Agent and OpenTelemetry Collector configuration when F5 WAF for NGINX security events do not appear in NGINX One Console."
+weight: 450
+toc: true
+nd-keywords: "security monitoring, troubleshooting, local data plane, nginx-agent, opentelemetry collector, secops_dashboard, WAF events"
+nd-summary: >
+ Use this guide when F5 WAF for NGINX security events do not appear in the NGINX One Console security dashboard even after you complete the setup flow.
+ It walks through the local data plane checks for invalid log profiles, missing OpenTelemetry log pipelines, and debug logging.
+ These checks help confirm whether NGINX Agent is receiving, parsing, and forwarding security events correctly.
+nd-audience: operator
+---
+
+## Overview
+
+Use this guide when you completed [Set up security monitoring]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/set-up-security-monitoring.md" >}}), sent test traffic, and still do not see F5 WAF for NGINX security events in the NGINX One Console dashboard.
+
+This guide focuses on the **local data plane**. It helps you verify four things:
+
+1. Whether the embedded OpenTelemetry Collector is dropping security logs because the deployed log profile format is wrong.
+2. Whether the NGINX Agent embedded OpenTelemetry Collector is the only process listening on port `1514`.
+3. Whether the NGINX agent generated OpenTelemetry Collector config has the expected security log pipeline.
+4. Whether debug logging shows the collector forwarding security logs to NGINX One Console.
+
+---
+
+## Before you begin
+
+Before you begin, ensure you have:
+
+- Access to the data plane host where NGINX Plus, F5 WAF for NGINX, and NGINX Agent are running.
+- Permission to read `/var/log/nginx-agent/` and `/etc/nginx-agent/`.
+- Security monitoring already configured by following [Set up security monitoring]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/set-up-security-monitoring.md" >}}).
+
+---
+
+## 1. Check for invalid log profile errors
+
+Check whether NGINX Agent's embedded OpenTelemetry Collector is rejecting incoming F5 WAF for NGINX security logs. This happens when the logs don't match the format the security monitoring pipeline expects.
+
+Open the collector log on the data plane:
+
+```shell
+sudo tail -f /var/log/nginx-agent/opentelemetry-collector-agent.log
+```
+
+Look for either of the following errors:
+
+```text
+Security violation log body is not a string. All security violation logs will be dropped until the collector is restarted.
+```
+
+```text
+Security violation log does not appear to be CSV format. Ensure the NAP logging profile uses the secops-dashboard-log format. All security violation logs will be dropped until the collector is restarted.
+```
+
+If you see either message, the data plane probably isn't using the NGINX One Console default `secops_dashboard` log profile for `app_protect_security_log`. Make sure every http, server, or location block that should log violations uses this profile.
+
+### Fix
+
+1. In NGINX One Console, redeploy the default [`secops_dashboard` log profile]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/default-log-profile.md" >}}) to the affected instance.
+2. Update the NGINX configuration so `app_protect_security_log` points to that deployed bundle.
+3. Restart NGINX Agent to reset the embedded OpenTelemetry Collector after you correct the log profile.
+
+After the restart, send a new test request and check the dashboard again.
+
+---
+
+## 2. Check that port `1514` is reserved for the collector
+
+F5 WAF for NGINX sends security logs to `syslog:server=127.0.0.1:1514`. If another process is listening on port `1514`, the NGINX Agent embedded OpenTelemetry Collector may never receive the security logs.
+
+Run the following command on the data plane:
+
+```shell
+sudo ss -ltnp | grep 1514
+```
+
+Confirm that no unexpected process is listening on port `1514`. If another service is bound to that port, stop or reconfigure it. The embedded collector needs port `1514` free to receive F5 WAF for NGINX security logs.
+
+---
+
+## 3. Verify the generated OpenTelemetry log pipeline
+
+If the collector log does **not** show either invalid-log-profile error, verify that the generated OpenTelemetry Collector config still contains the security log pipeline.
+
+{{< call-out "note" >}}NGINX Agent generates this security log pipeline only when at least one `http`, `server`, or `location` block is set up with `app_protect_security_log` pointing to `syslog:server=127.0.0.1:1514`. If no protected context uses that syslog destination, the pipeline isn't generated. Without it, no WAF security logs are forwarded to NGINX One Console.{{< /call-out >}}
+
+Open the generated collector config:
+
+```shell
+sudo grep -A 12 "logs/default:" /etc/nginx-agent/opentelemetry-collector-agent.yaml
+```
+
+Confirm it includes the following pipeline:
+
+```yaml
+logs/default:
+ receivers:
+ - tcplog/nginx_app_protect
+ processors:
+ - securityviolationsfilter/default
+ - batch/default_logs
+ - resource/default
+ exporters:
+ - otlp/default
+```
+
+This pipeline accepts F5 WAF for NGINX security logs from `tcplog/nginx_app_protect`. It filters and batches the logs, then exports them to NGINX One Console through `otlp/default`.
+
+If this pipeline is missing or materially different, the collector isn't set up as expected for security monitoring. In that case, review any custom collector configuration merged through `nginx-agent.conf`, then restart NGINX Agent so it regenerates the collector config.
+
+---
+
+## 4. Enable debug logging for the collector pipeline
+
+If the collector log doesn't show the invalid-log-profile errors and the generated pipeline looks correct, turn on debug logging. This lets you confirm the embedded collector is processing and forwarding security logs.
+
+Add the following configuration to the end of `/etc/nginx-agent/nginx-agent.conf`:
+
+```yaml
+collector:
+ exporters:
+ debug: {}
+ pipelines:
+ logs:
+ default:
+ receivers:
+ - tcplog/nginx_app_protect
+ processors:
+ - securityviolationsfilter/default
+ - batch/default_logs
+ exporters:
+ - otlp/default
+ - debug
+```
+
+Restart NGINX Agent so the updated collector configuration is applied.
+
+The `debug` exporter causes the embedded OpenTelemetry Collector to write its processed log output to:
+
+```text
+/var/log/nginx-agent/opentelemetry-collector-agent.log
+```
+
+Use this to confirm the collector is handling F5 WAF for NGINX security events locally. It continues forwarding them to NGINX One Console through `otlp/default`.
+
+{{< call-out "note" >}}The debug exporter increases log volume. Remove it after troubleshooting so the collector log returns to its normal verbosity.{{< /call-out >}}
+
+---
+
+## What to do next
+
+After each fix:
+
+1. Restart NGINX Agent.
+2. Send a new test request through the protected application path. For example requests, see [Example test requests for a default blocking policy]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/set-up-security-monitoring.md#example-test-requests-for-a-default-blocking-policy" >}}).
+3. Check `/var/log/nginx-agent/opentelemetry-collector-agent.log`.
+4. Recheck the **WAF** > **Security Dashboard** and **Event Logs** tab in NGINX One Console.
+
+If the collector is processing events locally but the dashboard remains empty, gather the following and provide them to F5 support:
+
+- NGINX Agent configuration: `/etc/nginx-agent/nginx-agent.conf`
+- Generated OpenTelemetry Collector configuration: `/etc/nginx-agent/opentelemetry-collector-agent.yaml`
+- NGINX Agent log: `/var/log/nginx-agent/agent.log`
+- Embedded OpenTelemetry Collector log: `/var/log/nginx-agent/opentelemetry-collector-agent.log`
+
+---
+
+## References
+
+For more information, see:
+
+- [Set up security monitoring]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/set-up-security-monitoring.md" >}})
+- [secops_dashboard log profile]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/default-log-profile.md" >}})
+- [Security dashboard reference]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/dashboard-metrics-reference.md" >}})
+- [Export NGINX instance metrics]({{< ref "/nginx-one-console/agent/configure-otel-metrics.md" >}})
diff --git a/content/nginx-one-console/waf-integration/waf-security-dashboard/set-up-security-monitoring.md b/content/nginx-one-console/waf-integration/waf-security-dashboard/set-up-security-monitoring.md
index 62ad89a3ab..0a301b06d3 100644
--- a/content/nginx-one-console/waf-integration/waf-security-dashboard/set-up-security-monitoring.md
+++ b/content/nginx-one-console/waf-integration/waf-security-dashboard/set-up-security-monitoring.md
@@ -18,7 +18,7 @@ nd-audience: operator
Use this guide to enable F5 WAF for NGINX security monitoring on an NGINX Plus instance that is already connected to NGINX One Console. After completing the steps, security events appear in the [security monitoring dashboard]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/_index.md" >}}), where you can review attacks, violations, and triggered signatures.
-You deploy the [`secops_dashboard` log profile]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/default-log-profile.md" >}}) to the instance through NGINX One Console. You then add the F5 WAF for NGINX directives to the NGINX configuration using the console's config editor, and verify the pipeline by triggering test violations. NGINX Agent automatically configures its OpenTelemetry collector to forward security events to NGINX One Console when it detects the correct directives in the NGINX configuration. You do not need to edit the NGINX Agent configuration by hand.
+You deploy the [`secops_dashboard` log profile]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/default-log-profile.md" >}}) to the instance through NGINX One Console. You then add the F5 WAF for NGINX directives to the NGINX configuration using the console's config editor, generate test traffic, and confirm the resulting events appear in the dashboard. NGINX Agent automatically configures its OpenTelemetry collector to forward security events to NGINX One Console when it detects the correct directives in the NGINX configuration. You do not need to edit the NGINX Agent configuration by hand.
---
@@ -50,7 +50,7 @@ The security dashboard relies on the `secops_dashboard` log profile to capture s
4. Select **Next**. The wizard displays the F5 WAF for NGINX directive snippet to paste into your NGINX configuration. The wizard also opens the config editor for the target instance.
-5. Open the server block where you want to enable F5 WAF for NGINX (for example, `/etc/nginx/conf.d/default.conf`) and paste the snippet into the `server`, `http`, or `location` context. The snippet looks like this:
+5. Open the NGINX configuration file that handles the traffic you want to monitor (for example, `/etc/nginx/conf.d/default.conf`) and paste the snippet into the `http`, `server`, or `location` context where F5 WAF for NGINX is already enabled. The snippet looks like this:
```nginx
app_protect_security_log_enable on;
@@ -69,10 +69,32 @@ For more on the deployment wizard and the alternative **Add File** > **Existing
When you select **Publish** in the previous step, NGINX One Console pushes the configuration change to the instance and displays a confirmation message. At that point, the F5 WAF for NGINX policy and the `secops_dashboard` log profile are in place on the data plane, and the security log directive is wired to NGINX Agent.
-Any request that F5 WAF for NGINX inspects on the instance produces a security event that flows to NGINX One Console. To see security events in the dashboard:
+Any request that F5 WAF for NGINX inspects on the instance produces a security event that flows to NGINX One Console. Use the following checks to confirm the pipeline end to end:
-1. In NGINX One Console, go to **WAF** > **Security Dashboard**.
-2. As your instance handles traffic, attacks, violations, and triggered signatures appear on the dashboard within about a minute of the request being processed.
+1. Send one or more requests through the protected application path on the instance you just configured. If you have a staging policy or a known test case that triggers a violation, use it so the event is easy to identify. Otherwise, normal inspected traffic is enough to confirm the pipeline.
+2. In NGINX One Console, go to **WAF** > **Security Dashboard**.
+3. Set the time window to **Last 5 minutes**, then add a global filter for the target **Instance**, **Hostname**, or **Policy** so you only see events from the instance you just configured.
+4. Open the **Event Logs** tab and confirm at least one event appears for the request you just sent. Check that the row shows the expected URI, policy, and request status (`blocked`, `alerted`, or `passed`).
+5. Open the event row to confirm the detail panel shows the request context, triggered violations or signatures, and the generated **Support ID**. If you need to verify a single event later, copy the Support ID and use [Find a security event by Support ID]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/find-event-by-support-id.md" >}}).
+
+Events typically appear within about a minute of the request being processed.
+
+### Example test requests for a default blocking policy
+
+If the protected path uses the default F5 WAF for NGINX policy in blocking mode, the following requests commonly produce a `blocked` event because they match high-confidence attack signatures or raise the violation rating to a blocked threshold. Replace `https://app.example.com/` with a protected URL in your environment.
+
+```shell
+# Cross-site scripting (XSS) test
+curl -G "https://app.example.com/" --data-urlencode "a="
+
+# Path traversal test
+curl -G "https://app.example.com/" --data-urlencode "file=../../../../etc/passwd"
+
+# SQL injection test
+curl -G "https://app.example.com/" --data-urlencode "id=1' UNION SELECT 1,2,3--"
+```
+
+If your policy is in transparent mode, if signatures are staged, or if you heavily customized the default policy, these requests may appear as `alerted` instead of `blocked`. The dashboard still confirms that the security event pipeline is working.
For details on how the dashboard is organized and how to read each widget, see the [security dashboard reference]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/dashboard-metrics-reference.md" >}}).
@@ -110,6 +132,8 @@ Re-run the deployment wizard after fixing the configuration.
If events still do not appear after a request is processed, contact F5 support with the instance hostname and the time window you tested.
+For local data plane checks of the embedded OpenTelemetry Collector, generated collector pipeline, and debug forwarding, see [Troubleshoot security monitoring on the local data plane]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/local-dataplane-troubleshooting.md" >}}).
+
---
## References
@@ -122,6 +146,7 @@ If events still do not appear after a request is processed, contact F5 support w
- [secops_dashboard log profile]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/default-log-profile.md" >}})
- [Dashboard metrics reference]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/dashboard-metrics-reference.md" >}})
+- [Troubleshoot security monitoring on the local data plane]({{< ref "/nginx-one-console/waf-integration/waf-security-dashboard/local-dataplane-troubleshooting.md" >}})
**Related how-to guides**
diff --git a/content/nic/install/license-secret.md b/content/nic/install/license-secret.md
index d9066ef6ba..d1f0ccf59c 100644
--- a/content/nic/install/license-secret.md
+++ b/content/nic/install/license-secret.md
@@ -41,6 +41,30 @@ Once created, you can download the `.jwt` file.
{{< include "/nic/installation/jwt-password-note.md" >}}
+### Update the Secret
+
+If you've already deployed NGINX Ingress Controller and need to rotate or renew the JWT (for example, when the existing token is about to expire or has been replaced), update the existing Secret in place.
+
+First, take your new JWT license token, and save it to your existing `license.jwt` file.
+
+Next, use the following command to generate the updated Secret manifest and apply it:
+
+```shell
+kubectl create secret generic license-token \
+--save-config \
+--dry-run=client \
+--from-file=license.jwt= \
+--type=nginx.com/license \
+-o yaml | \
+kubectl apply -f -
+```
+
+Notes:
+- Replace `license.jwt` on the `--from-file` flag with the path to your renewed JWT file if it's not in the current directory.
+- If your Secret resides in a specific namespace, include `-n ` on the `kubectl create secret` command so the generated YAML contains the correct namespace.
+- Ensure the Secret name (`license-token` by default) matches the name referenced by your Helm values or Management ConfigMap.
+- After the Secret is updated, the mounted Secret volume in the Pod is refreshed automatically by Kubernetes. NGINX Plus applies the updated license automatically. If you do not see the update take effect after a short period, restart the Ingress Controller Pod(s) to force a re-read of the Secret.
+
### Add the license Secret to your deployment
If using a name other than the default `license-token`, provide the name of this Secret when installing NGINX Ingress Controller:
diff --git a/static/google1f145127a2762dc1.html b/static/google1f145127a2762dc1.html
new file mode 100644
index 0000000000..ccb5d453ab
--- /dev/null
+++ b/static/google1f145127a2762dc1.html
@@ -0,0 +1 @@
+google-site-verification: google1f145127a2762dc1.html
\ No newline at end of file