diff --git a/content/includes/nap-waf/config/common/forward-proxy-conf.md b/content/includes/nap-waf/config/common/forward-proxy-conf.md
new file mode 100644
index 000000000..eca8f09bc
--- /dev/null
+++ b/content/includes/nap-waf/config/common/forward-proxy-conf.md
@@ -0,0 +1,20 @@
+Enable Forward Proxy Settings for IP Intelligence Client.
+
+To configure proxy settings, edit the client configuration file:
+Path:
+```shell
+/etc/app_protect/tools/iprepd.cfg
+```
+Example configuration:
+```shell
+EnableProxy=True
+ProxyHost=5.1.2.4
+ProxyPort=8080
+ProxyUsername=admin # Optional
+ProxyPassword=admin # Optional
+CACertPath=/etc/ssl/certs/ca-certificates.crt # Optional
+```
+After saving the changes, restart the client to apply the new settings.
+```shell
+/opt/app_protect/bin/iprepd /etc/app_protect/tools/iprepd.cfg > ipi.log 2>&1 &
+```
diff --git a/content/includes/nap-waf/config/common/ip-groups-override-rules.md b/content/includes/nap-waf/config/common/ip-groups-override-rules.md
new file mode 100644
index 000000000..e9c2ff0f5
--- /dev/null
+++ b/content/includes/nap-waf/config/common/ip-groups-override-rules.md
@@ -0,0 +1,62 @@
+#### IP-Address-Lists feature as part of Override Rules feature.
+
+The Override Rules feature allows you to override original or parent policy settings.
+
+Rules are defined using specific conditions, which can include an IP Address Lists based on the declarative policy JSON schema.
+
+When triggered, the rule is applied to the _clientIp_ attribute using the _matches_ function.
+
+'clientIp.matches(ipAddressLists["standalone"])'
+
+Here is a policy example:
+
+```json
+{
+ "policy": {
+ "name": "ip_group_override_rule",
+ "template": {
+ "name": "POLICY_TEMPLATE_NGINX_BASE"
+ },
+ "applicationLanguage": "utf-8",
+ "caseInsensitive": false,
+ "enforcementMode": "blocking",
+ "ip-address-lists": [
+ {
+ "name": "standalone",
+ "ipAddresses": [
+ {
+ "ipAddress": "1.1.1.1/32"
+ }
+ ]
+ }
+ ],
+ "override-rules": [
+ {
+ "name": "myRule1",
+ "condition": "clientIp.matches(ipAddressLists['standalone'])",
+ "actionType": "extend-policy",
+ "override": {
+ "policy": {
+ "enforcementMode": "transparent"
+ }
+ }
+ }
+ ]
+ }
+}
+```
+
+The previous example policy contains an IP address lists with the name "standalone", used for the override rule condition "clientIp.matches(ipAddressLists['standalone'])".
+The condition means that the rule enforcement is applied and override base policy enforcement when clientIp is matched to one of ipAddresses in ipAddressList with name "standalone".
+The value used for the override condition must exist and exactly match the name in "ip-address-lists".
+
+#### Possible errors
+
+| Error text | Input | Explanation |
+| -----------| ------------- | ------------ |
+| _Invalid field invalidList_ | _clientIp.matches(invalidList['standalone']);_ | An incorrect keyword was used instead of _ipAddressLists_ |
+| _Invalid value empty string_ | _clientIp.matches(ipAddressLists['']_ | An empty name was provided |
+| _Failed to compile policy - 'ipGroupOverridePolicy'_ | _uri.matches(ipAddressLists['standalone']);_ | Used _ipAddressLists_ without the _clientIP_ attribute |
+
+
+
diff --git a/content/includes/nap-waf/config/common/ip-groups-overview.md b/content/includes/nap-waf/config/common/ip-groups-overview.md
new file mode 100644
index 000000000..d1729a7d0
--- /dev/null
+++ b/content/includes/nap-waf/config/common/ip-groups-overview.md
@@ -0,0 +1,81 @@
+IP address lists is a feature to organize lists of allowed and forbidden IP addresses across several lists with common attributes.
+
+This allows you to control unique policy settings for incoming requests based on specific IP addresses.
+
+Each IP address list contains a unique name, enforcement type (_always_, _never_ and _policy-default_), and list of IP addresses.
+
+
+An example of a declarative policy using IP address lists configuration:
+
+```json
+{
+ "policy": {
+ "name": "IpGroups_policy",
+ "template": {
+ "name": "POLICY_TEMPLATE_NGINX_BASE"
+ },
+ "applicationLanguage": "utf-8",
+ "caseInsensitive": false,
+ "enforcementMode": "blocking",
+ "ip-address-lists": [
+ {
+ "name": "Standalone",
+ "description": "Optional Description",
+ "blockRequests": "policy-default",
+ "setGeolocation": "IN",
+ "ipAddresses": [
+ {
+ "ipAddress": "1.2.3.4/32"
+ },
+ {
+ "ipAddress": "1111:fc00:0:112::2"
+ }
+ ]
+ }
+ ]
+ }
+}
+
+```
+The example with IP-Group definition in external file external_ip_groups.json:
+
+```json
+{
+ "policy": {
+ "name": "IpGroups_policy2",
+ "template": {
+ "name": "POLICY_TEMPLATE_NGINX_BASE"
+ },
+ "applicationLanguage": "utf-8",
+ "caseInsensitive": false,
+ "enforcementMode": "blocking",
+ "ip-address-lists": [
+ {
+ "name": "external_ip_groups",
+ "description": "Optional Description",
+ "blockRequests": "always",
+ "setGeolocation": "IL",
+ "$ref": "file:///tmp/policy/external_ip_groups.json"
+ }
+ ]
+ }
+}
+```
+Example of the file external_ip_groups.json
+
+```json
+{
+ "name": "External IP address lists",
+ "description": "Optional Description",
+ "blockRequests": "always",
+ "setGeolocation": "IR",
+ "ipAddresses": [
+ {
+ "ipAddress": "66.51.41.21"
+ },
+ {
+ "ipAddress": "66.52.42.22"
+ }
+ ]
+}
+```
diff --git a/content/includes/nap-waf/config/common/ip-intelligence-conf.md b/content/includes/nap-waf/config/common/ip-intelligence-conf.md
new file mode 100644
index 000000000..094b42cb6
--- /dev/null
+++ b/content/includes/nap-waf/config/common/ip-intelligence-conf.md
@@ -0,0 +1,121 @@
+
+
+NGINX App Protect WAF provides an IP Intelligence feature, which allows customizing the enforcement based on the source IP of the request to limit access from IP addresses with questionable reputation. Please note that:
+- The IP intelligence feature is **disabled** by default and needs to be installed, enabled, and configured within the policy.
+- To review the installation steps, please refer to the administration guide: [App Protect v4]({{< ref "/nap-waf/v4/admin-guide/install.md#Prerequisites" >}}) / [App Protect v5]({{< ref "/nap-waf/v5/admin-guide/install.md#Prerequisites" >}})
+- The system must have an active Internet connection and a working DNS.
+- If NGINX App Protect is behind a firewall, ensure external access to vector.brightcloud.com over port 443 - this is the IP Intelligence server used for data retrieval.
+- If NGINX App Protect accesses the Internet through a forward proxy server, ensure that it is configured correctly [App Protect v4]({{< ref "/nap-waf/v4/configuration-guide/configuration.md#ip-intelligence-forward-proxy-configuration" >}}) / [App Protect v5]({{< ref "/nap-waf/v5/configuration-guide/configuration.md##ip-intelligence-forward-proxy-configuration" >}}).
+
+Once installed, make sure to enable the feature in the two relevant sections of the policy:
+1. By enabling the corresponding violation in the violation list: `"name": "VIOL_MALICIOUS_IP"` and assigning the appropriate `block` and `alarm` values to the violation.
+
+2. By enabling the feature in the corresponding IP Intelligence JSON section: `"ip-intelligence": {"enabled": true}` and defining actions for the IP Intelligence categories listed below.
+
+An example policy where both elements are enabled, and all the IP intelligence categories are configured to `block` and `alarm` can be found here:
+
+```json
+{
+ "policy": {
+ "name": "ip_intelligency_policy",
+ "template": {
+ "name": "POLICY_TEMPLATE_NGINX_BASE"
+ },
+ "applicationLanguage": "utf-8",
+ "caseInsensitive": false,
+ "enforcementMode": "blocking",
+ "blocking-settings": {
+ "violations": [
+ {
+ "name": "VIOL_MALICIOUS_IP",
+ "alarm": true,
+ "block": true
+ }
+ ]
+ },
+ "ip-intelligence": {
+ "enabled": true,
+ "ipIntelligenceCategories": [
+ {
+ "category": "Anonymous Proxy",
+ "alarm": true,
+ "block": true
+ },
+ {
+ "category": "BotNets",
+ "alarm": true,
+ "block": true
+ },
+ {
+ "category": "Cloud-based Services",
+ "alarm": true,
+ "block": true
+ },
+ {
+ "category": "Denial of Service",
+ "alarm": true,
+ "block": true
+ },
+ {
+ "category": "Infected Sources",
+ "alarm": true,
+ "block": true
+ },
+ {
+ "category": "Mobile Threats",
+ "alarm": true,
+ "block": true
+ },
+ {
+ "category": "Phishing Proxies",
+ "alarm": true,
+ "block": true
+ },
+ {
+ "category": "Scanners",
+ "alarm": true,
+ "block": true
+ },
+ {
+ "category": "Spam Sources",
+ "alarm": true,
+ "block": true
+ },
+ {
+ "category": "Tor Proxies",
+ "alarm": true,
+ "block": true
+ },
+ {
+ "category": "Web Attacks",
+ "alarm": true,
+ "block": true
+ },
+ {
+ "category": "Windows Exploits",
+ "alarm": true,
+ "block": true
+ }
+ ]
+ }
+ }
+}
+```
+
+This policy will basically block `"block": true` all IP addresses that are part of any threat category and add a log entry `"alarm": true` for the transaction.
+
+The IP address database is managed by an external provider and is constantly updated (every 1 minute by default). The database also categorizes IP addresses into one or more threat categories. These are the same categories that can be configured individually in the IP intelligence section:
+- Anonymous Proxy
+- BotNets
+- Cloud-based Services
+- Denial of Service
+- Infected Sources
+- Mobile Threats
+- Phishing Proxies
+- Scanners
+- Spam Sources
+- Tor Proxies
+- Web Attacks
+- Windows Exploits
+
+Note that since the IP address database is constantly updated, IP address enforcement is also expected to change. IP Addresses may be added, removed, or moved from one category to another based on the reported activity of the IP address.
diff --git a/content/includes/nap-waf/config/v5/build-nginx-image-oss/build-rocky.md b/content/includes/nap-waf/config/v5/build-nginx-image-oss/build-rocky.md
new file mode 100644
index 000000000..00f2fcd65
--- /dev/null
+++ b/content/includes/nap-waf/config/v5/build-nginx-image-oss/build-rocky.md
@@ -0,0 +1,41 @@
+```dockerfile
+# syntax=docker/dockerfile:1
+
+# Base Image
+FROM rockylinux:9
+
+# Install NGINX OSS and NGINX App Protect WAF v5 module
+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 \
+ dnf -y install wget ca-certificates yum-utils \
+ && wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/dependencies.repo \
+ && echo "[nginx-mainline]" > /etc/yum.repos.d/nginx.repo \
+ && echo "name=nginx mainline repo" >> /etc/yum.repos.d/nginx.repo \
+ && echo "baseurl=http://nginx.org/packages/mainline/centos/\$releasever/\$basearch/" >> /etc/yum.repos.d/nginx.repo \
+ && echo "gpgcheck=1" >> /etc/yum.repos.d/nginx.repo \
+ && echo "enabled=1" >> /etc/yum.repos.d/nginx.repo \
+ && echo "gpgkey=https://nginx.org/keys/nginx_signing.key" >> /etc/yum.repos.d/nginx.repo \
+ && echo "module_hotfixes=true" >> /etc/yum.repos.d/nginx.repo \
+ && echo "[app-protect-x-oss]" > /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-oss.repo \
+ && echo "name=nginx-app-protect repo" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-oss.repo \
+ && echo "baseurl=https://pkgs.nginx.com/app-protect-x-oss/centos/${UBI_VERSION}/\$basearch/" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-oss.repo \
+ && echo "sslclientcert=/etc/ssl/nginx/nginx-repo.crt" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-oss.repo \
+ && echo "sslclientkey=/etc/ssl/nginx/nginx-repo.key" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-oss.repo \
+ && echo "gpgcheck=0" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-oss.repo \
+ && echo "enabled=1" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-oss.repo \
+ && dnf clean all \
+ && dnf install -y app-protect-module-oss \
+ && dnf clean all \
+ && rm -rf /var/cache/dnf \
+ && ln -sf /dev/stdout /var/log/nginx/access.log \
+ && ln -sf /dev/stderr /var/log/nginx/error.log
+
+# Expose port
+EXPOSE 80
+
+# Define stop signal
+STOPSIGNAL SIGQUIT
+
+# Set default command
+CMD ["nginx", "-g", "daemon off;"]
+```
diff --git a/content/includes/nap-waf/config/v5/build-nginx-image-plus/build-rocky.md b/content/includes/nap-waf/config/v5/build-nginx-image-plus/build-rocky.md
new file mode 100644
index 000000000..e0362cd74
--- /dev/null
+++ b/content/includes/nap-waf/config/v5/build-nginx-image-plus/build-rocky.md
@@ -0,0 +1,35 @@
+```dockerfile
+# syntax=docker/dockerfile:1
+
+# Base Image
+FROM rockylinux:9
+
+# Install NGINX Plus and NGINX App Protect WAF v5 module
+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 \
+ dnf -y install wget ca-certificates \
+ && wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/dependencies.repo \
+ && wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/${NGINX_PLUS_REPO} \
+ && echo "[app-protect-x-plus]" > /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-plus.repo \
+ && echo "name=nginx-app-protect repo" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-plus.repo \
+ && echo "baseurl=https://pkgs.nginx.com/app-protect-x-plus/centos/${UBI_VERSION}/\$basearch/" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-plus.repo \
+ && echo "sslclientcert=/etc/ssl/nginx/nginx-repo.crt" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-plus.repo \
+ && echo "sslclientkey=/etc/ssl/nginx/nginx-repo.key" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-plus.repo \
+ && echo "gpgcheck=0" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-plus.repo \
+ && echo "enabled=1" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-plus.repo \
+ && dnf clean all \
+ && dnf install -y app-protect-module-plus \
+ && dnf clean all \
+ && rm -rf /var/cache/dnf \
+ && ln -sf /dev/stdout /var/log/nginx/access.log \
+ && ln -sf /dev/stderr /var/log/nginx/error.log
+
+# Expose port
+EXPOSE 80
+
+# Define stop signal
+STOPSIGNAL SIGQUIT
+
+# Set default command
+CMD ["nginx", "-g", "daemon off;"]
+```
diff --git a/content/includes/nap-waf/ip-intelligence.md b/content/includes/nap-waf/ip-intelligence.md
new file mode 100644
index 000000000..31f173479
--- /dev/null
+++ b/content/includes/nap-waf/ip-intelligence.md
@@ -0,0 +1,67 @@
+If the deployment intends to use the IP intelligence Feature (available from version 5.7.0), then the IP intelligence container needs to be added to the deployment in the docker compose file.
+
+Modify the original `docker-compose.yml` file to include the additional IP Intelligence container:
+
+```yaml
+services:
+ waf-enforcer:
+ container_name: waf-enforcer
+ image: private-registry.nginx.com/nap/waf-enforcer:5.7.0
+ environment:
+ - ENFORCER_PORT=50000
+ ports:
+ - "50000:50000"
+ volumes:
+ - /opt/app_protect/bd_config:/opt/app_protect/bd_config
+ - /var/IpRep:/var/IpRep
+ networks:
+ - waf_network
+ restart: always
+ user: "101:101"
+ depends_on:
+ - waf-ip-intelligence
+
+ waf-config-mgr:
+ container_name: waf-config-mgr
+ image: private-registry.nginx.com/nap/waf-config-mgr:5.7.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
+ user: "101:101"
+ network_mode: none
+ depends_on:
+ waf-enforcer:
+ condition: service_started
+
+ waf-ip-intelligence:
+ container_name: waf-ip-intelligence
+ image: private-registry.nginx.com/nap/waf-ip-intelligence:5.7.0
+ volumes:
+ - /var/IpRep:/var/IpRep
+ networks:
+ - waf_network
+ restart: always
+ user: "101:101"
+
+networks:
+ waf_network:
+ driver: bridge
+```
+
+Notes:
+- Replace `waf-config-mgr`, `waf-enforcer` and `waf-ip-intelligence` tags with the actual release version tag you are deploying. We are using version 5.7.0 for this example deployment.
+- By default, the containers `waf-config-mgr`, `waf-enforcer` and `waf-ip-intelligence` operate with the user and group IDs set to 101:101. Ensure that the folders and files are accessible to these IDs.
+
+Before creating the deployment in docker compose, create the required directories:
+
+```shell
+sudo mkdir -p /opt/app_protect/config /opt/app_protect/bd_config /var/IpRep
+```
+
+Then set correct ownership:
+
+```shell
+sudo chown -R 101:101 /opt/app_protect/ /var/IpRep
+```
diff --git a/content/includes/nap-waf/policy.html b/content/includes/nap-waf/policy.html
index de530f555..0d84e0c67 100644
--- a/content/includes/nap-waf/policy.html
+++ b/content/includes/nap-waf/policy.html
@@ -270,153 +270,160 @@
xml-profiles |
Yes |
array of objects |
@@ -2849,13 +2856,13 @@ ip-address-lists
- Specifies how the system responds to blocking requests sent from this IP address list.
-- Policy Default: Specifies that the Policy Blocking Settings will be used for requests from this IP address list.
+- Policy Default: Specifies that the policy enforcementMode will be used for requests from this IP address list.
- Never Block: Specifies that the system does not block requests sent from this IP address list, even if your security policy is configured to block all traffic.
- Always Block: Specifies that the system blocks requests sent from this IP address list.
-Optional |
+Optional, if absent Policy Default is used.
- always
- never
@@ -2871,13 +2878,13 @@ ip-address-lists
ipAddresses |
array of objects |
-Specifies the IP addresses. |
+Specifies the IP addresses. Use CIDR notation for subnet definition. |
|
matchOrder |
integer |
-Specifies the order index for IP Address List matching. If unspecified, the order is implicitly as the lists appear in the policy. IP Address Groups with a lower matchOrder will be checked for a match prior to items with higher matchOrder. |
+Specifies the order matching index between different IP Address Lists. If unspecified, the order is implicitly as the lists appear in the policy. IP Address Lists with a lower matchOrder will be checked for a match prior to items with higher matchOrder. |
|
@@ -2889,13 +2896,13 @@ ip-address-lists
neverLogRequests |
boolean |
-Specifies when enabled that the system does not log requests or responses sent from this IP address list, even if the traffic is illegal, and even if your security policy is configured to log all traffic. |
+Specifies when enabled that the system does not log requests or responses sent from this IP address list, even if the traffic is illegal, and even if your security policy is configured to log all traffic. Optional, if absent default value is false. |
|
setGeolocation |
string |
-Specifies a geolocation to be associated for this IP address list. Optional |
+Specifies a geolocation to be associated for this IP address list. This will force the IP addresses in the list to be considered as though they are in that geolocation. This applies to blocking via "disallowed-geolocations" and to logging. Optional |
|
@@ -2920,11 +2927,92 @@ ipAddresses
ipAddress |
string |
+Specifies the IP address. Use CIDR notation for subnet definition. |
+ |
+
+
+
+ip-intelligence
+
+ipIntelligenceCategories
+
+
+
+
+
+
+
+
+
+
+
+
+alarm |
+boolean |
+ |
+ |
+
+
+block |
+boolean |
+ |
+ |
+
+
+category |
+string |
+ |
+
+- Anonymous Proxy
+- BotNets
+- Cloud-based Services
+- Denial of Service
+- Infected Sources
+- Mobile Threats
+- Phishing Proxies
+- Scanners
+- Spam Sources
+- Tor Proxies
+- Web Attacks
+- Windows Exploits
+ |
+
+
+
json-profiles
@@ -3359,6 +3447,7 @@ login-pages
- http-digest: The web server performs the authentication; user names and passwords are not transmitted over the network, nor are they stored in plain text.
- ntlm: Microsoft LAN Manager authentication (also called Integrated Windows Authentication) does not transmit credentials in plain text, but requires a continuous TCP connection between the server and client.
- ajax-or-json-request: The web server uses JSON and AJAX requests to authenticate users trying to access the web application through the login URL. For this option, you also need to type the name of the JSON element containing the user name and password.
+- request-body: The web server uses the request body to authenticate users trying to access the web application through the login URL. This allows brute force login detection using, for example, SAML authentication used on Microsoft Federation Services for SSO which uses SOAP API to login.
@@ -3380,7 +3469,7 @@ login-pages
passwordRegex |
string |
- |
+PCRE regular expression for capturing the password. The regular expression must include exactly one capturing group (in rounded parentheses) for the value of the password. For example: "pwd=(w+)". The entered expression is validated and any invalid code is noted and must be corrected. Note: This setting is only relevant if authenticationType is request-body. |
|
@@ -3398,7 +3487,7 @@ login-pages
usernameRegex |
string |
- |
+PCRE regular expression for capturing the username. The regular expression must include exactly one capturing group (in rounded parentheses) for the value of the username. For example: "user_id=(w+)". The entered expression is validated and any invalid code is noted and must be corrected. Note: This setting is only relevant if authenticationType is request-body. |
|
@@ -3605,7 +3694,7 @@ override-rules
Request Attributes:
-- clientIp: Client IP address in canonical IPv4 or IPv6 format. Use CIDR notation for subnet definition. Example: 192.168.1.2 or fd00:1::/48. If trustXff (X-Forwarded-For) is enabled in the containing policy, then the value is taken from the configured header (XFF or other). The only supported boolean function for the clientIP attribute is matches.
+- clientIp: Client IP address in canonical IPv4 or IPv6 format or ip-address-list. Use CIDR notation for subnet definition. Example: 192.168.1.2 or fd00:1::/48. If trustXff (X-Forwarded-For) is enabled in the containing policy, then the value is taken from the configured header (XFF or other). The only supported boolean function for the clientIP attribute is matches.
- host: The value of the Host header
- method: The HTTP method in the request
- uri: The URI (path part) of the request
@@ -3616,7 +3705,7 @@ override-rules
- headers['<name>']: (map-type) The value of the specified header name. Example: "headers['Accept'].startsWith('application')"
-Note: The "headers['<name>']" attribute does not support 'Cookie' as a header name. |
+Note: The "headers['<name>']" attribute does not support 'Cookie' as a header name. Attribute "clientIp" supports using "ipAddressLists" in condition: "clientIp.matches(ipAddressLists[''])
|
@@ -6414,6 +6503,7 @@ violations
- VIOL_XML_MALFORMED
- VIOL_GEOLOCATION
- VIOL_WEBSOCKET_BAD_REQUEST
+- VIOL_MALICIOUS_IP
diff --git a/content/nap-waf/v4/admin-guide/install.md b/content/nap-waf/v4/admin-guide/install.md
index c3e0575dc..d0781d810 100644
--- a/content/nap-waf/v4/admin-guide/install.md
+++ b/content/nap-waf/v4/admin-guide/install.md
@@ -32,8 +32,8 @@ NGINX App Protect WAF supports the following operating systems:
- [Debian 11 (Bullseye) & 12 (Bookworm)](#debian-10--debian-11--debian-12-installation)
- [Oracle Linux 8.1.x and above](#oracle-linux-81-installation)
- [RHEL 8.1.x and above](#rhel-81-installation)
-- [RHEL 9 and above](#rhel-9-installation)
-- [Ubuntu 20.04 (Focal), 22.04 (Jammy) & 24.04 (Noble)](#ubuntu-installation)
+- [RHEL 9, Rocky Linux 9 and above](#rhel-9-installation)
+- [Ubuntu 22.04 (Jammy) & 24.04 (Noble)](#ubuntu-installation)
The NGINX App Protect WAF package has the following dependencies:
@@ -51,6 +51,8 @@ The NGINX App Protect WAF package has the following dependencies:
See the NGINX Plus full list of prerequisites for more details. NGINX App Protect WAF can be installed as a module to an existing NGINX Plus installation or as a complete NGINX Plus with App Protect installation in a clean environment.
+Please note that an additional package **app-protect-ip-intelligence** is required if the customer intends to use the IP Intelligence feature. This package does not come as a dependency of App Protect and needs to be installed and maintained separately. This package installs the client that downloads and updates the database required for enforcing IP Intelligence.
+
## Storage I/O Performance
When deploying App Protect on NGINX Plus take into consideration the performance of storage on which it is going to be installed.
@@ -214,6 +216,30 @@ If a user other than **nginx** is to be used, note the following:
sudo service nginx start
```
+14. (Optional) A new feature, `IP Intelligence` is available (version 4.15.0 and above). The feature requires the installation of an additional package to function properly:
+
+ ```shell
+ sudo apk add app-protect-ip-intelligence
+ ```
+
+ After installing the package, run the client:
+
+ ```shell
+ /opt/app_protect/bin/iprepd /etc/app_protect/tools/iprepd.cfg > ipi.log 2>&1 &
+ ```
+
+ Verify the client is populating the database:
+
+ ```shell
+ tail -f iprepd.log
+ ```
+
+ Update your policy to include the new configuration, then run [apreload]({{< ref "/nap-waf/v4/configuration-guide/configuration.md#apreload" >}}) command to make changes take effect
+
+ {{< note >}} For this capability to function properly, please follow the guidelines listed in the [configuration guide]({{< ref "/nap-waf/v4/configuration-guide/configuration.md#ip-intelligence-configuration" >}}){{< /note >}}
+
+
+
---
## Amazon Linux Installation
@@ -328,6 +354,28 @@ If a user other than **nginx** is to be used, note the following:
sudo systemctl start nginx
```
+1. (Optional) A new feature feature `IP Intelligence` is available (version 4.15.0 and above). The feature requires the installation of an additional package to function properly:
+
+ ```shell
+ sudo dnf install -y app-protect-ip-intelligence
+ ```
+
+ After installing the package, run the client:
+
+ ```shell
+ /opt/app_protect/bin/iprepd /etc/app_protect/tools/iprepd.cfg > ipi.log 2>&1 &
+ ```
+
+ Verify the client is populating the database:
+
+ ```shell
+ tail -f iprepd.log
+ ```
+
+ Update your policy to include the new configuration, then run [apreload]({{< ref "/nap-waf/v4/configuration-guide/configuration.md#apreload" >}}) command to make changes take effect
+
+ {{< note >}} For this capability to function properly, please follow the guidelines listed in the [configuration guide]({{< ref "/nap-waf/v4/configuration-guide/configuration.md#ip-intelligence-configuration" >}}){{< /note >}}
+
## Debian Installation
1. If you already have NGINX packages in your system, back up your configs and logs:
@@ -467,6 +515,28 @@ If a user other than **nginx** is to be used, note the following:
sudo systemctl start nginx
```
+16. (Optional) A new feature feature `IP Intelligence` is available (version 4.15.0 and above). The feature requires the installation of an additional package to function properly:
+
+ ```shell
+ sudo apt-get -y install app-protect-ip-intelligence
+ ```
+
+ After installing the package, run the client:
+
+ ```shell
+ /opt/app_protect/bin/iprepd /etc/app_protect/tools/iprepd.cfg > ipi.log 2>&1 &
+ ```
+
+ Verify the client is populating the database:
+
+ ```shell
+ tail -f iprepd.log
+ ```
+
+ Update your policy to include the new configuration, then run [apreload]({{< ref "/nap-waf/v4/configuration-guide/configuration.md#apreload" >}}) command to make changes take effect
+
+ {{< note >}} For this capability to function properly, please follow the guidelines listed in the [configuration guide]({{< ref "/nap-waf/v4/configuration-guide/configuration.md#ip-intelligence-configuration" >}}){{< /note >}}
+
{{< warning >}} Debian enables **AppArmor** by default, but NGINX App Protect WAF will run in unconfined mode after being installed as it is shipped with no AppArmor profile. To benefit from AppArmor access control capabilities for NGINX App Protect WAF, you will have to write your own AppArmor profile for NGINX App Protect WAF executables found in `/opt/app_protect/bin` such that it best suits your environment.
{{< /warning >}}
@@ -588,7 +658,29 @@ If a user other than **nginx** is to be used, note the following:
sudo systemctl start nginx
```
----
+17. (Optional) A new feature feature `IP Intelligence` is available (version 4.15.0 and above). The feature requires the installation of an additional package to function properly:
+
+ ```shell
+ sudo dnf install -y app-protect-ip-intelligence
+ ```
+
+ After installing the package, run the client:
+
+ ```shell
+ /opt/app_protect/bin/iprepd /etc/app_protect/tools/iprepd.cfg > ipi.log 2>&1 &
+ ```
+
+ Verify the client is populating the database:
+
+ ```shell
+ tail -f iprepd.log
+ ```
+
+ Update your policy to include the new configuration, then run [apreload]({{< ref "/nap-waf/v4/configuration-guide/configuration.md#apreload" >}}) command to make changes take effect
+
+ {{< note >}} For this capability to function properly, please follow the guidelines listed in the [configuration guide]({{< ref "/nap-waf/v4/configuration-guide/configuration.md#ip-intelligence-configuration" >}}){{< /note >}}
+
+ ---
## RHEL 9+ Installation
@@ -708,7 +800,29 @@ If a user other than **nginx** is to be used, note the following:
sudo systemctl start nginx
```
----
+1. (Optional) A new feature `IP Intelligence` is available (version 4.15.0 and above). The feature requires the installation of an additional package to function properly:
+
+ ```shell
+ sudo dnf install -y app-protect-ip-intelligence
+ ```
+
+ After installing the package, run the client:
+
+ ```shell
+ /opt/app_protect/bin/iprepd /etc/app_protect/tools/iprepd.cfg > ipi.log 2>&1 &
+ ```
+
+ Verify the client is populating the database:
+
+ ```shell
+ tail -f iprepd.log
+ ```
+
+ Update your policy to include the new configuration, then run [apreload]({{< ref "/nap-waf/v4/configuration-guide/configuration.md#apreload" >}}) command to make changes take effect
+
+ {{< note >}} For this capability to function properly, please follow the guidelines listed in the [configuration guide]({{< ref "/nap-waf/v4/configuration-guide/configuration.md#ip-intelligence-configuration" >}}){{< /note >}}
+
+ ---
## Ubuntu Installation
@@ -843,6 +957,28 @@ If a user other than **nginx** is to be used, note the following:
sudo systemctl start nginx
```
+16. (Optional), a new feature `IP Intelligence` is supported (Check the release notes for the App Protect versions that support IP Intelligence). The feature requires the installation of an additional package to function properly:
+
+ ```shell
+ sudo apt-get -y install app-protect-ip-intelligence
+ ```
+
+ After installing the package, run the client:
+
+ ```shell
+ /opt/app_protect/bin/iprepd /etc/app_protect/tools/iprepd.cfg > ipi.log 2>&1 &
+ ```
+
+ Verify the client is populating the database:
+
+ ```shell
+ tail -f iprepd.log
+ ```
+
+ Update your policy to include the new configuration, then run [apreload]({{< ref "/nap-waf/v4/configuration-guide/configuration.md#apreload" >}}) command to make changes take effect
+
+ {{< note >}} For this capability to function properly, please follow the guidelines listed in the [configuration guide]({{< ref "/nap-waf/v4/configuration-guide/configuration.md#ip-intelligence-configuration" >}}){{< /note >}}
+
{{< note >}} Ubuntu 20.04 / Ubuntu 22.04 / Ubuntu 24.04 activates **AppArmor** by default, but NGINX App Protect WAF will run in unconfined mode after being installed as it is shipped with no AppArmor profile. To benefit from AppArmor access control capabilities for NGINX App Protect WAF, you will have to write your own AppArmor profile for NGINX App Protect WAF executables found in `/opt/app_protect/bin` such that it best suits your environment.
{{< /note >}}
@@ -933,7 +1069,13 @@ If a user other than **nginx** is to be used, note the following:
/bin/su -s /bin/sh -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 &" nginx
/usr/sbin/nginx -g 'daemon off;'
```
+
+ If you want to use IP intelligence feature (Available from versions 4.15.0 and above), add this additional line to your `entrypoint.sh` file:
+ ```shell
+ /opt/app_protect/bin/iprepd /etc/app_protect/tools/iprepd.cfg > ipi.log 2>&1 &
+ ```
+
7. Create a Docker image:
- For Oracle Linux/Debian/Ubuntu/Alpine/Amazon Linux:
@@ -996,6 +1138,11 @@ 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 \
apk update && apk add app-protect
+# Only use if you want to install and use the IP intelligence feature:
+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 \
+ apk update && apk add app-protect-ip-intelligence
+
# 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
@@ -1033,6 +1180,11 @@ RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644
&& dnf clean all \
&& rm -rf /var/cache/yum
+# Only use if you want to install and use the IP intelligence feature:
+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 \
+ dnf -y install app-protect-ip-intelligence
+
# 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
@@ -1085,6 +1237,11 @@ 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 app-protect
+# Only use if you want to install and use the IP intelligence feature:
+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 install -y app-protect-ip-intelligence
+
# 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
@@ -1125,6 +1282,11 @@ RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644
&& dnf clean all \
&& rm -rf /var/cache/dnf
+# Only use if you want to install and use the IP intelligence feature:
+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 \
+ dnf install -y app-protect-ip-intelligence
+
# 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
@@ -1163,6 +1325,53 @@ RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644
&& dnf clean all \
&& rm -rf /var/cache/dnf
+# Only use if you want to install and use the IP intelligence feature:
+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 \
+ dnf install -y app-protect-ip-intelligence
+
+# 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/
+
+CMD ["sh", "/root/entrypoint.sh"]
+```
+
+### Rocky Linux 9 Dockerfile example
+
+```dockerfile
+# syntax=docker/dockerfile:1
+# For Rocky Linux 9:
+FROM rockylinux:9
+
+# Install prerequisite packages:
+RUN dnf -y install wget ca-certificates 'dnf-command(config-manager)'
+
+# Add NGINX Plus repo to Yum:
+RUN wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/plus-9.repo
+
+# Add NGINX App-protect & dependencies repo to Yum:
+RUN wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/app-protect-9.repo
+RUN dnf config-manager --set-enabled crb \
+ && wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/dependencies.repo \
+ && dnf clean all
+
+# Install NGINX App Protect WAF:
+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 \
+ dnf install --enablerepo=codeready-builder-for-rhel-9-x86_64-rpms -y app-protect \
+ && dnf clean all \
+ && rm -rf /var/cache/dnf
+
+# Only use if you want to install and use the IP intelligence feature:
+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 \
+ dnf install -y app-protect-ip-intelligence
+
# 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
@@ -1204,6 +1413,11 @@ RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644
&& dnf clean all \
&& rm -rf /var/cache/dnf
+# Only use if you want to install and use the IP intelligence feature:
+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 \
+ dnf install -y app-protect-ip-intelligence
+
# 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
@@ -1256,6 +1470,11 @@ 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 && DEBIAN_FRONTEND="noninteractive" apt-get install -y app-protect
+# Only use if you want to install and use the IP intelligence feature:
+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 install -y app-protect-ip-intelligence
+
# 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
@@ -1465,6 +1684,30 @@ RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644
&& rm -rf /var/cache/dnf
```
+### Rocky Linux 9 Converter Docker Deployment Example
+
+```dockerfile
+# syntax=docker/dockerfile:1
+# For Rocky Linux 9:
+FROM rockylinux:9
+
+# Install prerequisite packages:
+RUN dnf -y install wget ca-certificates 'dnf-command(config-manager)'
+
+# Add NGINX App-protect & dependencies repo to Yum:
+RUN wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/app-protect-9.repo
+RUN dnf config-manager --set-enabled crb \
+ && wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/dependencies.repo \
+ && dnf clean all
+
+# Install NGINX App Protect WAF:
+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 \
+ dnf install -y app-protect-compiler \
+ && dnf clean all \
+ && rm -rf /var/cache/dnf
+```
+
### Oracle Linux 8 Converter Docker Deployment Example
```dockerfile
@@ -1628,6 +1871,12 @@ On a host with access to the NGINX App Protect WAF repository:
yum install --downloadonly --downloaddir=/etc/packages/ app-protect
```
+ Only use if you want to install and use the IP intelligence feature:
+
+ ```shell
+ yum install --downloadonly --downloaddir=/etc/packages/ app-protect-ip-intelligence
+ ```
+
3. Download the `epel-release` dependency package:
For RHEL 8.1+ / Oracle Linux 8.1+:
@@ -1656,6 +1905,12 @@ On an offline host:
yum -y install app-protect
```
+ Only use if you want to install and use the IP intelligence feature:
+
+ ```shell
+ yum -y install app-protect-ip-intelligence
+ ```
+
### Example Deployment for Debian/Ubuntu
#### Add the NGINX App Protect WAF Packages to an Internal Repository
@@ -1670,6 +1925,13 @@ On a host with access to the NGINX App Protect WAF repository:
apt-get update
for i in $(apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts --no-breaks --no-replaces --no-enhances app-protect | grep "^\w" | sort -u); do apt-get download $i 2>>errors.txt; done
```
+
+ Only use if you want to install and use the IP intelligence feature:
+
+ ```shell
+ cd /etc/packages/
+ apt-get download app-protect-ip-intelligence
+ ```
2. Add the packages in `/etc/packages` to your local repository.
@@ -1685,6 +1947,11 @@ On an offline host:
apt-get update
apt-get install -y app-protect
```
+ Only use if you want to install and use the IP intelligence feature:
+
+ ```shell
+ apt-get install -y app-protect-ip-intelligence
+ ```
## Post-Installation Checks
@@ -2434,12 +2701,28 @@ You can uninstall the App Protect in below Operating Systems by using the follow
### RHEL 8.1+ / Oracle Linux 8.1+ / RHEL 9+
+If you have previously installed `app-protect-ip-intelligence` package, please make sure to uninstall it first:
+
+```shell
+sudo dnf remove app-protect-ip-intelligence
+```
+
+Then proceed with uninstalling App Protect packages:
+
```shell
sudo dnf remove app-protect app-protect-selinux
```
### Debian 11 / Debian 12 / Ubuntu 20.04 / Ubuntu 22.04 / Ubuntu 24.04
+If you have previously installed `app-protect-ip-intelligence` package, please make sure to uninstall it first:
+
+```shell
+sudo apt-get remove app-protect-ip-intelligence
+```
+
+Then proceed with uninstalling App Protect packages:
+
```shell
sudo apt-get remove app-protect \
app-protect-plugin \
@@ -2455,6 +2738,14 @@ app-protect-bot-signatures
### Alpine 3.16 / Alpine 3.17 / Alpine 3.19
+If you have previously installed `app-protect-ip-intelligence` package, please make sure to uninstall it first:
+
+```shell
+sudo apk del app-protect-ip-intelligence
+```
+
+Then proceed with uninstalling App Protect packages:
+
```shell
sudo apk del app-protect \
app-protect-plugin \
diff --git a/content/nap-waf/v4/configuration-guide/configuration.md b/content/nap-waf/v4/configuration-guide/configuration.md
index 025870d05..6b3a9c2c0 100644
--- a/content/nap-waf/v4/configuration-guide/configuration.md
+++ b/content/nap-waf/v4/configuration-guide/configuration.md
@@ -38,7 +38,9 @@ When configuring NGINX App Protect WAF, `app_protect_enable` should always be en
|[Deny and Allow IP lists](#deny-and-allow-ip-lists) | Manually define denied & allowed IP addresses as well as IP addresses to never log. |
|[XFF headers & trust](#xff-headers-and-trust) | Disabled by default. User can enable it and optionally add a list of custom XFF headers. |
|[gRPC Protection](#grpc-protection-for-unary-traffic) | gRPC content profile detects malformed content, parses well-formed content, and extracts the text fields for detecting attack signatures and disallowed meta-characters. In addition, it enforces size restrictions and prohibition of unknown fields. The Interface Definition Language (IDL) files for the gRPC API must be attached to the profile. gRPC protection can be on [unary](#grpc-protection-for-unary-traffic) or [bidirectional](#grpc-protection-for-bidirectional-streaming) traffic.|
-|[Brute Force Attack Preventions](#brute-force-attack-preventions) | Configure brute-force-attack-preventions parameters to secured areas of a web application from brute force attacks.|}
+|[Brute Force Attack Preventions](#brute-force-attack-preventions) | Configure brute-force-attack-preventions parameters to secured areas of a web application from brute force attacks.|
+|[IP Address Lists](#ip-address-lists) | Configure IP Address Lists feature to organize lists of allowed and forbidden IP addresses across several lists with common attributes.|
+|[IP Intelligence](#ip-intelligence-configuration) | Configure the IP Intelligence feature to customize enforcement based on the source IP of the request, limiting access from IP addresses with questionable reputation.|
### Disallowed File Types
{{< include "nap-waf/config/common/disallowed-file-types.md" >}}
@@ -240,6 +242,14 @@ http {
{{< include "nap-waf/config/common/enforcer-cookie-settings.md" >}}
+### IP Intelligence Configuration
+
+{{< include "nap-waf/config/common/ip-intelligence-conf.md" >}}
+
+### IP Intelligence Forward Proxy Configuration
+
+{{< include "nap-waf/config/common/forward-proxy-conf.md" >}}
+
### Additional Configuration Options
@@ -478,6 +488,15 @@ For the full reference of Override Rules condition syntax and usage see the NGIN
{{< include "nap-waf/config/common/geolocation-override-rules.md" >}}
+## IP Address Lists
+
+### Overview
+
+{{< include "nap-waf/config/common/ip-groups-overview.md" >}}
+
+### IP Address Lists in Policy Override Rules Conditions
+
+{{< include "nap-waf/config/common/ip-groups-override-rules.md" >}}
## JSON Web Token Protection
@@ -660,12 +679,23 @@ systematic, username/password combinations to discover legitimate authentication
To prevent brute force attacks, NGINX App Protect WAF monitors IP addresses, usernames, and the number of failed login attempts beyond a maximum threshold.
When brute force patterns are detected, the NGINX App Protect WAF policy either trigger an alarm or block the attack if the failed
login attempts reached a maximum threshold for a specific username or coming from a specific IP address.
-To enable brute force protection, at least one login page must be created.
-The login page entity is created separately and is not included in the brute force configuration block.
+In order to create a brute force configuration for a specific URL in NGINX App Protect you must first create a User-Defined URL, then a Login Page and finally define the URL element in the Brute Force configuration section.
---
+### The User-Defined URL example
-### Login page policy example
+```json
+"urls": [
+ {
+ "method": "*",
+ "name": "/html_login",
+ "protocol": "http",
+ "type": "explicit"
+ }
+ ],
+```
+
+### Login pages example
A login page specifies the login URL that users must pass through to get authenticated. The configuration of a login URL includes the URL itself, the username and passwords parameters and the validation criteria (how we know that a login was successful or failed)
```json
@@ -690,18 +720,10 @@ A login page specifies the login URL that users must pass through to get authent
{{< note >}} For further configuration details, see NGINX App Protect WAF Declarative Policy Guide [Declarative Policy guide]({{< ref "/nap-waf/v4/declarative-policy/policy/#policy/login-pages" >}}). {{< /note >}}
---
-### Brute force policy example
+### Brute force prevention example
Example1: A single brute force configuration is applied universally to all login pages.
```json
-{
- "policy": {
- "name": "BruteForcePolicy",
- "template": {
- "name": "POLICY_TEMPLATE_NGINX_BASE"
- },
- "applicationLanguage": "utf-8",
- "enforcementMode": "blocking",
"brute-force-attack-preventions" : [
{
"bruteForceProtectionForAllLoginPages" : true,
@@ -719,21 +741,11 @@ Example1: A single brute force configuration is applied universally to all login
"sourceBasedProtectionDetectionPeriod" : 3600
}
]
- }
-}
```
Example2: Different brute force configurations can be defined for individual login pages,
with each configuration referencing a specific login page.
```json
-{
- "policy": {
- "name": "BruteForcePolicySpec",
- "template": {
- "name": "POLICY_TEMPLATE_NGINX_BASE"
- },
- "applicationLanguage": "utf-8",
- "enforcementMode": "blocking",
"brute-force-attack-preventions" : [
{
"bruteForceProtectionForAllLoginPages" : false,
@@ -753,13 +765,72 @@ Example2: Different brute force configurations can be defined for individual log
"method": "*",
"name": "/html_login",
"protocol": "http"
- }
+ }
}
],
+```
- }
+The following example adds all three of the pieces for a complete example policy.
+
+```json
+{
+ "policy": {
+ "name": "BruteForcePolicy",
+ "template": {
+ "name": "POLICY_TEMPLATE_NGINX_BASE"
+ },
+ "applicationLanguage": "utf-8",
+ "enforcementMode": "blocking",
+ "urls": [
+ {
+ "method": "*",
+ "name": "/html_login",
+ "protocol": "http",
+ "type": "explicit"
+ }
+ ],
+ "login-pages": [
+ {
+ "accessValidation": {
+ "responseContains": "Success"
+ },
+ "authenticationType": "form",
+ "url": {
+ "method": "*",
+ "name": "/html_login",
+ "protocol": "http",
+ "type": "explicit"
+ },
+ "usernameParameterName": "username",
+ "passwordParameterName": "password"
+ }
+ ],
+ "brute-force-attack-preventions": [
+ {
+ "bruteForceProtectionForAllLoginPages": false,
+ "loginAttemptsFromTheSameIp": {
+ "action": "alarm",
+ "enabled": true,
+ "threshold": 20
+ },
+ "loginAttemptsFromTheSameUser": {
+ "action": "alarm",
+ "enabled": true,
+ "threshold": 3
+ },
+ "reEnableLoginAfter": 3600,
+ "sourceBasedProtectionDetectionPeriod": 3600,
+ "url": {
+ "method": "*",
+ "name": "/html_login",
+ "protocol": "http"
+ }
+ }
+ ]
+ }
}
```
+
{{< note >}} For further configuration details, see NGINX App Protect WAF Declarative Policy Guide [Declarative Policy guide]({{< ref "/nap-waf/v4/declarative-policy/policy/#policy/brute-force-attack-preventions" >}}). {{< /note >}}
## Custom Dimensions Log Entries
diff --git a/content/nap-waf/v4/releases/about-4.15.md b/content/nap-waf/v4/releases/about-4.15.md
new file mode 100644
index 000000000..f56e4ac52
--- /dev/null
+++ b/content/nap-waf/v4/releases/about-4.15.md
@@ -0,0 +1,43 @@
+---
+title: NGINX App Protect WAF 4.15
+weight: 80
+toc: true
+nd-content-type: reference
+nd-product: NAP-WAF
+---
+
+June 24th, 2025
+
+## New features
+
+- Added support for [IP Intelligence]({{< ref "/nap-waf/v4/configuration-guide/configuration.md#ip-intelligence-configuration" >}})
+- Added support for Rocky Linux 9
+- Added support for Override rules for [IP Address Lists]({{< ref "/nap-waf/v4/configuration-guide/configuration.md#ip-address-lists" >}})
+
+## Important notes
+
+- Ubuntu 20.04 is no longer supported
+- 12447 - Upgrade libk5crypto3 package
+- 12520 - Upgrade Go compiler to 1.23.8
+
+## Resolved issues
+
+- 12527 - Remove CPAN - installed certs and source files
+- 11112 - Remove systemd/init.d leftovers in NAP WAF v5 pkgs
+- 12400 - Cookie attributes are not added to a TS cookie when there is more than one TS cookie
+- 12498 - Undefined behavior when using huge XFF
+- 12731 - Multiple clean_resp_reset internal error messages in logs when loading NAP
+
+## Supported packages
+
+| Distribution name | Package file |
+|--------------------------|----------------------------------------------------|
+| Alpine 3.19 | _app-protect-34.5.442.0-r1.apk_ |
+| Amazon Linux 2023 | _app-protect-34+5.442.0-1.amzn2023.ngx.x86_64.rpm_ |
+| Debian 11 | _app-protect_34+5.442.0-1\~bullseye_amd64.deb_ |
+| Debian 12 | _app-protect_34+5.442.0-1\~bookworm_amd64.deb_ |
+| Oracle Linux 8.1 | _app-protect-34+5.442.0-1.el8.ngx.x86_64.rpm_ |
+| Ubuntu 22.04 | _app-protect_34+5.442.0-1\~jammy_amd64.deb_ |
+| Ubuntu 24.04 | _app-protect_34+5.442.0-1\~noble_amd64.deb_ |
+| RHEL 8 and Rocky Linux 8 | _app-protect-34+5.442.0-1.el8.ngx.x86_64.rpm_ |
+| RHEL 9 and Rocky Linux 9 | _app-protect-34+5.442.0-1.el9.ngx.x86_64.rpm_ |
diff --git a/content/nap-waf/v5/admin-guide/deploy-on-docker.md b/content/nap-waf/v5/admin-guide/deploy-on-docker.md
index 40ab5e5b3..a2f0e3821 100644
--- a/content/nap-waf/v5/admin-guide/deploy-on-docker.md
+++ b/content/nap-waf/v5/admin-guide/deploy-on-docker.md
@@ -104,6 +104,11 @@ CMD ["nginx", "-g", "daemon off;"]
{{< include "nap-waf/config/v5/build-nginx-image-oss/build-rhel.md" >}}
+{{%/tab%}}
+{{%tab name="Rocky Linux 9"%}}
+
+{{< include "nap-waf/config/v5/build-nginx-image-oss/build-rocky.md" >}}
+
{{%/tab%}}
{{%tab name="Ubuntu"%}}
@@ -183,6 +188,11 @@ CMD ["nginx", "-g", "daemon off;"]
{{< include "nap-waf/config/v5/build-nginx-image-plus/build-rhel.md" >}}
+{{%/tab%}}
+{{%tab name="Rocky Linux 9"%}}
+
+{{< include "nap-waf/config/v5/build-nginx-image-plus/build-rocky.md" >}}
+
{{%/tab%}}
{{%tab name="Ubuntu"%}}
@@ -346,6 +356,11 @@ volumes:
```
+### Docker Compose File with IP Intelligence
+
+{{< include "nap-waf/ip-intelligence.md" >}}
+
+
### Docker Compose File with mTLS
To secure traffic between NGINX and App Protect Enforcer using mTLS, create a `docker-compose.yml` with the following configuration:
@@ -486,6 +501,11 @@ Proceed, by creating a `Dockerfile` using one of the examples provided below.
{{< include "nap-waf/config/v5/build-nginx-image-oss/build-rhel.md" >}}
+{{%/tab%}}
+{{%tab name="Rocky Linux 9"%}}
+
+{{< include "nap-waf/config/v5/build-nginx-image-oss/build-rocky.md" >}}
+
{{%/tab%}}
{{%tab name="Ubuntu"%}}
@@ -518,6 +538,11 @@ You are ready to [Build the image](#build-image-sub)
{{< include "nap-waf/config/v5/build-nginx-image-plus/build-rhel.md" >}}
+{{%/tab%}}
+{{%tab name="Rocky Linux 9"%}}
+
+{{< include "nap-waf/config/v5/build-nginx-image-plus/build-rocky.md" >}}
+
{{%/tab%}}
{{%tab name="Ubuntu"%}}
@@ -665,6 +690,11 @@ volumes:
app_protect_config:
app_protect_etc_config:
```
+
+#### Docker Compose File with IP Intelligence
+
+{{< include "nap-waf/ip-intelligence.md" >}}
+
### Start Deployment
1. To start the NGINX and WAF services, navigate to the directory that contains the `docker-compose.yml` file and run:
diff --git a/content/nap-waf/v5/admin-guide/deploy-with-helm.md b/content/nap-waf/v5/admin-guide/deploy-with-helm.md
index 32b3105be..4a2eeb801 100644
--- a/content/nap-waf/v5/admin-guide/deploy-with-helm.md
+++ b/content/nap-waf/v5/admin-guide/deploy-with-helm.md
@@ -66,6 +66,11 @@ Next, create a `Dockerfile` using one of the examples provided below.
{{< include "nap-waf/config/v5/build-nginx-image-oss/build-rhel.md" >}}
+{{%/tab%}}
+{{%tab name="Rocky Linux"%}}
+
+{{< include "nap-waf/config/v5/build-nginx-image-oss/build-rocky.md" >}}
+
{{%/tab%}}
{{%tab name="Ubuntu"%}}
@@ -108,6 +113,11 @@ You are ready to [Build the image](#build-image).
{{< include "nap-waf/config/v5/build-nginx-image-plus/build-rhel.md" >}}
+{{%/tab%}}
+{{%tab name="Rocky Linux 9"%}}
+
+{{< include "nap-waf/config/v5/build-nginx-image-plus/build-rocky.md" >}}
+
{{%/tab%}}
{{%tab name="Ubuntu"%}}
@@ -231,6 +241,11 @@ To use the *mTLS Configuration* options, read the [Secure Traffic Between NGINX
| | _appprotect.wafEnforcer.imagePullPolicy_ | Image pull policy. | IfNotPresent |
| | _appprotect.wafEnforcer.env.enforcerPort_ | Port for the WAF Enforcer. | 50000 |
| | _appprotect.wafEnforcer.resources_ | The resources of the WAF Enforcer container. | requests: cpu=20m,memory=256Mi |
+| **WAF IP Intelligence** | _appprotect.wafIpIntelligence.enable | Enable or disable the use of the IP intelligence container | false |
+| | _appprotect.wafIpIntelligence.image.repository_ | Docker image repository for the WAF IP Intelligence. | private-registry.nginx.com/nap/waf-ip-intelligence |
+| | _appprotect.wafIpIntelligence.image.tag_ | Docker image tag for the WAF Enforcer. | 5.6.0 |
+| | _appprotect.wafIpIntelligence.imagePullPolicy_ | Image pull policy. | IfNotPresent |
+| | _appprotect.wafIpIntelligence.resources_ | The resources of the WAF Enforcer container. | requests: cpu=10m,memory=256Mi |
| **Config** | _appprotect.config.name_ | The name of the ConfigMap used by the NGINX container. | nginx-config |
| | _appprotect.config.annotations_ | The annotations of the ConfigMap. | {} |
| | _appprotect.config.nginxJWT_ | JWT license for NGINX. | "" |
diff --git a/content/nap-waf/v5/admin-guide/deploy-with-manifests.md b/content/nap-waf/v5/admin-guide/deploy-with-manifests.md
index 310d5400b..ded07b037 100644
--- a/content/nap-waf/v5/admin-guide/deploy-with-manifests.md
+++ b/content/nap-waf/v5/admin-guide/deploy-with-manifests.md
@@ -59,6 +59,11 @@ Proceed, by creating a `Dockerfile` using one of the examples provided below.
{{< include "nap-waf/config/v5/build-nginx-image-oss/build-rhel.md" >}}
+{{%/tab%}}
+{{%tab name="Rocky Linux 9"%}}
+
+{{< include "nap-waf/config/v5/build-nginx-image-oss/build-rocky.md" >}}
+
{{%/tab%}}
{{%tab name="Ubuntu"%}}
@@ -101,6 +106,11 @@ You are ready to [Build the image](#build-image).
{{< include "nap-waf/config/v5/build-nginx-image-plus/build-rhel.md" >}}
+{{%/tab%}}
+{{%tab name="Rocky Linux 9"%}}
+
+{{< include "nap-waf/config/v5/build-nginx-image-plus/build-rocky.md" >}}
+
{{%/tab%}}
{{%tab name="Ubuntu"%}}
@@ -281,6 +291,82 @@ spec:
claimName: nap5-bundles-pvc
```
+An example `nap5-deployment-with-ip-intelligence.yaml` if you are using the IP Intelligence feature:
+
+Replace the `/nginx-app-protect-5:` with the actual image tag.
+
+```yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: nap5-deployment
+spec:
+ selector:
+ matchLabels:
+ app: nap5
+ replicas: 2
+ template:
+ metadata:
+ labels:
+ app: nap5
+ spec:
+ imagePullSecrets:
+ - name: regcred
+ containers:
+ - name: nginx
+ image: /nginx-app-protect-5:
+ imagePullPolicy: IfNotPresent
+ volumeMounts:
+ - name: app-protect-bd-config
+ mountPath: /opt/app_protect/bd_config
+ - name: app-protect-config
+ mountPath: /opt/app_protect/config
+ - name: waf-enforcer
+ image: private-registry.nginx.com/nap/waf-enforcer:
+ imagePullPolicy: IfNotPresent
+ env:
+ - name: ENFORCER_PORT
+ value: "50000"
+ volumeMounts:
+ - name: app-protect-bd-config
+ mountPath: /opt/app_protect/bd_config
+ - name: var-iprep
+ mountPath: /var/IpRep
+ - name: waf-config-mgr
+ image: private-registry.nginx.com/nap/waf-config-mgr:
+ imagePullPolicy: IfNotPresent
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop:
+ - all
+ volumeMounts:
+ - name: app-protect-bd-config
+ mountPath: /opt/app_protect/bd_config
+ - name: app-protect-config
+ mountPath: /opt/app_protect/config
+ - name: app-protect-bundles
+ mountPath: /etc/app_protect/bundles
+ - name: waf-ip-intelligence
+ image: private-registry.nginx.com/napwaf-ip-intelligence:
+ imagePullPolicy: IfNotPresent
+ securityContext:
+ allowPrivilegeEscalation: false
+ volumeMounts:
+ - name: var-iprep
+ mountPath: /var/IpRep
+ volumes:
+ - name: app-protect-bd-config
+ emptyDir: {}
+ - name: app-protect-config
+ emptyDir: {}
+ - name: var-iprep
+ emptyDir: {}
+ - name: app-protect-bundles
+ persistentVolumeClaim:
+ claimName: nap5-bundles-pvc
+```
+
Finally, `nap5-service.yaml`:
```yaml
@@ -436,6 +522,11 @@ Proceed, by creating a `Dockerfile` using one of the examples provided below.
{{< include "nap-waf/config/v5/build-nginx-image-oss/build-rhel.md" >}}
+{{%/tab%}}
+{{%tab name="Rocky Linux 9"%}}
+
+{{< include "nap-waf/config/v5/build-nginx-image-oss/build-rocky.md" >}}
+
{{%/tab%}}
{{%tab name="Ubuntu"%}}
@@ -468,6 +559,11 @@ You are ready to [Build the image](#build-image-sub)
{{< include "nap-waf/config/v5/build-nginx-image-plus/build-rhel.md" >}}
+{{%/tab%}}
+{{%tab name="Rocky Linux 9"%}}
+
+{{< include "nap-waf/config/v5/build-nginx-image-plus/build-rocky.md" >}}
+
{{%/tab%}}
{{%tab name="Ubuntu"%}}
diff --git a/content/nap-waf/v5/admin-guide/install.md b/content/nap-waf/v5/admin-guide/install.md
index 3a125b0a9..7e1f05355 100644
--- a/content/nap-waf/v5/admin-guide/install.md
+++ b/content/nap-waf/v5/admin-guide/install.md
@@ -68,6 +68,12 @@ Please follow these steps before you install either NGINX Open Source or NGINX P
{{%/tab%}}
+{{%tab name="Rocky Linux 9"%}}
+
+{{< include "nap-waf/config/v5/host-based-nginx-instructions/common-steps-with-dnf.md" >}}
+
+{{%/tab%}}
+
{{%tab name="Ubuntu"%}}
{{< include "nap-waf/config/v5/host-based-nginx-instructions/common-steps-with-ubuntu.md" >}}
@@ -111,6 +117,12 @@ Please follow these steps before you install either NGINX Open Source or NGINX P
{{%/tab%}}
+{{%tab name="Rocky Linux 9"%}}
+
+{{< include "nap-waf/config/v5/host-based-nginx-instructions/nginx-oss-centos.md" >}}
+
+{{%/tab%}}
+
{{%tab name="Ubuntu"%}}
{{< include "nap-waf/config/v5/host-based-nginx-instructions/nginx-oss-ubuntu.md" >}}
@@ -166,7 +178,7 @@ sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/nginx-plus-8.rep
{{%/tab%}}
-{{%tab name="RHEL 9"%}}
+{{%tab name="RHEL 9 / Rocky Linux 9"%}}
Download the NGINX Plus repository file [plus-9.repo](https://cs.nginx.com/static/files/plus-9.repo) to `/etc/yum.repos.d`:
@@ -294,6 +306,10 @@ networks:
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 NGINX App Protect WAF v5 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 keep in mind that this lowers security and isn't advised for prolonged use.
{{< /note >}}
+### Docker Compose File with IP Intelligence
+
+{{< include "nap-waf/ip-intelligence.md" >}}
+
## Start the Deployment
1. To start the WAF services, navigate to the directory that contains the `docker-compose.yml` file and run:
@@ -314,6 +330,10 @@ In some operating systems, security mechanisms like **SELinux** or **AppArmor**
curl "localhost/ |