Web Application Firewall is an additional layer of security for your services and now we are going to implement it on practice.
Let’s start with installing nginx ingress controller.
There are two ways to install the Nginx ingress controller: using helm or creating Kubernetes resources using kubectl.
helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespaceor
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.2/deploy/static/provider/cloud/deploy.yaml
We will create an ingress resource and a simple web server.
kubectl create deployment modsecurity --image=httpd --port=80
kubectl expose deployment modsecurity
kubectl create ingress ingress-localhost --class=nginx \
--rule='modsecurity/*=modsecurity:80'To access the k8s application, we need to add a record to the /etc/hosts file.
127.0.0.1 modsecurityIt is important to keep the tunnel to the ingress pod up for all subsequent actions.
kubectl port-forward --namespace=ingress-nginx service/ingress-nginx-controller 8080:80To test our environment, we need to enable ModSecurity by editing the ingress ConfigMap and adding an excerpt in the data key.
kubectl edit configmaps --namespace ingress-nginx ingress-nginx-controllerdata:
allow-snippet-annotations: "true"
enable-modsecurity: "true"
enable-owasp-modsecurity-crs: "true"Now let’s check if everything is ok
kubectl logs -f --namespace ingress-nginx \
--selector=app.kubernetes.io/component=controllerNow, let’s enable ModSecurity and The OWASP ModSecurity Core Rule Set.
data:
allow-snippet-annotations: "true"
enable-modsecurity: "true"
enable-owasp-modsecurity-crs: "true"
modsecurity-snippet: |-
SecRuleEngine On
SecRequestBodyAccess Onand test it
curl 'http://modsecurity:8080/?param="><script>alert(1);</script>'The output should be something like this
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx</center>
</body>
</html>ModSecurity rules have the following syntax:
SecRule VARIABLES OPERATOR [ACTIONS]data:
allow-snippet-annotations: "true"
enable-modsecurity: "true"
enable-owasp-modsecurity-crs: "true"
modsecurity-snippet: |-
SecRuleEngine On
SecRequestBodyAccess On
SecRule ARGS|ARGS_NAMES "\.classLoader\." "log,\
deny,\
phase:2,\
id:76000001,\
severity:CRITICAL,\
msg:\'Possible Spring4Shell exploitation\'"That request that will help us to block possible Spring4Shell exploit by a rule in the OWASP ModSecurity Core Rule Set.
Completely disable a rule
Sometimes, you have no choice but to disable a rule. Given a rule id, you can fully disable it with the directive:
SecRuleRemoveById RULE_ID modsecurity-snippet: |-
SecRuleEngine On
SecRequestBodyAccess On
SecRule ARGS|ARGS_NAMES "\.classLoader\." "log,\
deny,\
phase:2,\
id:76000001,\
severity:CRITICAL,\
msg:\'Possible Spring4Shell exploitation\'"
SecRuleRemoveById 949110Instead of completely turning off a rule, you can opt for a more specific and flexible approach. For instance, you may disable a rule for certain scenarios such as request paths or parameters. To illustrate, you can disable rule 932160 for the /login request by using the config below:
modsecurity-snippet: | SecRule REQUEST_FILENAME "@streq /login" \ "phase:1,nolog,pass,id:15000,ctl:ruleRemoveById=932160"
