Skip to content

Commit b7ce368

Browse files
ADubhlaoichJTorreG
andauthored
feat: Update WAF install and configuration steps (#1296)
This commit adds a necessary signature command to Alpine Linux, Debian & Ubuntu installation steps. It further improves installation use cases by adding some troubleshooting guidance to post-installation checks. Similarly, policy and bundle-specific troubleshooting guidance has been added to the compiler page. Finally, information on Bot signatures has been added, with contextual links added or updated for logical connections between use cases. --------- Co-authored-by: Jon Torre <78599298+JTorreG@users.noreply.github.com>
1 parent 244c403 commit b7ce368

File tree

8 files changed

+278
-6
lines changed

8 files changed

+278
-6
lines changed

content/includes/waf/install-post-checks.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,13 @@ Verify that Enforcement functionality is working by checking the following reque
6060

6161
```shell
6262
curl "localhost/<script>"
63-
```
63+
```
64+
65+
If you notice problems, there are ways to remediate them based on the context:
66+
67+
| Description | Solution |
68+
| ----------------------- | -------- |
69+
| *NGINX is not running or F5 WAF for NGINX does not behave as expected* | Review warning or error messages within [the log files]({{< ref "/waf/logging/logs-overview.md" >}}) |
70+
| *unknown directive app_protect_xxx error message* | Ensure F5 WAF for NGINX is [loaded as a module](#update-configuration-files) in the main context of NGINX configuration. |
71+
| *Too many open files error message* | Increase the maximum amount of open files with the [worker_rlimit_nofile](https://nginx.org/en/docs/ngx_core_module.html#worker_rlimit_nofile) directive. |
72+
| *setrlimit ... failed (Permission denied) error message* | Increase the limit by by running the following command as root: `setsebool -P httpd_setrlimit 1` |

content/includes/waf/table-policy-features.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
| ----------------------------------- | ----------- |
88
| [Allowed methods]({{< ref "/waf/policies/allowed-methods.md" >}}) | Checks allowed HTTP methods. By default, all the standard HTTP methods are allowed. |
99
| [Attack signatures]({{< ref "/waf/policies/attack-signatures.md" >}}) | The default policy covers the OWASP top 10 attack patterns. Specific signature sets can be added or disabled. |
10+
| [Bot signatures]({{< ref "/waf/policies/bot-signatures.md" >}}) | Bot signatures and headers can be inspected to authenticate the identity of a client making a request. |
1011
| [Brute force attack preventions]({{< ref "/waf/policies/brute-force-attacks.md" >}}) | Configure parameters to secure areas of a web application from brute force attacks. |
1112
| [Cookie enforcement]({{< ref "/waf/policies/cookie-enforcement.md" >}}) | By default all cookies are allowed and not enforced for integrity. The user can add specific cookies, wildcards or explicit, that will be enforced for integrity. It is also possible to set the cookie attributes: HttpOnly, Secure and SameSite for cookies found in the response. |
1213
| [Data guard]({{< ref "/waf/policies/data-guard.md" >}}) | Detects and masks Credit Card Number (CCN) and/or U.S. Social Security Number (SSN) and/or custom patterns in HTTP responses. Disabled by default. |

content/waf/changelog/2024.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ _March 19, 2024_
199199

200200
{{< table >}}
201201

202-
| Distribution name | NGINX Open Source (5.1) | NGINX Plus (5.1) | NGINX Plus (4.9) |
202+
| Distribution name | NGINX Open Source (5.1) | NGINX Plus (5.1) | NGINX Plus (4.8.1) |
203203
| ------------------------ | ----------------------------------------------------------------- | -------------------------------------------------------------- |----------------------------------------------------|
204204
| Alpine 3.17 | _app-protect-module-oss-1.25.4+4.815.0-r1.apk_ | _app-protect-module-plus-31+4.815.0-r1.apk_ | _app-protect-31.4.815.0-r1.apk_ |
205205
| Amazon Linux 2023 | _app-protect-module-oss-1.25.4+4.815.0-1.amzn2023.ngx.x86_64.rpm_ | _app-protect-module-plus-31+4.815.0-1.amzn2023.ngx.x86_64.rpm_ | _app-protect-31+4.815.0-1.amzn2023.ngx.x86_64.rpm_ |

content/waf/configure/compiler.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,27 @@ docker run \
228228
-dump -bundle $(pwd)/compiled_policy.tgz
229229
```
230230

231+
## Debugging bundle errors
232+
233+
When [configuring policies]({{< ref "/waf/policies/configuration.md">}}), you may run into problems.
234+
235+
There are ways to remediate them based on the context:
236+
237+
{{< table >}}
238+
| Description | Solution |
239+
| ----------------------- | -------- |
240+
| _Expected declarative policy_ | Ensure the JSON of the policy is well-formed |
241+
| _Policy Bundles version is older than the local version_ | You must recompile all your bundles from scratch when installing security updates. |
242+
| _Policy Bundles version is newer than the local version_ | You must recompile all your bundles from scratch when installing security updates. |
243+
| _Found mixed content of compiled and raw configuration_ | Only pre-compiled bundles can be used in NGINX configuration: compile JSON to bundles first. |
244+
| _Compiler is required, but not installed: Missing /opt/app_protect/bin/config_set_compiler_ | Only pre-compiled bundles can be used in NGINX configuration: compile JSON to bundles first. |
245+
| _Policy Bundles have differing global states_ | Recompile all of your bundles from scratch with your custom compiler. Bundles must be compiled with the same compiler: you cannot mix default and custom bundles. |
246+
| _Policy Bundles have differing cookie seeds_ | Recompile all of your bundles from scratch with your custom compiler. Bundles must be compiled with the same compiler: you cannot mix default and custom bundles. |
247+
| _Duplicate policy name found_ | Don't compile multiple policies with the same name, or one policy to multiple bundles. Each policy can be compiled once but a bundle can be re-used. |
248+
| _Duplicate logging profile name found | Don't compile the same logging profile to multiple bundles. Each profile can be compiled once but a bundle can be re-used. |
249+
| _Timeout waiting for enforcer_ | Likely an internal issue: [contact Support]({{< ref "/waf/support.md" >}}) |
250+
{{< /table >}}
251+
231252
## Global settings
232253

233254
The global settings allows configuration of the following items:

content/waf/configure/selinux.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,20 @@ nd-content-type: how-to
1212
nd-product: NAP-WAF
1313
---
1414

15-
The default settings for Security-Enhanced Linux (SELinux) on modern Red Hat Enterprise Linux (RHEL) and related distros can be very strict, erring on the side of security rather than convenience.
15+
The default settings for Security-Enhanced Linux (SELinux) on modern Red Hat Enterprise Linux (RHEL) and related distros can be very strict, prioritizing security over user convenience.
1616

1717
To ensure F5 WAF for NGINX operates smoothly without compromising security, consider setting up a custom SELinux policy or AppArmor profile.
1818

1919
For troubleshooting, you may use permissive (SELinux) or complain (AppArmor) mode to avoid these restrictions, but this is inadvisable for prolonged use.
2020

2121
Although F5 WAF for NGINX provides an optional package with prebuilt a SELinux policy (`app-protect-selinux`), your specific configuration might be blocked unless you adjust the policy or modify file labels.
2222

23+
{{< call-out "note" >}}
24+
25+
You may want to read the [Using NGINX and NGINX Plus with SELinux](https://www.f5.com/company/blog/nginx/using-nginx-plus-with-selinux) blog post for more information.
26+
27+
{{< /call-out >}}
28+
2329
## Modifying file labels
2430

2531
If you plan to store your security policy files in an alternative folder such as _/etc/security_policies_, you should change the default SELinux file context:
@@ -43,4 +49,16 @@ Review the syslog ports by entering the following command:
4349
semanage port -l | grep syslog
4450
```
4551

46-
For more information related to syslog, see the [Security logs]({{< ref "/waf/logging/security-logs.md" >}}) topic.
52+
For more information related to syslog, see the [Security logs]({{< ref "/waf/logging/security-logs.md" >}}) topic.
53+
54+
## Review audits
55+
56+
F5 WAF for NGINX files and processes are labelled with the `nap-compiler_t` and `nap-engine_t` contexts. NGINX Plus is labelled with `httpd_t`.
57+
58+
If SELinux denies access to something, you can search audit denials using one of the above contexts.
59+
60+
```shell
61+
ausearch --start recent -m avc --raw -se nap-engine_t
62+
```
63+
64+
The _--start recent_ argument searches the previous 10 minutes.

content/waf/install/update-signatures.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ For other deployment methods, you should read [Build and use the compiler tool](
1919
Signatures are divided into three groups:
2020

2121
- [Attack signatures]({{< ref "/waf/policies/attack-signatures.md" >}})
22+
- [Bot signatures]({{< ref "/waf/policies/bot-signatures.md" >}})
2223
- [Threat campaigns]({{< ref "/waf/policies/threat-campaigns.md" >}})
23-
- Bot signatures
2424

2525
F5 WAF for NGINX signature updates are released at a higher frequency than F5 WAF for NGINX itself, and are subsequently available in their own packages.
2626

@@ -35,7 +35,7 @@ Installing these packages also installed their dependencies, which includes the
3535
They will be named something in the following list:
3636

3737
- `app-protect-attack-signatures`
38-
- `app-protect-threat-campaigns`
3938
- `app-protect-bot-signatures`
39+
- `app-protect-threat-campaigns`
4040

4141
You can update these packages independently of the core F5 WAF for NGINX packages, ensuring you always have the latest signatures.

content/waf/install/virtual-environment.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ Navigate to your chosen operating system, which are alphabetically ordered.
4040

4141
### Alpine Linux
4242

43+
Add the F5 WAF for NGINX signing key:
44+
45+
```shell
46+
sudo wget -O /etc/apk/keys/app-protect-security-updates.rsa.pub https://cs.nginx.com/static/keys/app-protect-security-updates.rsa.pub
47+
```
48+
4349
Add the F5 WAF for NGINX repository:
4450

4551
```shell
@@ -76,6 +82,13 @@ sudo dnf install app-protect
7682

7783
### Debian
7884

85+
Add the F5 WAF for NGINX signing key:
86+
87+
```shell
88+
wget -qO - https://cs.nginx.com/static/keys/app-protect-security-updates.key | gpg --dearmor | \
89+
sudo tee /usr/share/keyrings/app-protect-security-updates.gpg > /dev/null
90+
```
91+
7992
Add the F5 WAF for NGINX repositories:
8093

8194
```shell
@@ -115,6 +128,12 @@ Add F5 WAF for NGINX dependencies:
115128
sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/dependencies.repo
116129
```
117130

131+
Enable F5 WAF for NGINX dependencies:
132+
133+
```shell
134+
sudo dnf config-manager --set-enabled crb
135+
```
136+
118137
Enable the _ol8_codeready_builder_ repository:
119138

120139
```shell
@@ -155,6 +174,13 @@ sudo dnf install app-protect
155174

156175
### Ubuntu
157176

177+
Add the F5 WAF for NGINX signing key:
178+
179+
```shell
180+
wget -qO - https://cs.nginx.com/static/keys/app-protect-security-updates.key | \
181+
gpg --dearmor | sudo tee /usr/share/keyrings/app-protect-security-updates.gpg > /dev/null
182+
```
183+
158184
Add the F5 WAF for NGINX repositories:
159185

160186
```shell
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
---
2+
# We use sentence case and present imperative tone
3+
title: "Bot signatures"
4+
# Weights are assigned in increments of 100: determines sorting order
5+
weight: 550
6+
# Creates a table of contents and sidebar, useful for large documents
7+
toc: true
8+
# Types have a 1:1 relationship with Hugo archetypes, so you shouldn't need to change this
9+
nd-content-type: reference
10+
# Intended for internal catalogue and search, case sensitive:
11+
# Agent, N4Azure, NIC, NIM, NGF, NAP-DOS, NAP-WAF, NGINX One, NGINX+, Solutions, Unit
12+
nd-product: NAP-WAF
13+
---
14+
15+
Bot signatures are a feature that protects applications by detecting signatures and clients that falsely claim to be browsers or search engines.
16+
17+
This feature is enabled by default with the `bot-defense` parameter, and includes both bot signatures and header anomalies, which can be disabled separately.
18+
19+
## Bot signatures
20+
21+
Bot signature detection works by inspecting the the User-Agent header and URI of a request.
22+
23+
Each detected bot signature belongs to a bot class: search engine signatures such as `googlebot` are under the trusted_bots class, but F5 WAF for NGINX performs additional checks to authenticate a trusted bot.
24+
25+
If these checks fail, it means the detected bot signature impersonated a search engine, and it will be given the class `malicous_bot`, anomaly `Search engine verification failed`.
26+
27+
The request will be blocked, regardless of the class's mitigation actions configuration.
28+
29+
This is a list of trusted bots, all of which are search engines.
30+
31+
| Name | Description |
32+
| ------------------ | ----------- |
33+
| Ask | [Ask.com engine](https://www.ask.com) |
34+
| Baidu | [Baidu search engine](https://www.baidu.com/) |
35+
| Baidu Image Spider | [Baidu search engine for images](https://image.baidu.com/) |
36+
| Bing | [Microsoft Bing search engine](https://www.bing.com/) |
37+
| BingPreview | [Microsoft Bing page snapshot generation engine](https://www.bing.com/) |
38+
| Daum | [Daum search engine](https://www.daum.net/) |
39+
| DuckDuckGo Bot | [DuckDuckGo search engine](https://duckduckgo.com/) |
40+
| fastbot | [fastbot search engine](https://www.fastbot.de/) |
41+
| Google | [Google search engine](https://www.google.com/) |
42+
| MojeekBot | [Mojeek search engine](https://www.mojeek.com/) |
43+
| Yahoo! Slurp | [Yahoo search engine](https://www.yahoo.com/) |
44+
| Yandex | [Yandex search engine](https://yandex.com/) |
45+
| YioopBot | Yioop search engine |
46+
47+
An action can be configured for each bot class, or configured for each bot signature individually:
48+
49+
* `ignore` - Bot signature is ignored (disabled)
50+
* `detect` - Only report without raising the violation - `VIOL_BOT_CLIENT`. The request is considered `legal` unless another violation is triggered.
51+
* `alarm` - Report, raise the violation, but pass the request. The request is marked as `illegal`.
52+
* `block` - Report, raise the violation, and block the request
53+
54+
This example enables bot signatures using the default bot configuration:
55+
56+
```json
57+
{
58+
"policy": {
59+
"name": "bot_defense_policy",
60+
"template": {
61+
"name": "POLICY_TEMPLATE_NGINX_BASE"
62+
},
63+
"applicationLanguage": "utf-8",
64+
"enforcementMode": "blocking",
65+
"bot-defense": {
66+
"settings": {
67+
"isEnabled": true
68+
}
69+
}
70+
}
71+
}
72+
```
73+
74+
The default actions for classes are: `detect` for `trusted-bot`, `alarm` for `untrusted-bot`, and `block` for `malicious-bot`.
75+
76+
The next example enables bot defense, configuring a violation for `trusted-bot`, and block for `untrusted-bot`.
77+
78+
```json
79+
{
80+
"policy": {
81+
"name": "bot_defense_policy",
82+
"template": {
83+
"name": "POLICY_TEMPLATE_NGINX_BASE"
84+
},
85+
"applicationLanguage": "utf-8",
86+
"enforcementMode": "blocking",
87+
"bot-defense": {
88+
"settings": {
89+
"isEnabled": true
90+
},
91+
"mitigations": {
92+
"classes": [
93+
{
94+
"name": "trusted-bot",
95+
"action": "alarm"
96+
},
97+
{
98+
"name": "untrusted-bot",
99+
"action": "block"
100+
},
101+
{
102+
"name": "malicious-bot",
103+
"action": "block"
104+
}
105+
]
106+
}
107+
}
108+
}
109+
}
110+
```
111+
112+
The next example overrides the action for a specific signature (python-requests):
113+
114+
```json
115+
{
116+
"policy": {
117+
"name": "bot_defense_policy",
118+
"template": {
119+
"name": "POLICY_TEMPLATE_NGINX_BASE"
120+
},
121+
"applicationLanguage": "utf-8",
122+
"enforcementMode": "blocking",
123+
"bot-defense": {
124+
"settings": {
125+
"isEnabled": true
126+
},
127+
"mitigations": {
128+
"signatures": [
129+
{
130+
"action": "ignore",
131+
"name": "python-requests"
132+
}
133+
]
134+
}
135+
}
136+
}
137+
}
138+
```
139+
140+
The bot signature file, `included_bot_signatures`, is located at the following path: `/opt/app-protect/var/update_files/bot_signatures/included_bot_signatures`.
141+
142+
This file is an up-to-date list of all bot signatures, following a format similar to the README-style text file found for [attack signatures]({{< ref "/waf/policies/attack-signatures.md" >}}).
143+
144+
It contains information such as:
145+
146+
- Bot name
147+
- Bot type
148+
- Bot classification/category
149+
150+
It is part of the _app-protect-bot-signatures_ package: for more information, see the [Update F5 WAF for NGINX signatures]({{< ref "/waf/install/update-signatures.md" >}}) topic.
151+
152+
## Header anomalies
153+
154+
In addition to detecting bot signatures, F5 WAF for NGINX verifies that a client is the browser it claims to be by inspecting the HTTP headers.
155+
156+
Each request receives a score and anomaly category, and is enforced according to the default anomaly action:
157+
158+
| Range | Anomaly | Action | Class |
159+
|--------------- | ----------------------------------------- | ------ | ------------------ |
160+
| 0-49 | None | None | Browser |
161+
| 50-99 | Suspicious HTTP Headers Presence or Order | Alarm | Suspicious Browser |
162+
| 100 and above | Invalid HTTP Headers Presence or Order | Block | Malicious Bot |
163+
| Non Applicable | SEARCH_ENGINE_VERIFICATION_FAILED | Block | Malicious Bot |
164+
165+
The default scores for each anomaly can be changed.
166+
167+
In this example, the score and action of the default bot configuration has been overrided:
168+
169+
```json
170+
{
171+
"policy": {
172+
"name": "bot_anomalies_and_signatures",
173+
"template": {
174+
"name": "POLICY_TEMPLATE_NGINX_BASE"
175+
},
176+
"applicationLanguage": "utf-8",
177+
"enforcementMode": "blocking",
178+
"bot-defense": {
179+
"mitigations": {
180+
"anomalies": [
181+
{
182+
"name": "Suspicious HTTP Headers",
183+
"action": "alarm",
184+
"scoreThreshold": 50
185+
},
186+
{
187+
"name": "Invalid HTTP Headers",
188+
"action": "block",
189+
"scoreThreshold": 99
190+
}
191+
]
192+
}
193+
}
194+
}
195+
}
196+
197+
```

0 commit comments

Comments
 (0)