Virtual environment

Information architecture note

The disconnected/air-gapped installation use case has very similar steps.

I’m identifying shared steps for it: depending on how large the steps might be, it might re-appear as a section on a page or have its own page.

This page describes how to install F5 WAF for NGINX with NGINX Plus on a virtual machine or bare metal environment.

Before you begin

To complete this guide, you will need the following prerequisites:

Depending on your deployment type, you may have additional requirements:

  • The IP intelligence topic explains additional set-up configuration to use the feature immediately.
  • Docker is required for NGINX Open Source or NGINX Plus type deployments.

Choose an installation style

The instructions on the rest of this page are split into tabs and sections based on your chosen operating system, NGINX version and deployment style.

Platform-specific instructions

Navigate to your chosen operating system, which are alphabetically ordered.

Alpine Linux

Add the F5 WAF for NGINX repository:

printf "https://pkgs.nginx.com/app-protect-x-oss/alpine/v`egrep -o '^[0-9]+\.[0-9]+' /etc/alpine-release`/main\n" | sudo tee -a /etc/apk/repositories

Update the repositories, then install the F5 WAF for NGINX package and its dependencies:

shell
sudo apk update
sudo apk add app-protect-module-oss

Add the F5 WAF for NGINX repository:

printf "https://pkgs.nginx.com/app-protect-x-plus/alpine/v`egrep -o '^[0-9]+\.[0-9]+' /etc/alpine-release`/main\n" | sudo tee -a /etc/apk/repositories

Update the repositories, then install the F5 WAF for NGINX package and its dependencies:

shell
sudo apk update
sudo apk add openssl ca-certificates app-protect-module-plus

Add the F5 WAF for NGINX repository:

shell
printf "https://pkgs.nginx.com/app-protect/alpine/v`egrep -o '^[0-9]+\.[0-9]+' /etc/alpine-release`/main\n" | sudo 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" | sudo tee -a /etc/apk/repositories

Update the repositories, then install the F5 WAF for NGINX package and its dependencies:

shell
sudo apk update
sudo apk add openssl ca-certificates app-protect

Amazon Linux

Create a file for the F5 WAF for NGINX repository:

/etc/yum.repos.d/app-protect-x-oss.repoo

shell
[app-protect-x-oss]
name=nginx-app-protect repo
baseurl=https://pkgs.nginx.com/app-protect-x-oss/amzn/2023/$basearch/
sslclientcert=/etc/ssl/nginx/nginx-repo.crt
sslclientkey=/etc/ssl/nginx/nginx-repo.key
gpgcheck=0
enabled=1

Install the F5 WAF for NGINX package and its dependencies:

sudo dnf install app-protect-module-oss

Create a file for the F5 WAF for NGINX repository:

/etc/yum.repos.d/app-protect-x-plus.repo

shell
[app-protect-x-plus]
name=nginx-app-protect repo
baseurl=https://pkgs.nginx.com/app-protect-x-plus/amzn/2023/$basearch/
sslclientcert=/etc/ssl/nginx/nginx-repo.crt
sslclientkey=/etc/ssl/nginx/nginx-repo.key
gpgcheck=0
enabled=1

Install the F5 WAF for NGINX package and its dependencies:

sudo dnf install app-protect-module-plus

Add the F5 WAF for NGINX repository:

sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/app-protect-amazonlinux2023.repo

Add F5 WAF for NGINX dependencies:

sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/dependencies.amazonlinux2023.repo

Install the F5 WAF for NGINX package and its dependencies:

sudo dnf install app-protect

Debian

Add the F5 WAF for NGINX repository:

shell
printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
https://pkgs.nginx.com/app-protect-x-oss/debian `lsb_release -cs` nginx-plus\n" | \
sudo tee /etc/apt/sources.list.d/nginx-app-protect.list

Update the repositories, then install the F5 WAF for NGINX package and its dependencies:

shell
sudo apt-get update
sudo apt-get install app-protect-module-oss

Add the F5 WAF for NGINX repository:

shell
printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
https://pkgs.nginx.com/app-protect-x-plus/debian `lsb_release -cs` nginx-plus\n" | \
sudo tee /etc/apt/sources.list.d/nginx-app-protect.list

