8000 Add WAF policy · nginx/kubernetes-ingress@af045fe · GitHub
[go: up one dir, main page]

Skip to content

Commit af045fe

Browse files
authored
Add WAF policy
1 parent 1832385 commit af045fe

36 files changed

+2238
-701
lines changed

deployments/common/crds-v1beta1/k8s.nginx.org_policies.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,24 @@ spec:
137137
type: integer
138138
zoneSize:
139139
type: string
140+
waf:
141+
description: 'WAF defines an WAF policy. policy status: preview'
142+
type: object
143+
properties:
144+
apPolicy:
145+
type: string
146+
enable:
147+
type: boolean
148+
securityLog:
149+
description: SecurityLog defines the security log of a WAF policy.
150+
type: object
151+
properties:
152+
apLogConf:
153+
type: string
154+
enable:
155+
type: boolean
156+
logDest:
157+
type: string
140158
status:
141159
description: PolicyStatus is the status of the policy resource
142160
type: object

deployments/common/crds/k8s.nginx.org_policies.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,24 @@ spec:
136136
type: integer
137137
zoneSize:
138138
type: string
139+
waf:
140+
description: 'WAF defines an WAF policy. policy status: preview'
141+
type: object
142+
properties:
143+
apPolicy:
144+
type: string
145+
enable:
146+
type: boolean
147+
securityLog:
148+
description: SecurityLog defines the security log of a WAF policy.
149+
type: object
150+
properties:
151+
apLogConf:
152+
type: string
153+
enable:
154+
type: boolean
155+
logDest:
156+
type: string
139157
status:
140158
description: PolicyStatus is the status of the policy resource
141159
type: object

deployments/helm-chart/crds/k8s.nginx.org_policies.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,24 @@ spec:
137137
type: integer
138138
zoneSize:
139139
type: string
140+
waf:
141+
description: 'WAF defines an WAF policy. policy status: preview'
142+
type: object
143+
properties:
144+
apPolicy:
145+
type: string
146+
enable:
147+
type: boolean
148+
securityLog:
149+
description: SecurityLog defines the security log of a WAF policy.
150+
type: object
151+
properties:
152+
apLogConf:
153+
type: string
154+
enable:
155+
type: boolean
156+
logDest:
157+
type: string
140158
status:
141159
description: PolicyStatus is the status of the policy resource
142160
type: object

