Enabling ModSecurity in the Kubernetes Ingress-NGINX Controller
Enabling ModSecurity in the Kubernetes Ingress-NGINX Controller
The Kubernetes Ingress-NGINX controller allows you to enable ModSecurity, a powerful open-source Web Application Firewall (WAF). This post will guide you through the process of enabling and configuring ModSecurity with Ingress-NGINX to protect your applications from various types of web attacks.
What is ModSecurity?
ModSecurity is a web application firewall designed to protect your applications from a range of web-based threats. With Ingress-NGINX, you can configure ModSecurity in multiple ways to meet your security needs.
There are three primary configurations for ModSecurity within Ingress-NGINX:
- Default Configuration (Detection Only)
- OWASP Core Rule Set (CRS)
- Custom Snippet
Let’s walk through these configurations.
Default Configuration
When ModSecurity is enabled without any additional rules or custom configurations, it runs in Detection Only Mode. This non-disruptive mode allows you to monitor traffic without affecting the behavior of your applications. It’s recommended to run in this mode initially, analyze the generated logs, and fine-tune the rules accordingly.
By default, ModSecurity comes with basic rules, which you can modify to suit your application needs.
OWASP Core Rule Set (CRS)
The OWASP Core Rule Set (CRS) is a set of widely used generic security rules designed to protect against the OWASP Top 10 vulnerabilities, such as:
- SQL Injection (SQLi)
- Cross-Site Scripting (XSS)
- Local File Inclusion (LFI)
- Remote File Inclusion (RFI)
- Remote Code Execution (RCE)
- Session Fixation
- Scanner Detection
- Metadata/Error Leakages
The CRS is highly documented and customizable, making it a robust solution for general-purpose web application security.
Custom Snippet
A ModSecurity Snippet allows you to define custom security rules and directives tailored to your application. You can either create all custom rules within the snippet (though this can become challenging to maintain) or build a custom Ingress-NGINX image with pre-configured ModSecurity settings.
For complex setups, building a custom image is often the best approach. However, this tutorial will focus on using snippets for easier integration.
Setting Up ModSecurity with Ingress-NGINX
Before diving into the ModSecurity configuration, ensure that your Ingress-NGINX controller is properly set up. If you already have it running on your Kubernetes cluster, you can skip the setup step. Otherwise, refer to the official documentation to deploy the Ingress-NGINX controller.
Deploying an Application with ModSecurity Enabled
Create a Deployment
First, let’s deploy an application to test the ModSecurity configuration. In this example, we’ll deploy a simple echo server.
echo " apiVersion: apps/v1 kind: Deployment metadata: name: meow spec: replicas: 2 selector: matchLabels: app: meow template: metadata: labels: app: meow spec: containers: - name: meow image: gcr.io/kubernetes-e2e-test-images/echoserver:2.1 ports: - containerPort: 8080 " | kubectl apply -f -
Verify the deployment:
kubectl get deploy kubectl get pods
Expose the Application
Next, expose the deployment via a Kubernetes Service:
echo " apiVersion: v1 kind: Service metadata: name: meow-svc spec: ports: - port: 80 targetPort: 8080 protocol: TCP selector: app: meow " | kubectl apply -f -
Verify the service is created:
kubectl get svc
Create an Ingress Rule with ModSecurity Enabled
Now, create an Ingress resource to route traffic to your application and enable ModSecurity with a custom snippet:
echo " apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/enable-modsecurity: 'true' nginx.ingress.kubernetes.io/modsecurity-snippet: | SecRuleEngine On SecRequestBodyAccess On SecAuditEngine RelevantOnly SecAuditLogParts ABIJDEFHZ SecAuditLog /var/log/modsec_audit.log SecRule REQUEST_HEADERS:User-Agent 'bad-scanner' 'log,deny,status:403,msg:\'Scanner Detected\'' name: meow-ingress spec: rules: - http: paths: - path: /meow pathType: Prefix backend: service: name: meow-svc port: number: 80 " | kubectl apply -f -
Verify the Ingress resource:
kubectl get ing
Testing the ModSecurity Setup
With ModSecurity enabled, you can now test the firewall’s effectiveness.
Send a Normal Request
Get the Minikube IP and test a normal request to the application:
minikube ip curl https://<minikube-ip>/meow -k
Send a Request with a Forbidden User-Agent
Now, test with a User-Agent string that triggers the custom ModSecurity rule:
curl https://<minikube-ip>/meow -k -H "User-Agent: bad-scanner"
You should receive a 403 Forbidden response.
Reviewing Logs
To view ModSecurity logs and verify that the firewall is working as expected, check the logs of the NGINX Ingress controller:
kubectl logs -n kube-system <nginx-ingress-controller-pod>
kubectl exec -it -n kube-system <nginx-ingress-controller-pod> cat /var/log/modsec_audit.log
Troubleshooting
If ModSecurity doesn’t behave as expected or causes issues, examine the logs and NGINX configuration:
kubectl logs -n kube-system <nginx-ingress-controller-pod>
kubectl exec -it -n kube-system <nginx-ingress-controller-pod> cat /etc/nginx/nginx.conf