Update the repositories, then install the F5 WAF for NGINX package and its dependencies:

shell
sudo apt-get update
sudo apt-get install app-protect-module-plus

Add the F5 WAF for NGINX repositories:

shell
printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
https://pkgs.nginx.com/app-protect/debian `lsb_release -cs` nginx-plus\n" | \
sudo 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" | \
sudo tee /etc/apt/sources.list.d/app-protect-security-updates.list

Update the repositories, then install the F5 WAF for NGINX package and its dependencies:

shell
sudo apt-get update
sudo apt-get install app-protect

Oracle Linux / RHEL / Rocky Linux 8

The steps are identical for these platforms due to their similar architecture.

Create a file for the F5 WAF for NGINX repository:

/etc/yum.repos.d/app-protect-x-oss.repo

shell
[app-protect-x-oss]
name=nginx-app-protect repo
baseurl=https://pkgs.nginx.com/app-protect-x-oss/centos/7/$basearch/
sslclientcert=/etc/ssl/nginx/nginx-repo.crt
sslclientkey=/etc/ssl/nginx/nginx-repo.key
gpgcheck=0
enabled=1

Install the F5 WAF for NGINX package and its dependencies:

sudo yum install app-protect-module-oss

Create a file for the F5 WAF for NGINX repository:

/etc/yum.repos.d/app-protect-x-plus.repo

shell
[app-protect-x-plus]
name=nginx-app-protect repo
baseurl=https://pkgs.nginx.com/app-protect-x-plus/centos/8/$basearch/
sslclientcert=/etc/ssl/nginx/nginx-repo.crt
sslclientkey=/etc/ssl/nginx/nginx-repo.key
gpgcheck=0
enabled=1

Install the F5 WAF for NGINX package and its dependencies:

sudo dnf install app-protect-module-plus

Add the F5 WAF for NGINX repository:

sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/app-protect-8.repo

Add F5 WAF for NGINX dependencies:

sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/dependencies.repo

Enable the ol8_codeready_builder repository:

sudo dnf config-manager --set-enabled ol8_codeready_builder

Install the F5 WAF for NGINX package and its dependencies:

sudo dnf install app-protect

Ubuntu

Add the F5 WAF for NGINX repositories:

shell
printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
https://pkgs.nginx.com/app-protect-x-oss/ubuntu `lsb_release -cs` nginx-plus\n" | \
sudo tee /etc/apt/sources.list.d/nginx-app-protect.list

Update the repositories, then install the F5 WAF for NGINX package and its dependencies:

shell
sudo apt-get update
sudo apt-get install app-protect-module-oss

Add the F5 WAF for NGINX repositories:

shell
printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
https://pkgs.nginx.com/app-protect-x-plus/ubuntu `lsb_release -cs` nginx-plus\n" | \
sudo tee /etc/apt/sources.list.d/nginx-app-protect.list

Update the repository, then install the F5 WAF for NGINX package and its dependencies:

shell
sudo apt-get update
sudo apt-get install app-protect-module-plus

Add the F5 WAF for NGINX repositories:

shell
printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
https://pkgs.nginx.com/app-protect/ubuntu `lsb_release -cs` nginx-plus\n" | \
sudo 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/ubuntu `lsb_release -cs` nginx-plus\n" | \
sudo tee /etc/apt/sources.list.d/app-protect-security-updates.list

Update the repositories, then install the F5 WAF for NGINX package and its dependencies:

shell
sudo apt-get update
sudo apt-get install app-protect

RHEL / Rocky Linux 9

Create a file for the F5 WAF for NGINX repository:

/etc/yum.repos.d/app-protect-x-oss.repo

shell
[app-protect-x-oss]
name=nginx-app-protect repo
baseurl=https://pkgs.nginx.com/app-protect-x-oss/centos/7/$basearch/
sslclientcert=/etc/ssl/nginx/nginx-repo.crt
sslclientkey=/etc/ssl/nginx/nginx-repo.key
gpgcheck=0
enabled=1

Install the F5 WAF for NGINX package and its dependencies:

sudo yum install app-protect-module-oss

