NGINX App Protect WAF Compiler
Overview
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.
Use Cases
- 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.
Building Compiler Image
Important:
Regularly rebuild your compiler image and recompile security policies to ensure you are using the latest security updates.
-
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
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 \ --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.
Usage
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.
Policy Compilation
To compile a security policy from a JSON file and create a policy bundle, execute the following command:
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": "80miIOiSeXfvNBiDJV4t"
}
}
}
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
Logging Profile Compilation
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
Bundle Information
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
Global Settings
The global settings allows configuration of the following items:
waf-settings
Field Name | Type | Description |
---|---|---|
cookie-protection | object | Defines the cookie protection settings. |
user-defined-signatures | array of objects | Defines user defined signatures. |
cookie-protection
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). |
user-defined-signatures
Field Name | Reference | Type | Description |
---|---|---|---|
$ref | Yes | string | Path to the file that contains the user defined signatures. |
Example
{
"waf-settings": {
"cookie-protection": {
"seed": "80miIOiSeXfvNBiDJV4t"
},
"user-defined-signatures": [
{
"$ref": "file:///policies/uds.json"
}
]
}
}
Horizontal Scaling
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.
WAF Compiler in CI/CD
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