Manage Your App Protect WAF Configs
Overview
Instance Manager helps you manage your F5 NGINX App Protect WAF configurations, making it easy to stay secure. This guide shows you how to set up Instance Manager to configure and manage NGINX App Protect WAF.
Before You Begin
Complete the following prerequisites before proceeding with this guide.
-
You have one or more instances of NGINX App Protect WAF installed and running. See Support for NGINX App Protect WAF for a list of supported versions.
Note:
If you are using configuration management and the NGINX Management Suite Security Monitoring module, follow the instructions in the setup guide to set up your NGINX App Protect instances before proceeding with this guide. -
You have Instance Manager v2.6.0 or later installed, licensed, and running. If you have a subscription to NGINX App Protect WAF, you can find your Instance Manager license in the subscription details section of MyF5.
Limitations
Important:
App Protect WAF Config management is currently not supported when deploying Instance Manager on Kubernetes.
Instance Manager does not support the following NGINX App Protect features:
- Policies with external references
- Policies with modifications
- Custom signatures
Install the WAF Compiler
Instance Manager can use the NGINX App Protect WAF compiler to “pre-compile” security configurations before syncing them to managed data plane instances. You’ll need to install the WAF compiler package on the NGINX Management Suite host to enable this functionality. If you’ll be continuing with WAF compilation on the data plane host, installing the WAF compiler on the NGINX Management Suite host is not necessary.
Be sure to download and install the correct WAF compiler version for your environment:
- Each NGINX App Protect version has a corresponding WAF compiler version. You must install the WAF compiler that matches the version of NGINX App Protect that you have running.
- If you have different NGINX App Protect versions running, install the correct WAF compiler package for each on the management plane host. Instance Manager will use the correct WAF compiler for each version to bundle the security configurations.
- You can create instance groups to keep track of and manage all instances that have the same version installed.
For more information about the WAF compiler, refer to the Security Bundle Compilation section of the Policy Configuration overview topic.
WAF Compiler and Supported App Protect Versions
The following table shows the NGINX App Protect WAF Release version and its corresponding WAF compiler version:
NGINX App Protect WAF Release version | WAF Compiler |
---|---|
NGINX App Protect WAF 5.4.0 | nms-nap-compiler-v5.210.0 |
NGINX App Protect WAF 5.3.0 | nms-nap-compiler-v5.144.0 |
NGINX App Protect WAF 5.2.0 | nms-nap-compiler-v5.48.0 |
NGINX App Protect WAF 5.1.0 | nms-nap-compiler-v5.17.0 |
NGINX App Protect WAF 4.12.0 | nms-nap-compiler-v5.210.0 |
NGINX App Protect WAF 4.11.0 | nms-nap-compiler-v5.144.0 |
NGINX App Protect WAF 4.10.0 | nms-nap-compiler-v5.48.0 |
NGINX App Protect WAF 4.9.0 | nms-nap-compiler-v5.17.0 |
NGINX App Protect WAF 4.8.1 | nms-nap-compiler-v4.815.0 |
NGINX App Protect WAF 4.8.0 | nms-nap-compiler-v4.762.0 |
NGINX App Protect WAF 4.7.0 | nms-nap-compiler-v4.641.0 |
NGINX App Protect WAF 4.6.0 | nms-nap-compiler-v4.583.0 |
NGINX App Protect WAF 4.5.0 | nms-nap-compiler-v4.457.0 |
NGINX App Protect WAF 4.4.0 | nms-nap-compiler-v4.402.0 |
NGINX App Protect WAF 4.3.0 | nms-nap-compiler-v4.279.0 |
NGINX App Protect WAF 4.2.0 | nms-nap-compiler-v4.218.0 |
NGINX App Protect WAF 4.1.0 | nms-nap-compiler-v4.100.1 |
NGINX App Protect WAF 4.0.0 | nms-nap-compiler-v4.2.0 |
NGINX App Protect WAF 3.12.2 | nms-nap-compiler-v3.1088.2 |
Note:
The install commands in this guide use an example version to show the correct command format.
Be sure to replace the version string in the example with the correct version to suit your needs. You can find the package versions in the NGINX App Protect WAF Release Notes.
The WAF compiler installs to the
/opt
directory. Set the permission level for the directory as appropriate to allow write access by the owner (for example,0755
).
Debian or Ubuntu
Install the WAF compiler, then restart the nms-integrations
service:
sudo apt-get install nms-nap-compiler-v5.210.0
Note:
- If you want to have more than one version of the
nms-nap-compiler
installed on your system at once, you’ll need to append-o Dpkg::Options::="--force-overwrite"
to thenms-nap-compiler
installation commands after your initialnms-nap-compiler
installation. For example, the installation command would look like this:sudo apt-get install nms-nap-compiler-v5.210.0 -o Dpkg::Options::="--force-overwrite"
RHEL 8.1 or later
Download the file dependencies.repo to /etc/yum.repos.d
, enable the codeready-builder
repository through subscription manager, and install the WAF compiler package:
sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/dependencies.repo
sudo subscription-manager repos --enable codeready-builder-for-rhel-8-x86_64-rpms
sudo yum install nms-nap-compiler-v5.210.0
RHEL 7.4 or later; CentOS
Download the file dependencies.repo
to /etc/yum.repos.d
, enable the RHEL 7 server repositories, and install the WAF compiler package.
sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/dependencies.repo
sudo yum-config-manager --enable rhui-REGION-rhel-server-optional rhui-REGION-rhel-server-releases rhel-7-server-optional-rpms
sudo yum install nms-nap-compiler-v5.210.0
Amazon Linux 2 LTS
Download the files nms-amazon2.repo
and app-protect-7.repo
to /etc/yum.repos.d
, enable the Extra Packages for Enterprise (EPEL)
repository, and install the WAF compiler package:
sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/nms-amazon2.repo
sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/app-protect-7.repo
sudo amazon-linux-extras enable epel
sudo yum clean metadata
sudo yum install epel-release
sudo yum install nms-nap-compiler-v5.210.0
Oracle Linux 7.4 or later
Download the file dependencies.repo
to /etc/yum.repos.d
, enable the ol8_codeready_builder
repository, and install the WAF compiler package:
sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/dependencies.repo
sudo yum-config-manager --enable ol8_codeready_builder
sudo yum install nms-nap-compiler-v5.210.0
Download from MyF5
If you are not able to access the public NGINX repository, you can download all of the required packages from MyF5.
Take the steps below to download the WAF compiler, Attack Signatures, and Threat Campaigns packages from MyF5.
-
Log in to MyF5.
-
Go to Resources > Downloads.
-
Select Group/Product Family: NGINX.
-
Select Product Line: NGINX App Protect.
-
Select a Product version.
-
Select the Linux distribution, distribution version, and Architecture.
-
Download the WAF compiler package and transfer it to the NGINX Management Suite host.
-
Run the appropriate command on the host to install the WAF compiler package from the file.
- Debian or Ubuntu:
sudo apt-get install -f /path/to/nms-nap-compiler-<version>_focal_amd64.deb
Note:
For Debian or Ubuntu, if you want to have more than one version of the
nms-nap-compiler
installed on your system at once, you’ll need to append-o Dpkg::Options::="--force-overwrite"
to thenms-nap-compiler
installation commands after your initialnms-nap-compiler
installation. For example, the installation command would look like this:sudo apt-get install -f /path/to/nms-nap-compiler-<version>_focal_amd64.deb -o Dpkg::Options::="--force-overwrite"
- RHEL, CentOS, or Oracle Linux:
sudo yum install -f /path/to/nms-nap-compiler-<version>_el8.ngx.x86_64.rpm
Automatically Download and Install New WAF Compiler
Once a version of the NGINX App Protect WAF compiler is manually installed on Instance Manager, the system will automatically download and install a new WAF compiler when it detects that an update is required. This typically happens when the NGINX App Protect WAF version on the data plane has been upgraded or when a new data plane with a different NGINX App Protect WAF version is added.
To enable the automatic download and installation of a new WAF compiler, you need to upload your NGINX App Protect WAF certificate and key to Instance Manager. This upload needs to be done only once. By providing the certificate and key, Instance Manager can securely fetch and install the latest WAF compiler from the NGINX repository.
If the automatic download and install of the new WAF compiler step fails, when publishing the NGINX configuration, the error message
missing the specific compiler, please install it and try again.
will appear. This happens if the NGINX App Protect WAF certificate and key are missing or not working, or if Instance Manager cannot connect to the NGINX Repository. Please check /var/log/nms/nms.log
for errors.
If you see the following error, your NGINX App Protect WAF certificate and key are missing, invalid, or have expired:
error when creating the nginx repo retriever - NGINX repo certificates not found
Also, please refer to Install the WAF Compiler for details on how to manually install the new WAF compiler.
Set Up Attack Signatures and Threat Campaigns
NGINX App Protect provides predefined Attack Signatures to protect your application against all attack types identified by the system. As new Attack Signatures are identified, they will become available for download so that your system will always have the most up-to-date protection.
Threat Campaigns is a threat intelligence feature included in an NGINX App Protect WAF subscription. The feature includes frequent update feeds containing contextual information about active attack campaigns currently being observed by F5 Threat Labs that NGINX App Protect WAF can provide protection against. Just like Attack Signatures, the Threat Campaign patterns are updated regularly. Unlike Attack Signatures, the NGINX App Protect WAF installation does not include any Threat Campaigns and you need to install them in order for the protection to take effect. Due to the highly dynamic nature of those campaigns the updates are issued far more frequently than the Attack Signatures. You need to install those updates close to the time they are issued in order to get the most effective protection.
In order to take advantage of new Attack Signature and Threat Campaign packages, you need to upload these packages to NGINX Management Suite.
You can either configure Instance Manager to download new versions automatically, or manage the files manually by downloading the packages from MyF5 and then uploading them to Instance Manager by using the REST API.
Automatically Download Latest Packages
Upload NGINX App Protect WAF Certificate and Key
You will need to use your NGINX repo certificates to setup automatic retrieval of Attack Signatures and Threat Campaigns packages. When you upload your NGINX App Protect WAF certificate and key to NGINX Instance Manager, you are letting NGINX Instance Manager access the NGINX repo to get Attack Signature and Threat Campaign files on your behalf.
-
Log in to MyF5 and go to My Products and Plans > Subscriptions to download the SSL certificate (nginx-repo.crt) and private key (nginx-repo.key) for your NGINX App Protect subscription.
-
Create a JSON file, similar to the example below, that contains the text from your crt and key files. You will need to replace all of the newlines in the crt and key output with
\n
.{ "name": "nginx-repo", "nginxResourceType": "NginxRepo", "certPEMDetails": { "caCerts": [], "password": "", "privateKey": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDt71QRqMl/7/rv\n[CONTENT SNIPPED]\n-----END PRIVATE KEY-----\n", "publicCert": "-----BEGIN CERTIFICATE-----\nMIIEPzCCAyegAwIBAgIRANydR2VZ+mlt75SkttRyQTkwDQYJKoZIhvcNAQELBQAw\n[CONTENT SNIPPED]\n-----END CERTIFICATE-----", "type": "PEM" } }
-
Send an HTTP POST request to the Instance Manager REST API to upload the repo certificate and key.
Example request
curl -X POST 'https://{{NMS_FQDN}}//api/platform/v1/certs' \ --header "Authorization: Bearer <access token>" \ --header "Content-Type: application/json" \ -d@nginx-repo-certs.json
Example response
{ "certAssignmentDetails": [], "certMetadata": [ { "authorityKeyIdentifier": "<FINGERPRINT>", "commonName": "<SUBSCRIPTION NAME>", "expired": false, "expiry": 59789838, "issuer": "C=US, ST=Washington, L=Seattle, Inc., O=F5 Networks\\, OU=Certificate Authority, CN=F5 PRD Issuing Certificate Authority TEEM V1", "publicKeyType": "RSA (2048 bit)", "serialNumber": "<SERIAL NUMBER>", "signatureAlgorithm": "SHA256-RSA", "subject": "CN=<SUBSCRIPTION NAME>", "subjectAlternativeName": "", "subjectKeyIdentifier": "<FINGERPRINT>", "thumbprint": "<THUMBPRINT>", "thumbprintAlgorithm": "SHA256-RSA", "validFrom": "2021-12-21T16:57:55Z", "validTo": "2024-12-20T00:00:00Z", "version": 3 } ], "certPEMDetails": { "caCerts": [], "password": "**********", "privateKey": "**********", "publicCert": "[CONTENT SNIPPED]", "type": "PEM" }, "created": "2023-01-27T23:42:41.587760092Z", "modified": "2023-01-27T23:42:41.587760092Z", "name": "nginx-repo", "serialNumber": "<SERIAL NUMBER>", "uid": "d08d9f54-58dd-447a-a71d-6fa5aa0d880c", "validFrom": "2021-12-21T16:57:55Z", "validTo": "2024-12-20T00:00:00Z" }
Enable automatic downloads
Instance Manager can automatically download the latest Attack Signature and Threat Campaign versions. To enable automatic downloads, take the steps below.
-
Log in to the management plane host using SSH.
-
Open the
/etc/nms/nms.conf
file for editing. -
Adjust the
app_protect_security_update
options, shown in the example below, to enable and configure automatic downloads:integrations: # enable this for integrations on tcp # address: 127.0.0.1:8037 address: unix:/var/run/nms/integrations.sock # Dqlite config dqlite: addr: 127.0.0.1:7892 app_protect_security_update: # Enable this setting to automatically retrieve the latest Attack Signatures and Threat Campaigns. enable: true # Enable this setting to specify how often, in hours, the latest Attack Signatures and Threat Campaigns are retrieved. # The default interval is 6 hours, the maximum interval is 48 hours, and the minimum is 1 hour. interval: 6 # Enable this setting to specify how many updates to download for the latest Attack Signatures and Threat Campaigns. # By default, the 10 latest updates are downloaded. The maximum value is 20, and the minimum value is 1. number_of_updates: 10
-
Save the changes and close the file.
-
Restart the
nms-integrations
service:sudo systemctl restart nms-integrations
If you do not see the latest Attack Signatures and Threat Campaigns packages downloaded as expected, please check /var/log/nms/nms.log
for errors.
If you see the following error, your NGINX App Protect WAF certificate and key are invalid or have expired:
error when creating the nginx repo retriever - NGINX repo certificates not found
Manually Update Packages
Download packages from MyF5
-
Log in to MyF5, then go to Resources > Downloads.
-
Select Group/Product Family: NGINX.
-
Select Product Line: NGINX App Protect.
-
Select a Product version (a version that matches your WAF compiler version).
-
Select your Linux Distribution, Version and Architecture.
-
Find and download the deb or rpm package starting with “app-protect-attack-signatures” for Attack Signatures and “app-protect-threat-campaigns” for Threat Campaigns.
-
Using utilities such as az or rpm2cpio|cpio to extract the following 3 files from the package:
signatures.bin.tgz
for Attack Signatures orthreat_campaigns.bin.tgz
for Threat Campaignssignature_update.yaml
for Attack Signatures orthreat_campaign_update.yaml
for Threat Campaignsversion
-
Using a file archive utility, such as tar, bundle the three files into a single
.tgz
file. For example:tar –czvf attack-signatures.tgz signatures.bin.tgz signature_update.yaml version
Upload packages to Instance Manager
You will need to use the Instance Manager REST API to upload the bundled Attack Signatures and Threat Campaigns.
Attack Signatures Example
curl -X POST 'https://{{NMS_FQDN}}//api/platform/v1/security/attack-signatures' \
--header "Authorization: Bearer <access token>" \
--form 'revisionTimestamp="2022.11.16"' \
--form 'filename=@"/attack-signatures.tgz"'
Threat Campaigns Example
curl -X POST 'https://{{NMS_FQDN}}//api/platform/v1/security/threat-campaigns' \
--header "Authorization: Bearer <access token>" \
--form 'revisionTimestamp="2022.11.15"' \
--form 'filename=@"/threat-campaigns.tgz"'
Important:
The bundle you upload for Attack Signatures or Threat Campaigns must correspond to the OS of your Instance Manager. For example, if your Instance Manager is running on ubuntu-20.04, then the bundle you upload for Attack Signatures or Threat Campaigns needs to be created from the ubuntu-20.04 packages.
Update the Security Monitoring Signature Database
The Security Monitoring module’s analytics dashboards make use of a Signature Database to provide more information on Attack Signatures that have triggered Security Violations, such as the Signature’s name, accuracy, and risk level.
To ensure that the dashboards show the most up-to-date information, you need to update the Security Monitoring Signature Database
Setup Compiler Resource Pruning
You can configure the following compiler resources to prune automatically:
- Compiled Security Policies
- Compiled Security Log Profiles
- Attack Signatures
- Threat Campaigns
In the case of compiled security policies
and compiled security log profiles
, the definition of the security policy
and/or security log profile
is not removed. Only the compiled bundles associated with those resources are removed.
To enable automatic compiler resource pruning, please follow these steps:
-
Log in to the management plane host using SSH.
-
Open the
/etc/nms/nms.conf
file for editing. -
Update the
policy_manager
field to contain the desiredtime to live
values for each resource type; see the following snippet for an example of adding the necessary fields underintegrations
->policy_manager
:integrations: address: unix:/var/run/nms/integrations.sock dqlite: addr: 127.0.0.1:7892 policy_manager: # Time to live for attack signatures. If the attack signatures exceed their TTL and are not deployed to an instance or # instance group they will be deleted from the database. Duration unit can be seconds (s), minutes (m), or hours (h). attack_signatures_ttl: 336h # Time to live for compiled bundles, this includes compiled security policies and compiled log profiles. If a compiled # bundle exceeds its TTL and is not deployed to an instance or instance group it will be deleted from the database. Note # that the compiled bundle is deleted, not the definition of it (i.e. the security policy or log profile definition). # Duration unit can be seconds (s), minutes (m), or hours (h). compiled_bundles_ttl: 336h # Time to live for threat campaigns. If the threat campaigns exceed their TTL and are not deployed to an instance or # instance group they will be deleted from the database. Duration unit can be seconds (s), minutes (m), or hours (h). threat_campaigns_ttl: 1440h app_protect_security_update: enable: true interval: 6 number_of_updates: 10
-
Save the changes and close the file.
-
Restart the
nms-integrations
service:sudo systemctl restart nms-integrations
The compiler resource pruning process occurs once upon start-up of the nms-integrations
service and once every 24 hours
after the nms-integrations
service has been started.
Onboard NGINX App Protect WAF Instances
To onboard your NGINX App Protect WAF instances to Instance Manager, you need to install and configure NGINX Agent.
Install NGINX Agent
-
Use SSH to connect to the NGINX App Protect WAF instance. Take the steps below for each instance to download and install NGINX Agent from the management plane host.
-
Download the NGINX Agent package from the NGINX Management Suite host and run the agent install script.
Tip:
You can add instances with the same version of NGINX App Protect installed to an instance group by running the agent install command on each instance with the optional `–instance-group`` flag.Note: To complete this step, make sure that
gpg
is installed on your system. You can install NGINX Agent using various command-line tools likecurl
orwget
. If your NGINX Instance Manager host is not set up with valid TLS certificates, you can use the insecure flags provided by those tools. See the following examples:-
Secure:
curl https://<NMS_FQDN>/install/nginx-agent | sudo sh
-
Insecure:
curl --insecure https://<NMS_FQDN>/install/nginx-agent | sudo sh
You can add your NGINX instance to an existing instance group or create one using
--instance-group
or-g
flag when installing NGINX Agent.The following example shows how to download and run the script with the optional
--instance-group
flag adding the NGINX instance to the instance group my-instance-group:curl https://<NMS_FQDN>/install/nginx-agent > install.sh; chmod u+x install.sh sudo ./install.sh --instance-group my-instance-group
By default, the install script attempts to use a secure connection when downloading packages. If, however, the script cannot create a secure connection, it uses an insecure connection instead and logs the following warning message:
Warning: An insecure connection will be used during this nginx-agent installation
To require a secure connection, you can set the optional flag
skip-verify
tofalse
.The following example shows how to download and run the script with an enforced secure connection:
curl https://<NMS_FQDN>/install/nginx-agent > install.sh chmod u+x install.sh; chmod u+x install.sh sudo sh ./install.sh --skip-verify false
-
Secure:
wget https://<NMS_FQDN>/install/nginx-agent -O - | sudo sh -s --skip-verify false
-
Insecure:
wget --no-check-certificate https://<NMS_FQDN>/install/nginx-agent -O - | sudo sh
When you install the NGINX Agent, you can use the
--instance-group
or-g
flag to add your NGINX instance to an existing instance group or to a new group that you specify.The following example downloads and runs the NGINX Agent install script with the optional
--instance-group
flag, adding the NGINX instance to the instance group my-instance-group:wget https://gnms1.npi.f5net.com/install/nginx-agent -O install.sh ; chmod u+x install.sh sudo ./install.sh --instance-group my-instance-group
-
Configure NGINX Agent
-
Edit the NGINX Agent configuration file (
/etc/nginx-agent/nginx-agent.conf
) to allow access to the/etc/app-protect
directory and enable reporting.- The agent needs access to any directories where NGINX App Protect configuration files are stored on the data plane host.
- The
report_interval
is the length of time the agent waits between checks for changes to NGINX App Protect WAF configurations. precompiled_publication
enables the publication of precompiled NGINX App Protect security policies and log profiles.
... config_dirs: "/etc/nginx:/usr/local/etc/nginx:/usr/share/nginx/modules:/etc/nms:/etc/app_protect" extensions: - nginx-app-protect nginx_app_protect: report_interval: 15s precompiled_publication: true ...
Note:
You can use the NGINX Agent installation script to add these fields:
# Download install script via API curl https://<NMS_FQDN>/install/nginx-agent > install.sh # Specify the -m | --nginx-app-protect-mode flag to set up management of NGINX App Protect on # the instance. In the example below we specify 'precompiled-publication' for the flag value # which will make the config field 'precompiled_publication' set to 'true', if you would like to # set the config field 'precompiled_publication' to 'false' you can specify 'none' as the flag value. sudo sh ./install.sh --nginx-app-protect-mode precompiled-publication
-
Restart NGINX Agent.
sudo systemctl restart nginx-agent
Verify Installation
You should now be able to view your NGINX App Protect WAF instances in the Instance Manager user interface. Take the steps below to verify that NGINX Agent is installed and reporting data to Instance Manager.
-
In a web browser, go to the FQDN for your NGINX Instance Manager host and log in. Then, select Instance Manager from the Launchpad menu.
-
Select Instances.
-
You should see the installed version listed in the NGINX App Protect column.
-
Select the instance, then scroll to the App Protect Details section. There, you should see the “App Protect WAF” status and “Build” should match the version installed on the instance.
See Also:
You can use tools likecurl
or Postman to interact with the NGINX Instance Manager REST API. The API URL ishttps://<NIM-FQDN>/api/[nim|platform]/<API_VERSION>
, and each request requires authentication. For more details on authentication options, see the API Overview.
You can query the Instance Manager REST API to verify the following information:
- NGINX App Protect WAF version
- NGINX App Protect WAF running status
- Total number of instances with NGINX App Protect WAF installed, out of the total number of NGINX instances
Method | Endpoint |
---|---|
GET | /api/platform/v1/instances |
GET | /api/platform/v1/systems |
-
Send an HTTP
GET
request to the/api/platform/v1/systems
endpoint to find out what version of NGINX App Protect is running. This response will also show the Threat Campaign and Attack Signature package versions running on each instance.JSON response
{ "count": 3, "items": [ [...] "appProtect": { "attackSignatureVersion": "2022.11.16", "status": "active", "threatCampaignVersion": "2022.11.15", "version": "build-3.954.0" }, [...] ] }
-
Send an HTTP
GET
request to the/api/platform/v1/instances
endpoint to find out the number of instances with NGINX App Protect WAF installed. The total count will be in thenginxAppProtectWAFCount
field in the response.For example:
JSON response
{ "count": 3, "items": [ [...] ], "nginxAppProtectWAFCount": 2, "nginxPlusCount": 3 }
Configure Docker Compose for NGINX App Protect WAF Version 5
Version 5 of NGINX App Protect WAF provides a container-based architecture that requires some configuration changes to operate with Instance Manager.
-
Edit the
docker-compose.yaml
you created according to NGINX App Protect WAF to provide the containers with read access to the policies and log profiles written to the instance by Instance Manager.- Add the line
user: 101:nginx-agent-group
to each service, wherenginx-agent-group
is the ID of the NGINX Agent group. The value of this group ID can be determined with
cat /etc/group
- Add the directory
/etc/nms
to the volume maps for both services
For example:
version: "3.9" services: waf-enforcer: container_name: waf-enforcer image: private-registry.nginx.com/nap/waf-enforcer:5.2.0 user: 101:1002 environment: - ENFORCER_PORT=50000 ports: - "50000:50000" volumes: - /opt/app_protect/bd_config:/opt/app_protect/bd_config - /etc/nms:/etc/nms networks: - waf_network restart: always waf-config-mgr: container_name: waf-config-mgr image: private-registry.nginx.com/nap/waf-config-mgr:5.2.0 user: 101:1002 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 - /etc/nms:/etc/nms restart: always network_mode: none depends_on: waf-enforcer: condition: service_started networks: waf_network: driver: bridge
- Add the line
-
Restart the containers:
docker compose restart
Onboard Security Policies
Instance Manager provides the same default security policies as NGINX App Protect WAF:
- NGINX Default Policy: provides OWASP Top 10 and Bot security protection.
- NGINX Strict Policy: contains more restrictive criteria for blocking traffic than the default policy.
If you want to use the out-of-the-box policies, you can proceed to the next section: Add WAF configuration to NGINX Instances.
Continue in this section if you have custom security policies that you want to upload to Instance Manager.
Upload Custom Security Policies
If you onboarded NGINX App Protect WAF instances with existing security configurations, you’ll need to use the Instance Manager REST API to onboard the security policies referenced in the nginx.conf
on your NGINX App Protect instances.
To do so, take the steps below for each policy:
-
Use
base64
to encode the JSON policy.For example:
base64 -i ./ignore-xss-policy-example.json
ignore-xss-policy-example.json
{ "policy": { "name": "ignore-xss", "template": { "name": "POLICY_TEMPLATE_NGINX_BASE" }, "applicationLanguage": "utf-8", "enforcementMode": "blocking", "signatures": [ { "signatureId": 200001475, "enabled": false }, { "signatureId": 200000098, "enabled": false }, { "signatureId": 200001148, "enabled": false }, { "signatureId": 200001480, "enabled": false }, { "signatureId": 200001088, "enabled": false } ], "bot-defense": { "settings": { "isEnabled": false } }, "headers": [ { "name": "*", "type": "wildcard", "decodeValueAsBase64": "disabled" }, { "name": "*-bin", "type": "wildcard", "decodeValueAsBase64": "required" }, { "name": "Referer", "type": "explicit", "decodeValueAsBase64": "disabled" }, { "name": "Authorization", "type": "explicit", "decodeValueAsBase64": "disabled" }, { "name": "Transfer-Encoding", "type": "explicit", "decodeValueAsBase64": "disabled" } ], "cookies": [ { "name": "*", "type": "wildcard", "decodeValueAsBase64": "disabled" } ], "parameters": [ { "name": "*", "type": "wildcard", "decodeValueAsBase64": "disabled" } ] } }
-
Create a JSON request body that contains the encoded policy.
For example:
{ "metadata": { "name": "ignore-xss-example", "displayName": "Ignore Cross Site Scripting example", "description": "Security policy that intentionally ignores cross site scripting" }, "content": "ewogICAgInBvbGljeSI6IHsKICAgICAgICAibmFtZSI6ICJpZ25vcmUteHNzIiwKICAgICAgICAidGVtcGxhdGUiOiB7CiAgICAgICAgICAgICJuYW1lIjogIlBPTElDWV9URU1QTEFURV9OR0lOWF9CQVNFIgogICAgICAgIH0sCiAgICAgICAgImFwcGxpY2F0aW9uTGFuZ3VhZ2UiOiAidXRmLTgiLAogICAgICAgICJlbmZvcmNlbWVudE1vZGUiOiAiYmxvY2tpbmciLAogICAgICAgICJzaWduYXR1cmVzIjogWwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAic2lnbmF0dXJlSWQiOiAyMDAwMDE0NzUsCiAgICAgICAgICAgICAgICAiZW5hYmxlZCI6IGZhbHNlCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJzaWduYXR1cmVJZCI6IDIwMDAwMDA5OCwKICAgICAgICAgICAgICAgICJlbmFibGVkIjogZmFsc2UKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgInNpZ25hdHVyZUlkIjogMjAwMDAxMTQ4LAogICAgICAgICAgICAgICAgImVuYWJsZWQiOiBmYWxzZQogICAgICAgICAgICB9LAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAic2lnbmF0dXJlSWQiOiAyMDAwMDE0ODAsCiAgICAgICAgICAgICAgICAiZW5hYmxlZCI6IGZhbHNlCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJzaWduYXR1cmVJZCI6IDIwMDAwMTA4OCwKICAgICAgICAgICAgICAgICJlbmFibGVkIjogZmFsc2UKICAgICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgImJvdC1kZWZlbnNlIjogewogICAgICAgICAgICAic2V0dGluZ3MiOiB7CiAgICAgICAgICAgICAgICAiaXNFbmFibGVkIjogZmFsc2UKICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImhlYWRlcnMiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJuYW1lIjogIioiLAogICAgICAgICAgICAgICAgInR5cGUiOiAid2lsZGNhcmQiLAogICAgICAgICAgICAgICAgImRlY29kZVZhbHVlQXNCYXNlNjQiOiAiZGlzYWJsZWQiCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJuYW1lIjogIiotYmluIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogIndpbGRjYXJkIiwKICAgICAgICAgICAgICAgICJkZWNvZGVWYWx1ZUFzQmFzZTY0IjogInJlcXVpcmVkIgogICAgICAgICAgICB9LAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibmFtZSI6ICJSZWZlcmVyIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImV4cGxpY2l0IiwKICAgICAgICAgICAgICAgICJkZWNvZGVWYWx1ZUFzQmFzZTY0IjogImRpc2FibGVkIgogICAgICAgICAgICB9LAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibmFtZSI6ICJBdXRob3JpemF0aW9uIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogImV4cGxpY2l0IiwKICAgICAgICAgICAgICAgICJkZWNvZGVWYWx1ZUFzQmFzZTY0IjogImRpc2FibGVkIgogICAgICAgICAgICB9LAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibmFtZSI6ICJUcmFuc2Zlci1FbmNvZGluZyIsCiAgICAgICAgICAgICAgICAidHlwZSI6ICJleHBsaWNpdCIsCiAgICAgICAgICAgICAgICAiZGVjb2RlVmFsdWVBc0Jhc2U2NCI6ICJkaXNhYmxlZCIKICAgICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgImNvb2tpZXMiOiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJuYW1lIjogIioiLAogICAgICAgICAgICAgICAgInR5cGUiOiAid2lsZGNhcmQiLAogICAgICAgICAgICAgICAgImRlY29kZVZhbHVlQXNCYXNlNjQiOiAiZGlzYWJsZWQiCiAgICAgICAgICAgIH0KICAgICAgICBdLAogICAgICAgICJwYXJhbWV0ZXJzIjogWwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAibmFtZSI6ICIqIiwKICAgICAgICAgICAgICAgICJ0eXBlIjogIndpbGRjYXJkIiwKICAgICAgICAgICAgICAgICJkZWNvZGVWYWx1ZUFzQmFzZTY0IjogImRpc2FibGVkIgogICAgICAgICAgICB9CiAgICAgICAgXQogICAgfQp9CiAgICAgICAgCg==" }
-
Send an HTTP
POST
request to the/api/platform/v1/security/policies
endpoint to create the policy on Instance Manager.For example:
curl -X POST https://{{NMS_FQDN}}/api/platform/v1/security/policies \ -H "Authorization: Bearer <access token>" --ContentType application/json \ -d '{"content": "ewogICAgInBvbGljeSI6[CONTENT_SNIPPED]QogICAgfQp9CiAgICAgICAgCg==", \ "metadata": {"description": "Ignore cross-site scripting is a security policy that intentionally ignores cross site scripting.", \ "displayName": "Ignore cross-site scripting example", "name": "ignore-xss-example"}}'
You should receive a success response similar to the example below:
{ "metadata": { "created": "2022-12-16T03:41:53.516Z", "description": "Security policy that intentionally ignores cross site scripting", "displayName": "Ignore Cross Site Scripting example", "modified": "2022-12-16T03:47:34.465920964Z", "name": "ignore-xss-example", "revisionTimestamp": "2022-12-16T03:41:53.516Z", "uid": "23139e0a-4ac8-49f9-b7a0-0577b42c70c7" }, "selfLink": { "rel": "/api/platform/v1/security/policies/23139e0a-4ac8-49f9-b7a0-0577b42c70c7" } }
-
Verify that your policies have been onboarded by sending an HTTP
GET
request to the/api/platform/v1/security/policies
endpoint:curl -X GET https://{{NMS_FQDN}}/api/platform/v1/security/policies \ -H "Authorization: Bearer <access token>z"
You should receive a success response similar to the example below:
Example response
{ "items": [ { "content": "", "metadata": { "created": "2022-12-14T00:04:07.646Z", "description": "The default policy provides OWASP Top 10 and Bot security protection", "displayName": "NGINX Default Policy", "modified": "2022-12-14T00:04:07.646Z", "name": "NginxDefaultPolicy", "revisionTimestamp": "2022-12-14T00:04:07.646Z", "uid": "ae7d2ffc-972d-4951-a7ba-2340e1b8fe1c" } }, { "content": "", "metadata": { "created": "2022-12-14T00:04:07.65Z", "description": "The strict policy contains more restrictive criteria for blocking traffic than the default policy", "displayName": "NGINX Strict Policy", "modified": "2022-12-14T00:04:07.65Z", "name": "NginxStrictPolicy", "revisionTimestamp": "2022-12-14T00:04:07.65Z", "uid": "94665634-0d7e-4b72-87e8-491d951c8510" } }, { "content": "", "metadata": { "created": "2022-12-16T03:41:53.516Z", "description": "Security policy that intentionally ignores cross site scripting", "displayName": "Ignore Cross Site Scripting example", "modified": "2022-12-16T03:47:34Z", "name": "ignore-xss-example", "revisionTimestamp": "2022-12-16T03:41:53.516Z", "uid": "23139e0a-4ac8-49f9-b7a0-0577b42c70c7" } } ] }
Add WAF Configuration to NGINX Instances
The NGINX App Protect WAF Configuration Guide provides information about how and where to add the directives that allow you to add security to your instances. Instance Manager ships with the same reference policies as NGINX App Protect WAF:
- NGINX Default Policy (
NginxDefaultPolicy.tgz
): Provides OWASP Top 10 and Bot security protection out of the box. - NGINX Strict Policy (
NginxStrictPolicy.tgz
): Contains more restrictive criteria for blocking traffic than the default policy, with a higher risk of false positives.
You can use either of these policies as-is. Many users treat the reference policy as starting point and customize it to suit the needs of their applications. The Security Monitoring dashboards provide insights that can help you fine-tune your security policies.
When using Instance Manager to manage your WAF configuration, keep the following in mind:
-
Instance Manager can compile JSON security policies into a
.tgz
bundle. -
You can reference custom policy files using the
app_protect_policy_file
directive.Important:
If you already have JSON security policies referenced in your NGINX configuration, you can keep them as-is if precompiled publication is not enabled in the NGINX Agent. However, you’ll need to change the file extension for the referenced files from.json
to.tgz
if precompiled publication is enabled. The file name for the compiled bundle will be the same as the original file. Instance Manager does not support both.json
and.tgz
files within a single NGINX configuration -
If you are using custom policies, be sure NGINX Agent has permission to access the location(s) where the policies are stored on the data plane. To do so, edit the NGINX Agent configuration file on the data plane host and add the custom file path to the
config_dirs
setting. -
Instance Manager uses the NGINX App Protect WAF default log profiles. You can specify the desired log profile by using the
app_protect_security_log
directive. Instance Manager does not support the use of custom log profiles.
The examples in this guide use the default path for NGINX App Protect configuration files. If you have these files stored elsewhere on your data plane instance(s), be sure to use the correct file path when setting up your configuration.
Edit the NGINX configuration
By using the Instance Manager web interface or REST API, add the NGINX App Protect WAF configurations to the appropriate context in your NGINX configuration.
The example below shows the directives added to a location
block:
...
server {
...
location / {
##Enable NGINX App Protect
app_protect_enable on;
## Reference to a custom security policy bundle
app_protect_policy_file /etc/nms/ignore-xss.tgz;
## enable logging
app_protect_security_log_enable on;
## Reference to the log profile bundle
app_protect_security_log /etc/nms/log-default.tgz;
...
}
Note:
If you’re using the NGINX Management Suite Security Monitoring module, you should already have the
app_protect_security_log
directive set to reference thesecops_dashboard.tgz
file as shown below. Do not change this setting.app_protect_security_log "/etc/nms/secops_dashboard.tgz" syslog:server=127.0.0.1:514;
Refer to the Security Monitoring setup guide to learn more.
Important:
NGINX configuration for NGINX App Protect Version 5 requires the following changes:
The
app_protect_enforcer_address
directive must be included within thehttp
context of the NGINX configuration:app_protect_enforcer_address 127.0.0.1:50000;
JSON policies and log profiles are not supported for Version 5, so all policies and log profiles must be precompiled and the
precompiled_publication
attribute in the NGINX Agent configuration must be set totrue
.Refer to the NGINX App Protect WAF Configuration Guide to learn more.
Additional example configurations tailored for NGINX features can be found in the NGINX App Protect WAF Configuration Guide.
-
In a web browser, go to the FQDN for your NGINX Instance Manager host and log in. Then, select Instance Manager from the Launchpad menu.
-
On the left menu, select Instances or Instance Groups.
-
Select Edit Config from the Actions menu (represented by an ellipsis,
...
) for the desired instance or instance group. -
If precompiled publication is enabled, change the file extension from
.json
to.tgz
if there are any referenced security policies in the file. -
If you want to apply the default security policy, select Apply Security and then copy the desired policy snippet by selecting Copy.
-
Paste the snippet into an
http
,server
, orlocation
context in the configuration.If multiple policies have been published, the most granular policy will apply.
-
Select Publish to immediately push the updated configuration to the selected instance or instance group.
See Also:
You can use tools likecurl
or Postman to interact with the NGINX Instance Manager REST API. The API URL ishttps://<NIM-FQDN>/api/[nim|platform]/<API_VERSION>
, and each request requires authentication. For more details on authentication options, see the API Overview.
Method | Endpoint |
---|---|
GET | /api/platform/v1/systems/{systemUID}/instances |
POST | /api/platform/v1/security/{systemUID}/instances/{nginxUID}/config |
-
Send an HTTP
GET
request to the/api/platform/v1/systems/{systemUID}/instances
endpoint. This returns a list of all instances from which you can find the unique identifier (UID) of the instance that you want to update. -
Add the desired configurations to your
nginx.conf
file, or to any other configuration file that’s within the context defined in the NGINX Agentconfig_dirs
setting.-
At a minimum, you should add
app_protect_enable on;
. -
If precompiled publication is enabled, change the file extension from
.json
to.tgz
if there are any referenced security policies in the file. -
If you’d like to use the default security policies, paste either of the policy snippets below into an
http
,server
, orlocation
context in the configuration file. The most granular policy will be applied if multiple policies have been published.app_protect_policy_file /etc/nms/NginxDefaultPolicy.tgz; app_protect_policy_file /etc/nms/NginxStrictPolicy.tgz;
-
-
Encode the configuration file using base64:
base64 -i /etc/nginx/nginx.conf
-
Provide the encoded string in
configFiles.files.contents
, as shown below.Important! Before deploying an updated configuration to an instance group, ensure that all instances in the group have the same version of NGINX App Protect WAF installed. Otherwise, the deployment may fail.
curl -X POST https://{{NMS_FQDN}}/api/platform/v1/systems/{systemUID}/instances/{nginxUID}/config -H "Authorization: Bearer <access token>" \ --Content-Type application/json -d @
JSON Response
{ "auxFiles": { "files": [ { "contents": "PCFET0NUWVBFIGh0bWw+CjxodG1sPgo8aGVhZD4KP<EXAMPLE_SNIPPED>", "name": "/var/www/html/index.nginx-debian.html" } ], "rootDir": "/" }, "configFiles": { "files": [ { "contents": "dXNlciB3d3ctZGF0YTsKd29ya2VyX3Byb2Nlc3Nlc<EXAMPLE_SNIPPED>", "name": "nginx.conf" } ], "rootDir": "/etc/nginx" }, "configUID": "", "ignoreConflict": false, "validateConfig": true }
Verify Configuration
Once you have added the NGINX App Protect WAF directives to your NGINX configuration, you should see the NGINX App Protect WAF status reported as “Active”. Take the steps below to verify the configuration in the Instance Manager web interface.
In a web browser, go to the FQDN for your NGINX Instance Manager host and log in. Then, select Instance Manager from the Launchpad menu.
- Select Instances.
- You should see the installed version listed in the NGINX App Protect column.
- Select the instance, then scroll to the App Protect Details section. There, you should see the “App Protect WAF” status is “Active”. The “Build” should match the version installed on the instance.
Troubleshooting
If you’re having issues with NGINX App Protect WAF, we suggest trying the following troubleshooting steps. If none of them helps, please reach out to NGINX Customer Support for further assistance.
Verify that NGINX App Protect WAF is not installed on the NGINX Management Suite host
To ensure no library conflicts arise when installing nms-nap-compiler
, verify that NGINX App Protect WAF is not installed on the NGINX Management Suite host. You can do this by taking the following steps:
-
Open an SSH connection to your NGINX Management Suite host and log in.
-
Run the following command:
- Debian-based distributions, run
dpkg -s app-protect
- RPM-based distributions, run
rpm -qi grep app-protect
- Debian-based distributions, run
If NGINX App Protect WAF is installed, you’ll need to uninstall it.
Verify the WAF compiler version and NGINX App Protect version match
Each NGINX App Protect WAF version has a corresponding version of the WAF compiler. You must install the correct WAF compiler version for the version of NGINX App Protect WAF running on the managed instance(s). Refer to WAF Compiler and Supported App Protect Versions for compatibility details.
To view the installed version of the WAF compiler:
-
Open an SSH connection to your NGINX Management Suite host and log in.
-
Run the following command:
ls -l /opt/nms-nap-compiler
Verify the WAF compiler is running properly
Check if the WAF compiler has been installed and is working properly by viewing the command-line help:
sudo /opt/nms-nap-compiler/app_protect-<version>/bin/apcompile -h
For example, to view the help description for WAF compiler 5.210.0, run the following command:
sudo /opt/nms-nap-compiler/app_protect-5.210.0/bin/apcompile -h
The output looks similar to the following example:
USAGE:
/opt/nms-nap-compiler/app_protect-5.210.0/bin/apcompile <options>
Examples:
/opt/nms-nap-compiler/app_protect-5.210.0/bin/apcompile -p /path/to/policy.json -o mypolicy.tgz
/opt/nms-nap-compiler/app_protect-5.210.0/bin/apcompile -p policyA.json -g myglobal.json -o /path/to/policyA_bundle.tgz
/opt/nms-nap-compiler/app_protect-5.210.0/bin/apcompile -g myglobalsettings.json --global-state-outfile /path/to/myglobalstate.tgz
/opt/nms-nap-compiler/app_protect-5.210.0/bin/apcompile -b /path/to/policy_bundle.tgz --dump
/opt/nms-nap-compiler/app_protect-5.210.0/bin/apcompile -l logprofA.json -o /path/to/logprofA_bundle.tgz
...
Verify NGINX Agent configuration on NGINX App Protect WAF instance
Configure NGINX Agent on your NGINX App Protect WAF instance with settings similar to the following example:
“/etc/nginx-agent/nginx-agent.conf”
# path to aux file dirs can also be added
config_dirs: "/etc/nginx:/usr/local/etc/nginx:/usr/share/nginx/modules:/etc/nms:/etc/app_protect"
# Enable necessary NAP extensions
extensions:
- nginx-app-protect
- nap-monitoring
nginx_app_protect:
# Report interval for NGINX App Protect details - the frequency the NGINX Agent checks NGINX App Protect for changes.
report_interval: 15s
# Enable precompiled publication from the NGINX Management Suite (true) or perform compilation on the data plane host (false).
precompiled_publication: true
nap_monitoring:
# Buffer size for collector. Will contain log lines and parsed log lines
collector_buffer_size: 50000
# Buffer size for processor. Will contain log lines and parsed log lines
processor_buffer_size: 50000
# Syslog server IP address the collector will be listening to
syslog_ip: "127.0.0.1"
# Syslog server port the collector will be listening to
syslog_port: 514
Verify access to the NGINX packages repository
To allow Instance Manager to automatically download the latest Attack Signatures and Threat Campaigns, you need to upload the certificate and key files included with your subscription to allow access to the package repository.
If you already uploaded your certificate and key files, use the command below to verify that they allow access to the package repo:
curl --key /etc/ssl/nginx/nginx-repo.key --cert /etc/ssl/nginx/nginx-repo.crt https://pkgs.nginx.com/app-protect-security-updates/index.xml
The output looks similar to the following example:
...
<repositories>
<repository distro="centos" version="6" arch="x86_64" prefix="centos/6/x86_64/">
</repository>
<repository distro="centos" version="7" arch="x86_64" prefix="centos/7/x86_64/">
<package type="rpm">
<name>app-protect-attack-signatures</name>
<arch>x86_64</arch>
<version epoch="0" ver="2019.07.16" rel="1.el7.ngx"/>
<location href="RPMS/app-protect-attack-signatures-2019.07.16-1.el7.ngx.x86_64.rpm"/>
</package>
<package type="rpm">
<name>app-protect-attack-signatures</name>
<arch>x86_64</arch>
<version epoch="0" ver="2020.04.30" rel="1.el7.ngx"/>
<location href="RPMS/app-protect-attack-signatures-2020.04.30-1.el7.ngx.x86_64.rpm"/>
</package>
...
What’s Next
Now that configuration management is set up, you can use the Instance Manager REST API to manage security policies, view system information about your NGINX App Protect WAF instances, and update Attack Signatures and Threat Campaigns. Learn more in Manage App Protect WAF Configuration using the REST API.