Create a file for the F5 WAF for NGINX repository:

/etc/yum.repos.d/app-protect-x-plus.repo

shell
[app-protect-x-plus]
name=nginx-app-protect repo
baseurl=https://pkgs.nginx.com/app-protect-x-plus/centos/8/$basearch/
sslclientcert=/etc/ssl/nginx/nginx-repo.crt
sslclientkey=/etc/ssl/nginx/nginx-repo.key
gpgcheck=0
enabled=1

Install the F5 WAF for NGINX package and its dependencies:

sudo dnf install app-protect-module-plus

Add the F5 WAF for NGINX repository:

sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/app-protect-9.repo

Add F5 WAF for NGINX dependencies:

sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/dependencies.repo

Enable the codeready-builder repository:

sudo subscription-manager repos --enable codeready-builder-for-rhel-9-x86_64-rpms

Install the F5 WAF for NGINX package and its dependencies:

sudo dnf install app-protect

Update configuration files

Once you have installed F5 WAF for NGINX, you must load it as a module in the main context of your NGINX configuration.

load_module modules/ngx_http_app_protect_module.so;

The Enforcer address must be added at the http context:

app_protect_enforcer_address 127.0.0.1:50000;

And finally, F5 WAF for NGINX can enabled on a http, server or location context:

app_protect_enable on;
You should only enable F5 WAF for NGINX on proxy_pass and grpc_pass locations.

Here are two examples of how these additions could look in configuration files:

/etc/nginx/nginx.conf

nginx
user  nginx;
worker_processes  auto;