docs-web/configuration/policy-resource.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ This document is the reference documentation for the Policy resource. An example
2424
- [EgressMTLS Merging Behavior](#egressmtls-merging-behavior)
2525
- [OIDC](#oidc)
2626
- [OIDC Merging Behavior](#oidc-merging-behavior)
27+
- [WAF](#waf)
28+
- [WAF Merging Behavior](#waf-merging-behavior)
2729
- [Using Policy](#using-policy)
2830
- [Applying Policies](#applying-policies)
2931
- [Invalid Policies](#invalid-policies)
@@ -77,6 +79,10 @@ spec:
7779
- The EgressMTLS policy configures upstreams authentication and certificate verification.
7880
- `egressMTLS <#egressmtls>`_
7981
- No*
82+
* - ``waf``
83+
- The WAF policy configures WAF and log configuration policies for `NGINX AppProtect </nginx-ingress-controller/app-protect/installation/>`_
84+
- `WAF <#waf>`_
85+
- No*
8086
```
8187
8288
\* A policy must include exactly one policy.
@@ -521,6 +527,67 @@ webapp-policy 27m
521527

522528
For `kubectl get` and similar commands, you can also use the short name `pol` instead of `policy`.
523529

530+
### WAF
531+
532+
> **Feature Status**: WAF is available as a preview feature: it is suitable for experimenting and testing; however, it must be used with caution in production environments. Additionally, while the feature is in preview status, we might introduce some backward-incompatible changes to the resource specification in the next releases. The feature is disabled by default. To enable it, set the [enable-preview-policies](/nginx-ingress-controller/configuration/global-configuration/command-line-arguments/#cmdoption-enable-preview-policies) command-line argument of the Ingress Controller.
533+
534+
> Note: This feature is only available in NGINX Plus with AppProtect.
535+
536+
The WAF policy configures NGINX Plus to secure client requests using App Protect policies.
537+
538+
For example, the following policy will enable the referenced APPolicy and APLogConf with the configured log destination:
539+
```yaml
540+
waf:
541+
enable: true
542+
apPolicy: "default/dataguard-alarm"
543+
securityLog:
544+
enable: true
545+
apLogConf: "default/logconf"
546+
logDest: "syslog:server=127.0.0.1:514"
547+
```
548+
549+
> Note: The feature is implemented using the NGINX Plus [NGINX App Protect Module](https://docs.nginx.com/nginx-app-protect/configuration/).
550+
551+
```eval_rst
552+
.. list-table::
553+
:header-rows: 1
554+
555+
* - Field
556+
- Description
557+
- Type
558+
- Required
559+
* - ``enable``
560+
- Enables NGINX App Protect.
561+
- ``bool``
562+
- Yes
563+
* - ``apPolicy``
564+
- The `App Protect policy </nginx-ingress-controller/app-protect/configuration/#app-protect-policies/>`_ of the WAF. Accepts an optional namespace.
565+
- ``string``
566+
- No
567+
* - ``securityLog.enable``
568+
- Enables security log.
569+
- ``bool``
570+
- No
38BA 571+
* - ``securityLog.apLogConf``
572+
- The `App Protect log conf </nginx-ingress-controller/app-protect/configuration/#app-protect-logs>`_ resource. Accepts an optional namespace.
573+
- ``string``
574+
- No
575+
* - ``securityLog.logDest``
576+
- The log destination for the security log. Accepted variables are ``syslog:server=<ip-address | localhost>:<port>``, ``stderr``, ``<absolute path to file>``. Default is ``"syslog:server=127.0.0.1:514"``.
577+
- ``string``
578+
- No
579+
```
580+
581+
#### WAF Merging Behavior
582+
583+
A VirtualServer/VirtualServerRoute can reference multiple WAF policies. However, only one can be applied. Every subsequent reference will be ignored. For example, here we reference two policies:
584+
```yaml
585+
policies:
586+
- name: waf-policy-one
587+
- name: waf-policy-two
588+
```
589+
In this example the Ingress Controller will use the configuration from the first policy reference `waf-policy-one`, and ignores `waf-policy-two`.
590+
524591
### Applying Policies
525592

526593
You can apply policies to both VirtualServer and VirtualServerRoute resources. For example:
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# WAF
2+
3+
In this example we deploy the NGINX Plus Ingress controller with [NGINX App Protect](https://www.nginx.com/products/nginx-app-protect/), a simple web application and then configure load balancing and WAF protection for that application using the VirtualServer resource.
4+
5+
## Prerequisites
6+
7+
1. Follow the installation [instructions](../../docs/installation.md) to deploy the Ingress controller with NGINX App Protect.
8+
1. Save the public IP address of the Ingress controller into a shell variable:
9+
```
10+
$ IC_IP=XXX.YYY.ZZZ.III
11+
```
12+
1. Save the HTTPS port of the Ingress controller into a shell variable:
13+
```
14+
$ IC_HTTPS_PORT=<port number>
15+
```
16+
17+
## Step 1. Deploy a Web Application
18+
19+
Create the application deployment and service:
20+
```
21+
$ kubectl apply -f webapp.yaml
22+
```
23+
24+
## Step 2 - Deploy the AP Policy
25+
26+
1. Create the syslog service and pod for the App Protect security logs:
27+
```
28+
$ kubectl apply -f syslog.yaml
29+
```
30+
1. Create the App Protect policy, log configuration and user defined signature:
31+
```
32+
$ kubectl apply -f ap-dataguard-alarm-policy.yaml
33+
$ kubectl apply -f ap-logconf.yaml
34+
$ kubectl apply -f ap-apple-uds.yaml
35+
```
36+
37+
## Step 3 - Configure Load Balancing
38+
39+
Update the `logDest` field from `virtualserver.yaml` with the ClusterIP of the syslog service. For example, if the IP is `10.101.21.110`:
40+
```yaml
41+
waf:
42+
...
43+
logDest: "syslog:server=10.101.21.110:514"
44+
```
45+
46+
Create the VirtualServer Resource:
47+
```
48+
$ kubectl apply -f virtualserver.yaml
49+
```
50+
Note the App Protect configuration settings in the Policy resource. They enable WAF protection by configuring App Protect with the policy and log configuration created in the previous step.
51+
52+
## Step 4 - Test the Application
53+
54+
1. To access the application, curl the coffee and the tea services. We'll use `curl`'s `--insecure` option to turn off certificate verification of our self-signed
55+
certificate and the --resolve option to set the Host header of a request with `webapp.example.com`
56+
57+
Send a request to the application:
58+
```
59+
$ curl --resolve webapp.example.com:$IC_HTTPS_PORT:$IC_IP https://webapp.example.com:$IC_HTTPS_PORT/ --insecure
60+
Server address: 10.12.0.18:80
61+
Server name: webapp-7586895968-r26zn
62+
...
63+
```
64+
65+
Now, let's try to send a request with a suspicious URL:
66+
```
67+
$ curl --resolve webapp.example.com:$IC_HTTPS_PORT:$IC_IP "https://webapp.example.com:$IC_HTTPS_PORT/<script>" --insecure
68+
<html><head><title>Request Rejected</title></head><body>
69+
...
70+
```
71+
Lastly, let's try to send some suspicious data that matches the user defined signature.
72+
```
73+
$ curl --resolve webapp.example.com:$IC_HTTPS_PORT:$IC_IP -X POST -d "apple" "https://webapp.example.com:$IC_HTTPS_PORT/" --insecure
74+
<html><head><title>Request Rejected</title></head><body>
75+
...
76+
```
77+
As you can see, the suspicious requests were blocked by App Protect
78+
79+
1. To check the security logs in the syslog pod:
80+
```
81+
$ kubectl exec -it <SYSLOG_POD> -- cat /var/log/messages
82+
```
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
apiVersion: appprotect.f5.com/v1beta1
2+
kind: APUserSig
3+
metadata:
4+
name: apple
5+
spec:
6+
signatures:
7+
- accuracy: medium
8+
attackType:
9+
name: Brute Force Attack
10+
description: Medium accuracy user defined signature with tag (Fruits)
11+
name: Apple_medium_acc
12+
risk: medium
13+
rule: content:"apple"; nocase;
14+
signatureType: request
15+
systems:
16+
- name: Microsoft Windows
17+
- name: Unix/Linux
18+
tag: Fruits
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
apiVersion: appprotect.f5.com/v1beta1
2+
kind: APPolicy
3+
metadata:
4+
name: dataguard-alarm
5+
spec:
6+
policy:
7+
signature-requirements:
8+
- tag: Fruits
9+
signature-sets:
10+
- name: apple_sigs
11+
block: true
12+
signatureSet:
13+
filter:
14+
tagValue: Fruits
15+
tagFilter: eq
16+
applicationLanguage: utf-8
17+
blocking-settings:
18+
violations:
19+
- alarm: true
20+
block: false
21+
name: VIOL_DATA_GUARD
22+
data-guard:
23+
creditCardNumbers: true
24+
enabled: true
25+
enforcementMode: ignore-urls-in-list
26+
enforcementUrls: []
27+
lastCcnDigitsToExpose: 4
28+
lastSsnDigitsToExpose: 4
29+
maskData: true
30+
usSocialSecurityNumbers: true
31+
enforcementMode: blocking
32+
name: dataguard-alarm
33+
template:
34+
name: POLICY_TEMPLATE_NGINX_BASE
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: appprotect.f5.com/v1beta1
2+
kind: APLogConf
3+
metadata:
4+
name: logconf
5+
spec:
6+
content:
7+
format: default
8+
max_message_size: 64k
9+
max_request_size: any
10+
filter:
11+
request_type: all
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: syslog
5+
spec:
6+
replicas: 1
7+
selector:
8+
matchLabels:
9+
app: syslog
10+
template:
11+
metadata:
12+
labels:
13+
app: syslog
14+
spec:
15+
containers:
16+
- name: syslog
17+
image: balabit/syslog-ng:3.28.1
18+
ports:
19+
- containerPort: 514
20+
- containerPort: 601
21+
---
22+
apiVersion: v1
23+
kind: Service
24+
metadata:
25+
name: syslog-svc
26+
spec:
27+
ports:
28+
- port: 514
29+
targetPort: 514
30+
protocol: TCP
31+
selector:
32+
app: syslog
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
apiVersion: k8s.nginx.org/v1
2+
kind: VirtualServer
3+
metadata:
4+
name: webapp
5+
spec:
6+
host: webapp.example.com
7+
policies:
8+
- name: waf-policy
9+
upstreams:
10+
- name: webapp
11+
service: webapp-svc
12+
port: 80
13+
routes:
14+
- path: /
15+
action:
16+
pass: webapp
17+
policies:
18+
- name: waf-policy
0 commit comments
Comments
 (0)
0