NGINX App Protect WAF Compiler
The F5 NGINX App Protect WAF v5 Compiler is a tool that compiles security policies and logging profiles from JSON format to a bundle file that the Enforcer can consume and apply. The bundle file is then referenced in the nginx configuration file. The compiler is packaged as a Docker image and can be run using the Docker CLI or involved during a CI/CD process.
- Get latest security updates - Attack Signatures, Threat Campaigns, Bot Signatures.
- Apply multiple policy bundle files within the same
nginx.conf
. - Configure global settings such as the cookie seed and user-defined signatures.
Important To ensure you are using the latest security updates, it is recommended to regularly rebuild your compiler image with the latest signature packages and recompile security policies.
-
Download Certificates
Log in to My F5 and download the following two files from your active NGINX App Protect WAF subscription:
nginx-repo.key nginx-repo.crt
-
Configure Docker to interact with the F5 Container Registry at
private-registry.nginx.com
:sudo mkdir -p /etc/docker/certs.d/private-registry.nginx.com sudo cp <path-to-your-nginx-repo.crt> /etc/docker/certs.d/private-registry.nginx.com/client.cert sudo cp <path-to-your-nginx-repo.key> /etc/docker/certs.d/private-registry.nginx.com/client.key
Note: Please note that the file extension for the certificate file has changed from.crt
to.cert
-
Create the
Dockerfile
:# syntax=docker/dockerfile:1 ARG BASE_IMAGE=private-registry.nginx.com/nap/waf-compiler:<version-tag> FROM ${BASE_IMAGE} # Installing packages as root USER root ENV DEBIAN_FRONTEND="noninteractive" RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \ --mount=type=secret,id=nginx-key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \ apt-get update \ && apt-get install -y \ apt-transport-https \ lsb-release \ ca-certificates \ wget \ gnupg2 \ ubuntu-keyring \ && wget -qO - https://cs.nginx.com/static/keys/app-protect-security-updates.key | gpg --dearmor | \ tee /usr/share/keyrings/app-protect-security-updates.gpg >/dev/null \ && 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" | \ tee /etc/apt/sources.list.d/nginx-app-protect.list \ && wget -P /etc/apt/apt.conf.d https://cs.nginx.com/static/files/90pkgs-nginx \ && apt-get update \ && apt-get install -y \ app-protect-attack-signatures \ app-protect-bot-signatures \ app-protect-threat-campaigns \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* # non-root default user (UID 101) USER nginx
Note: The user can upgrade or downgrade one of the Signatures by specifying a specific version, for example: app-protect-attack-signatures-2020.04.30.
You can use the Docker registry API to list the available image tags.
Replace <path-to-your-nginx-repo.key>
with the location of your client key and <path-to-your-nginx-repo.crt>
with the location of your client certificate. The optional jq
command is used to format the JSON output for easier reading and requires the jq JSON processor to be installed.
curl -s https://private-registry.nginx.com/v2/nap/waf-compiler/tags/list --key <path-to-your-nginx-repo.key> --cert <path-to-your-nginx-repo.crt> |jq
{
"name": "nap/waf-compiler",
"tags": [
"1.0.0",
"5.1.0",
"5.2.0"
]
}
-
Build the image
Run the command below to build your image, where
waf-compiler-<version-tag>:custom
is an example of the image tag: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 waf-compiler-<version-tag>:custom .
Note: Never upload your NGINX App Protect WAF images to a public container registry such as Docker Hub. Doing so violates your license agreement.
This section assumes that you built a customized compiler image - waf-compiler-<version-tag>:custom
.
Make sure that input files are accessible to UID 101.
To compile a security policy from a JSON file and create a policy bundle, execute the following command:
Warning Ensure that the output directory is writable, otherwise you may encounter a permission denied error.
docker run --rm \
-v $(pwd):$(pwd) \
waf-compiler-<version-tag>:custom \
-p $(pwd)/policy.json -o $(pwd)/compiled_policy.tgz
However, to utilize multiple policy bundles within a single NGINX configuration, it’s necessary to supply a global settings JSON file. This ensures that all bundles have a common foundation, including cookie seed, user-defined signatures, and more.
For instance:
global_settings.json
:
{
"waf-settings": {
"cookie-protection": {
"seed": "<seed value>"
}
}
}
Compilation with global settings:
docker run --rm \
-v $(pwd):$(pwd) \
waf-compiler-1.0.0:custom \
-g $(pwd)/global_settings.json -p $(pwd)/policy.json -o $(pwd)/compiled_policy.tgz
Using -include-source
, you can incorporate the source of the policy (as policy.json
) or logging profile (as logging_profile.json
) into the final bundle. This process transforms any configuration that relies on external references into an inline configuration within the bundled source. Furthermore, when -include-source
is combined with -full-export
, the policy.json within the bundle will contain the entire source policy, including any default settings from the base template.
docker run --rm \
-v $(pwd):$(pwd) \
waf-compiler-1.0.0:custom \
-include-source -full-export -g $(pwd)/global_settings.json -p $(pwd)/policy.json -o $(pwd)/compiled_policy.tgz
To compile a logging profile, execute the command below:
docker run \
-v $(pwd):$(pwd) \
waf-compiler-<version-tag>:custom \
-l $(pwd)/log_01.json -o $(pwd)/log01.tgz
To view information about a bundle file, such as attack signatures versions, use the following command:
docker run \
-v $(pwd):$(pwd) \
waf-compiler-<version-tag>:custom \
-dump -bundle $(pwd)/compiled_policy.tgz
The global settings allows configuration of the following items:
Field Name | Type | Description |
---|---|---|
cookie-protection | object | Defines the cookie protection settings. |
user-defined-signatures | array of objects | Defines user defined signatures. |
Field Name | Type | Description |
---|---|---|
seed | string | The seed value is used by F5 NGINX App Protect WAF to generate the encryption key for the cookies it creates. These cookies are used for various purposes such as validating the integrity of the cookies generated by the application. Use a random alphanumeric string of at least 20 characters length (but not more than 1000 characters). |
Field Name | Reference | Type | Description |
---|---|---|---|
$ref | Yes | string | Path to the file that contains the user defined signatures. |
{
"waf-settings": {
"cookie-protection": {
"seed": "80miIOiSeXfvNBiDJV4t"
},
"user-defined-signatures": [
{
"$ref": "file:///policies/uds.json"
}
]
}
}
When deploying multiple scalability instances, such as Kubernetes deployment replicas, it is essential to ensure that all policy bundles are compiled with the same global settings and security updates.
When executing commands inside the compiler container, especially if it’s part of a CI/CD process and you’re overriding the default entrypoint, ensure that you use /opt/app_protect/bin/apcompile
as the compiler binary.
For example:
/opt/app_protect/bin/apcompile -g /path/to/global_settings.json -p /path/to/policy.json -o /path/to/compiled_policy.tgz