# F5 WAF for NGINX
load_module modules/ngx_http_app_protect_module.so;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    # F5 WAF for NGINX
    app_protect_enforcer_address 127.0.0.1:50000;

    include /etc/nginx/conf.d/*.conf;
}

/etc/nginx/conf.d/default.conf

nginx
server {
    listen 80;
    server_name domain.com;

    proxy_http_version 1.1;

    location / {

        # F5 WAF for NGINX
        app_protect_enable on;

        client_max_body_size 0;
        default_type text/html;
        proxy_pass http://127.0.0.1:8080/;
    }
}

server {
    listen 8080;
    server_name localhost;

    location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
    }

    # redirect server error pages to the static page /50x.html
    #
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }
}

Once you have updated your configuration files, you can reload NGINX to apply the changes. You have two options depending on your environment:

  • nginx -s reload
  • sudo systemctl reload nginx
If you’re using a V4 package, you have finished installing F5 WAF for NGINX and can look at Post-installation checks.

Configure Docker services

This section only applies to NGINX Open Source and NGINX Plus deployments.

Skip to Post-installation checks if you’re using a V4 package.

F5 WAF for NGINX uses Docker containers for its services when installed with a NGINX Open Source or NGINX Plus package, which requires extra set-up steps.

First, create new directories for the services:

sudo mkdir -p /opt/app_protect/config /opt/app_protect/bd_config

Then assign new owners, with 101:101 as the default UID/GID

sudo chown -R 101:101 /opt/app_protect/

Configure Docker for the F5 Container Registry

Create a directory and copy your certificate and key to this directory:

shell
mkdir -p /etc/docker/certs.d/private-registry.nginx.com
cp <path-to-your-nginx-repo.crt> /etc/docker/certs.d/private-registry.nginx.com/client.cert
cp <path-to-your-nginx-repo.key> /etc/docker/certs.d/private-registry.nginx.com/client.key

Download Docker images

Download the waf-enforcer and waf-config-mgr images.

Replace 5.2.0 with the release version you are deploying.

shell
docker pull private-registry.nginx.com/nap/waf-enforcer:5.2.0
docker pull private-registry.nginx.com/nap/waf-config-mgr:5.2.0

Create and run a Docker Compose file

Create a docker-compose.yml file with the following contents in your host environment, replacing image tags as appropriate:

yaml
services:
  waf-enforcer:
    container_name: waf-enforcer
    image: waf-enforcer:5.2.0
    environment:
      - ENFORCER_PORT=50000
    ports:
      - "50000:50000"
    volumes:
      - /opt/app_protect/bd_config:/opt/app_protect/bd_config
    networks:
      - waf_network
    restart: always

  waf-config-mgr:
    container_name: waf-config-mgr
    image: waf-config-mgr:5.2.0
    volumes:
      - /opt/app_protect/bd_config:/opt/app_protect/bd_config
      - /opt/app_protect/config:/opt/app_protect/config
      - /etc/app_protect/conf:/etc/app_protect/conf
    restart: always
    network_mode: none
    depends_on:
      waf-enforcer:
        condition: service_started

networks:
  waf_network:
    driver: bridge

In some operating systems, security mechanisms like SELinux or AppArmor are enabled by default, potentially blocking necessary file access for the nginx process and waf-config-mgr and waf-enforcer containers.

To ensure F5 WAF for NGINX operates smoothly without compromising security, consider setting up a custom SELinux policy or AppArmor profile.

For short-term troubleshooting, you may use permissive (SELinux) or complain (AppArmor) mode to avoid these restrictions, but this is inadvisable for prolonged use.

To start the F5 WAF for NGINX services, use docker compose up in the same folder as the docker-compose.yml file:

sudo docker compose up -d

Post-installation checks

The following steps check that F5 WAF for NGINX enforcement is operational.

They should be ran in the environment with the WAF components.

Check that the three processes for F5 WAF for NGINX are running using ps aux:

  • bd-socket-plugin
  • nginx: master process
  • nginx: worker process
shell
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         8  1.3  2.4 3486948 399092 ?      Sl   09:11   0:02 /usr/share/ts/bin/bd-socket-plugin tmm_count 4 proc_cpuinfo_cpu_mhz 2000000 total_xml_memory 307200000 total_umu_max_size 3129344 sys_max_account_id 1024 no_static_config
root        14  0.0  0.1  71060 26680 ?        S    09:11   0:00 nginx: master process /usr/sbin/nginx -c /tmp/policy/test_nginx.conf -g daemon off;
root        26  0.0  0.3  99236 52092 ?        S    09:12   0:00 nginx: worker process
root        28  0.0  0.0  11788  2920 pts/0    Ss   09:12   0:00 bash
root        43  0.0  0.0  47460  3412 pts/0    R+   09:14   0:00 ps aux

Verify there are no errors in the file /var/log/nginx/error.log and that the policy compiled successfully:

2020/05/10 13:21:04 [notice] 402#402: APP_PROTECT { "event": "configuration_load_start", "configSetFile": "/opt/f5waf/config/config_set.json" }
2020/05/10 13:21:04 [notice] 402#402: APP_PROTECT policy 'app_protect_default_policy' from: /etc/app_protect/conf/NginxDefaultPolicy.json compiled successfully
2020/05/10 13:21:04 [notice] 402#402: APP_PROTECT { "event": "configuration_load_success", "software_version": "1.1.1", "attack_signatures_package":{"revision_datetime":"2019-07-16T12:21:31Z"},"completed_successfully":true}
2020/05/10 13:21:04 [notice] 402#402: using the "epoll" event method
2020/05/10 13:21:04 [notice] 402#402: nginx/1.17.6 (nginx-plus-r20)
2020/05/10 13:21:04 [notice] 402#402: built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
2020/05/10 13:21:04 [notice] 402#402: OS: Linux 3.10.0-957.27.2.el7.x86_64
2020/05/10 13:21:04 [notice] 402#402: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2020/05/10 13:21:04 [notice] 406#406: start worker processes
2020/05/10 13:21:04 [notice] 406#406: start worker process 407

Check that sending an attack signature in a request returns a response block page containing a support ID:

shell
Request:
http://10.240.185.211/?a=<script>

Response:
The requested URL was rejected. Please consult with your administrator.

Your support ID is: 9847191526422998597

[Go Back]

If your policy includes JSON/XML profiles, check /var/log/app_protect/bd-socket-plugin.log for possible errors:

grep '|ERR' /var/log/app_protect/bd-socket-plugin.log

Verify that Enforcement functionality is working by checking the following request is rejected:

curl "localhost/<script>"

Next steps

Once you have successfully installed F5 WAF for NGINX, there are some topics you may want to follow afterwards: