Skip to content

Commit b7b25b7

Browse files
authored
Merge branch 'main' into nic-ngf-nginx-one-integration
2 parents 40c8e23 + 8280e8d commit b7b25b7

File tree

24 files changed

+1450
-127
lines changed

24 files changed

+1450
-127
lines changed

.github/workflows/build-push.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ jobs:
5858
5959
call-docs-build-push:
6060
needs: prod-check-branch
61-
uses: nginxinc/docs-actions/.github/workflows/docs-build-push.yml@cc69def33942d819719164723b35b5163d838276 # v1.0.9
61+
uses: nginxinc/docs-actions/.github/workflows/docs-build-push.yml@285440f02d9967b62aeb1b7e0b5c2c70d4f950cf # v1.0.10
6262
with:
6363
production_url_path: ""
6464
preview_url_path: "${{ vars.PREVIEW_URL_PATH }}"

Makefile

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
HUGO?=hugo
22
HUGO_VERSION?=$(shell hugo version 2>/dev/null | awk '{print $$2}' | cut -d '.' -f 2)
3-
HUGO_IMG?=hugomods/hugo:std-go-git-0.134.3
3+
HUGO_IMG?=hugomods/hugo:std-go-git-0.147.8
44

55
THEME_MODULE = github.com/nginxinc/nginx-hugo-theme
66

7-
ifeq ($(shell [ $(HUGO_VERSION) -gt 133 2>/dev/null ] && echo true || echo false), true)
8-
$(info Hugo is available and has a version greater than 133. Proceeding with build.)
7+
ifeq ($(shell [ $(HUGO_VERSION) -gt 146 2>/dev/null ] && echo true || echo false), true)
8+
$(info Hugo is available and has a version greater than 146. Proceeding with build.)
99
else
10-
$(warning Hugo is not available or using a version less than 134. Attempting to use docker. HUGO_VERSION=$(HUGO_VERSION))
10+
$(warning Hugo is not available or using a version less than 147. Attempting to use docker. HUGO_VERSION=$(HUGO_VERSION))
1111
HUGO=docker run --rm -it -v ${CURDIR}:/src -p 1313:1313 ${HUGO_IMG} /src/hugo-entrypoint.sh
1212
ifeq (, $(shell docker version 2> /dev/null))
13-
$(error Hugo (>0.134) or Docker are required to build the local previews.)
13+
$(error Hugo (>0.147) or Docker are required to build the local previews.)
1414
endif
1515
endif
1616

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Enable Forward Proxy Settings for IP Intelligence Client.
2+
3+
To configure proxy settings, edit the client configuration file:
4+
Path:
5+
```shell
6+
/etc/app_protect/tools/iprepd.cfg
7+
```
8+
Example configuration:
9+
```shell
10+
EnableProxy=True
11+
ProxyHost=5.1.2.4
12+
ProxyPort=8080
13+
ProxyUsername=admin # Optional
14+
ProxyPassword=admin # Optional
15+
CACertPath=/etc/ssl/certs/ca-certificates.crt # Optional
16+
```
17+
After saving the changes, restart the client to apply the new settings.
18+
```shell
19+
/opt/app_protect/bin/iprepd /etc/app_protect/tools/iprepd.cfg > ipi.log 2>&1 &
20+
```
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#### IP-Address-Lists feature as part of Override Rules feature.
2+
3+
The Override Rules feature allows you to override original or parent policy settings.
4+
5+
Rules are defined using specific conditions, which can include an IP Address Lists based on the declarative policy JSON schema.
6+
7+
When triggered, the rule is applied to the _clientIp_ attribute using the _matches_ function.
8+
9+
'clientIp.matches(ipAddressLists["standalone"])'
10+
11+
Here is a policy example:
12+
13+
```json
14+
{
15+
"policy": {
16+
"name": "ip_group_override_rule",
17+
"template": {
18+
"name": "POLICY_TEMPLATE_NGINX_BASE"
19+
},
20+
"applicationLanguage": "utf-8",
21+
"caseInsensitive": false,
22+
"enforcementMode": "blocking",
23+
"ip-address-lists": [
24+
{
25+
"name": "standalone",
26+
"ipAddresses": [
27+
{
28+
"ipAddress": "1.1.1.1/32"
29+
}
30+
]
31+
}
32+
],
33+
"override-rules": [
34+
{
35+
"name": "myRule1",
36+
"condition": "clientIp.matches(ipAddressLists['standalone'])",
37+
"actionType": "extend-policy",
38+
"override": {
39+
"policy": {
40+
"enforcementMode": "transparent"
41+
}
42+
}
43+
}
44+
]
45+
}
46+
}
47+
```
48+
49+
The previous example policy contains an IP address lists with the name "standalone", used for the override rule condition "clientIp.matches(ipAddressLists['standalone'])".
50+
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".
51+
The value used for the override condition must exist and exactly match the name in "ip-address-lists".
52+
53+
#### Possible errors
54+
55+
| Error text | Input | Explanation |
56+
| -----------| ------------- | ------------ |
57+
| _Invalid field invalidList_ | _clientIp.matches(invalidList['standalone']);_ | An incorrect keyword was used instead of _ipAddressLists_ |
58+
| _Invalid value empty string_ | _clientIp.matches(ipAddressLists['']_ | An empty name was provided |
59+
| _Failed to compile policy - 'ipGroupOverridePolicy'_ | _uri.matches(ipAddressLists['standalone']);_ | Used _ipAddressLists_ without the _clientIP_ attribute |
60+
61+
62+
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
IP address lists is a feature to organize lists of allowed and forbidden IP addresses across several lists with common attributes.
2+
3+
This allows you to control unique policy settings for incoming requests based on specific IP addresses.
4+
5+
Each IP address list contains a unique name, enforcement type (_always_, _never_ and _policy-default_), and list of IP addresses.
6+
7+
8+
An example of a declarative policy using IP address lists configuration:
9+
10+
```json
11+
{
12+
"policy": {
13+
"name": "IpGroups_policy",
14+
"template": {
15+
"name": "POLICY_TEMPLATE_NGINX_BASE"
16+
},
17+
"applicationLanguage": "utf-8",
18+
"caseInsensitive": false,
19+
"enforcementMode": "blocking",
20+
"ip-address-lists": [
21+
{
22+
"name": "Standalone",
23+
"description": "Optional Description",
24+
"blockRequests": "policy-default",
25+
"setGeolocation": "IN",
26+
"ipAddresses": [
27+
{
28+
"ipAddress": "1.2.3.4/32"
29+
},
30+
{
31+
"ipAddress": "1111:fc00:0:112::2"
32+
}
33+
]
34+
}
35+
]
36+
}
37+
}
38+
39+
```
40+
The example with IP-Group definition in external file external_ip_groups.json:
41+
42+
```json
43+
{
44+
"policy": {
45+
"name": "IpGroups_policy2",
46+
"template": {
47+
"name": "POLICY_TEMPLATE_NGINX_BASE"
48+
},
49+
"applicationLanguage": "utf-8",
50+
"caseInsensitive": false,
51+
"enforcementMode": "blocking",
52+
"ip-address-lists": [
53+
{
54+
"name": "external_ip_groups",
55+
"description": "Optional Description",
56+
"blockRequests": "always",
57+
"setGeolocation": "IL",
58+
"$ref": "file:///tmp/policy/external_ip_groups.json"
59+
}
60+
]
61+
}
62+
}
63+
```
64+
Example of the file external_ip_groups.json
65+
66+
```json
67+
{
68+
"name": "External IP address lists",
69+
"description": "Optional Description",
70+
"blockRequests": "always",
71+
"setGeolocation": "IR",
72+
"ipAddresses": [
73+
{
74+
"ipAddress": "66.51.41.21"
75+
},
76+
{
77+
"ipAddress": "66.52.42.22"
78+
}
79+
]
80+
}
81+
```
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
2+
3+
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:
4+
- The IP intelligence feature is **disabled** by default and needs to be installed, enabled, and configured within the policy.
5+
- 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" >}})
6+
- The system must have an active Internet connection and a working DNS.
7+
- 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.
8+
- 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" >}}).
9+
10+
Once installed, make sure to enable the feature in the two relevant sections of the policy:
11+
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.
12+
13+
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.
14+
15+
An example policy where both elements are enabled, and all the IP intelligence categories are configured to `block` and `alarm` can be found here:
16+
17+
```json
18+
{
19+
"policy": {
20+
"name": "ip_intelligency_policy",
21+
"template": {
22+
"name": "POLICY_TEMPLATE_NGINX_BASE"
23+
},
24+
"applicationLanguage": "utf-8",
25+
"caseInsensitive": false,
26+
"enforcementMode": "blocking",
27+
"blocking-settings": {
28+
"violations": [
29+
{
30+
"name": "VIOL_MALICIOUS_IP",
31+
"alarm": true,
32+
"block": true
33+
}
34+
]
35+
},
36+
"ip-intelligence": {
37+
"enabled": true,
38+
"ipIntelligenceCategories": [
39+
{
40+
"category": "Anonymous Proxy",
41+
"alarm": true,
42+
"block": true
43+
},
44+
{
45+
"category": "BotNets",
46+
"alarm": true,
47+
"block": true
48+
},
49+
{
50+
"category": "Cloud-based Services",
51+
"alarm": true,
52+
"block": true
53+
},
54+
{
55+
"category": "Denial of Service",
56+
"alarm": true,
57+
"block": true
58+
},
59+
{
60+
"category": "Infected Sources",
61+
"alarm": true,
62+
"block": true
63+
},
64+
{
65+
"category": "Mobile Threats",
66+
"alarm": true,
67+
"block": true
68+
},
69+
{
70+
"category": "Phishing Proxies",
71+
"alarm": true,
72+
"block": true
73+
},
74+
{
75+
"category": "Scanners",
76+
"alarm": true,
77+
"block": true
78+
},
79+
{
80+
"category": "Spam Sources",
81+
"alarm": true,
82+
"block": true
83+
},
84+
{
85+
"category": "Tor Proxies",
86+
"alarm": true,
87+
"block": true
88+
},
89+
{
90+
"category": "Web Attacks",
91+
"alarm": true,
92+
"block": true
93+
},
94+
{
95+
"category": "Windows Exploits",
96+
"alarm": true,
97+
"block": true
98+
}
99+
]
100+
}
101+
}
102+
}
103+
```
104+
105+
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.
106+
107+
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:
108+
- Anonymous Proxy
109+
- BotNets
110+
- Cloud-based Services
111+
- Denial of Service
112+
- Infected Sources
113+
- Mobile Threats
114+
- Phishing Proxies
115+
- Scanners
116+
- Spam Sources
117+
- Tor Proxies
118+
- Web Attacks
119+
- Windows Exploits
120+
121+
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.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
```dockerfile
2+
# syntax=docker/dockerfile:1
3+
4+
# Base Image
5+
FROM rockylinux:9
6+
7+
# Install NGINX OSS and NGINX App Protect WAF v5 module
8+
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \
9+
--mount=type=secret,id=nginx-key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \
10+
dnf -y install wget ca-certificates yum-utils \
11+
&& wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/dependencies.repo \
12+
&& echo "[nginx-mainline]" > /etc/yum.repos.d/nginx.repo \
13+
&& echo "name=nginx mainline repo" >> /etc/yum.repos.d/nginx.repo \
14+
&& echo "baseurl=http://nginx.org/packages/mainline/centos/\$releasever/\$basearch/" >> /etc/yum.repos.d/nginx.repo \
15+
&& echo "gpgcheck=1" >> /etc/yum.repos.d/nginx.repo \
16+
&& echo "enabled=1" >> /etc/yum.repos.d/nginx.repo \
17+
&& echo "gpgkey=https://nginx.org/keys/nginx_signing.key" >> /etc/yum.repos.d/nginx.repo \
18+
&& echo "module_hotfixes=true" >> /etc/yum.repos.d/nginx.repo \
19+
&& echo "[app-protect-x-oss]" > /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-oss.repo \
20+
&& echo "name=nginx-app-protect repo" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-oss.repo \
21+
&& 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 \
22+
&& echo "sslclientcert=/etc/ssl/nginx/nginx-repo.crt" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-oss.repo \
23+
&& echo "sslclientkey=/etc/ssl/nginx/nginx-repo.key" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-oss.repo \
24+
&& echo "gpgcheck=0" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-oss.repo \
25+
&& echo "enabled=1" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-oss.repo \
26+
&& dnf clean all \
27+
&& dnf install -y app-protect-module-oss \
28+
&& dnf clean all \
29+
&& rm -rf /var/cache/dnf \
30+
&& ln -sf /dev/stdout /var/log/nginx/access.log \
31+
&& ln -sf /dev/stderr /var/log/nginx/error.log
32+
33+
# Expose port
34+
EXPOSE 80
35+
36+
# Define stop signal
37+
STOPSIGNAL SIGQUIT
38+
39+
# Set default command
40+
CMD ["nginx", "-g", "daemon off;"]
41+
```
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
```dockerfile
2+
# syntax=docker/dockerfile:1
3+
4+
# Base Image
5+
FROM rockylinux:9
6+
7+
# Install NGINX Plus and NGINX App Protect WAF v5 module
8+
RUN --mount=type=secret,id=nginx-crt,dst=/etc/ssl/nginx/nginx-repo.crt,mode=0644 \
9+
--mount=type=secret,id=nginx-key,dst=/etc/ssl/nginx/nginx-repo.key,mode=0644 \
10+
dnf -y install wget ca-certificates \
11+
&& wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/dependencies.repo \
12+
&& wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/${NGINX_PLUS_REPO} \
13+
&& echo "[app-protect-x-plus]" > /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-plus.repo \
14+
&& echo "name=nginx-app-protect repo" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-plus.repo \
15+
&& 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 \
16+
&& echo "sslclientcert=/etc/ssl/nginx/nginx-repo.crt" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-plus.repo \
17+
&& echo "sslclientkey=/etc/ssl/nginx/nginx-repo.key" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-plus.repo \
18+
&& echo "gpgcheck=0" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-plus.repo \
19+
&& echo "enabled=1" >> /etc/yum.repos.d/app-protect-${UBI_VERSION}-x-plus.repo \
20+
&& dnf clean all \
21+
&& dnf install -y app-protect-module-plus \
22+
&& dnf clean all \
23+
&& rm -rf /var/cache/dnf \
24+
&& ln -sf /dev/stdout /var/log/nginx/access.log \
25+
&& ln -sf /dev/stderr /var/log/nginx/error.log
26+
27+
# Expose port
28+
EXPOSE 80
29+
30+
# Define stop signal
31+
STOPSIGNAL SIGQUIT
32+
33+
# Set default command
34+
CMD ["nginx", "-g", "daemon off;"]
35+
```

0 commit comments

Comments
 (0)