Using ModSecurity to protect your endpoints in Kubernetes

Making use of ModSecurity WAF to protect your API endpoints running behind any ingress controller or API Gateway deployment

kubernetes security
2025-01-02
Thomas Kooi

What is ModSecurity?

ModSecurity is an open-source, cross-platform web application firewall (WAF) engine that provides a robust security layer for your web applications. Initially developed for Apache, ModSecurity now supports IIS and Nginx, offering flexible and powerful protection against various web-based attacks. It acts as an intrusion detection and prevention engine, analyzing HTTP traffic and blocking malicious requests before they reach your application.

Originally developed and sponsored by Trustwave, it has been transfered to the OWASP foundation earlier this year.

Why a WAF is valuable

Web Application Firewalls (WAFs) like ModSecurity provide a crucial security layer for protecting web applications from various threats. Here’s why implementing a WAF is valuable for your organization:

1. Protection Against Common Threats

A WAF can effectively block common web application attacks such as SQL injection, cross-site scripting (XSS), and cross-site request forgery (CSRF). By using predefined rule sets like the OWASP Core Rule Set (CRS), ModSecurity can detect and mitigate these vulnerabilities before they compromise your application.

2. Real-Time Threat Detection and Prevention

A WAF operates in real-time, providing immediate protection against attacks. ModSecurity continuously monitors traffic and can block threats as they occur, preventing malicious actors from exploiting vulnerabilities in your web applications.

3. Enhanced Visibility and Logging

ModSecurity provides detailed logging and monitoring capabilities, giving you greater visibility into the types of attacks targeting your web applications. This information is valuable for forensic analysis, helping you understand attack patterns and improve your overall security strategy.

Utilise a Defense in depth strategy

While a WAF provides a valuable security layer, it’s deployment should be part of a defence in depth strategy. There exists various best-practices and solutions to fully protect against common vulnerabilities such as the OWASP top 10 within your Software. Solutions like input validation, prepared statements must be implemented in the systems protected by a WAF.

Understanding ModSecurity CRS

The OWASP Core Rule Set (CRS) is a set of rules for ModSecurity and similar web application firewalls. It detects and mitigates common web threats like SQL injection and cross-site scripting (XSS). Using CRS with ModSecurity strengthens your web application’s security by addressing key vulnerabilities from the OWASP Top 10 list.

Deploying ModSecurity within Kubernetes

In this blog post, we’ll deploy a ModSecurity container alongside a demo echo deployment using the modsecurity-crs-docker image. This will act as our example API in our Kubernetes environment. We will go over the various actions you need to perform to configure the deployment in order to protect your endpoint(s).

ModSecurity Deployment as a proxy

Proxy Strategy for ModSecurity

ModSecurity Deployment as a proxy

Forward authentication strategy for ModSecurity

Preparation

Deployment of our demo API backend in Kubernetes

We will be deploying everything in the modsecurity namespace. You can create this using the command below:

kubectl create namespace modsecurity

Next, we will deploy our backend service:

kubectl -n modsecurity create deployment --image ealen/echo-server:0.9.2 backend;
kubectl -n modsecurity expose deploy/backend --port 80 --type=ClusterIP;

The ModSecurity Proxy deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: modsecurity-waf
  namespace: modsecurity
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: modsecurity
  template:
    metadata:
      labels:
        app.kubernetes.io/name: modsecurity
    spec:
      containers:
      - name: waf
        image: owasp/modsecurity-crs:4.5.0-nginx-alpine-202407300107
        imagePullPolicy: IfNotPresent
        env:
        - name: BACKEND
          value: http://backend.modsecurity.svc.cluster.local:80
        - name: DNS_SERVER
          value: '192.168.194.138'
        - name: ALLOWED_REQUEST_CONTENT_TYPE
          value: 'application/json'
        - name: ALLOWED_HTTP_VERSIONS
          value: 'HTTP/2'
        - name: ALLOWED_METHODS
          value: 'GET POST PUT PATCH HEAD DELETE OPTIONS'
        ports:
        - containerPort: 8080

Configuring the DNS server

For the ModSecurity WAF deployment to be able to properly find the backend application, it’s important to configure the DNS_SERVER. Due to how nginx works, it will not automatically pick-up the DNS resolver from the cluster. Luckily it’s pretty easy to find the correct IP addres for this using the following command:

kubectl get svc -n kube-system kube-dns -o jsonpath='{.spec.clusterIP}'

This will work in most clusters. In certain deployments, the kube-dns service may be called differently. An alternative command which may work could be:

kubectl get cm -n kube-system -o jsonpath='{.data.clusterDNS}' cluster-dns

Full Example

apiVersion: v1
kind: Namespace
metadata:
  name: modsecurity
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: modsecurity-waf
  namespace: modsecurity
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: modsecurity
  template:
    metadata:
      labels:
        app.kubernetes.io/name: modsecurity
    spec:
      containers:
      - name: waf
        image: owasp/modsecurity-crs:4.5.0-nginx-alpine-202407300107
        imagePullPolicy: IfNotPresent
        env:
        - name: BACKEND
          value: http://nginx-backend.modsecurity.svc.cluster.local:80
        - name: DNS_SERVER
          value: '192.168.194.138'
        - name: ALLOWED_REQUEST_CONTENT_TYPE
          value: 'application/json'
        - name: ALLOWED_HTTP_VERSIONS
          value: 'HTTP/2'
        - name: ALLOWED_METHODS
          value: 'GET POST PUT PATCH HEAD DELETE OPTIONS'
        ports:
        - containerPort: 8080
        resources: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-backend
  namespace: modsecurity
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      automountServiceAccountToken: false
      enableServiceLinks: false

      containers:
      - name: nginx
        # image: nginx
        image: ealen/echo-server:0.9.2
        resources: {}
        ports:
        - containerPort: 80
          name: http
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-backend
  namespace: modsecurity
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
---

Best Practices for ModSecurity Deployment

  1. Integrate into CI/CD: Include ModSecurity in your automated integration and acceptance tests to ensure your system continues to function correctly when deploying the WAF in front of your API.
  2. Continuous Monitoring: Regularly review logs and alerts generated by ModSecurity to stay ahead of potential threats and fine-tune rules as needed.
  3. Regular Updates: Keep ModSecurity and CRS updated to benefit from the latest security enhancements and protection against new vulnerabilities.

By following these steps and best practices, you can effectively enhance the security of your API using ModSecurity and OWASP CRS, protecting your applications from a wide range of web-based threats.

Testing the real-time threat detection

Just like with any software components, testing the threat detection from ModSecurity is a must to ensure that the WAF is blocking malicious traffic correctly. You can use curl to simulate attacks and see how ModSecurity reacts.

First, forward the pod’s ports using kubectl:

kubectl port-forward deploy/modsecurity-waf 8080

Try this command to simulate an SQL injection:

curl "http://localhost:8080?do='drop%20table'"

Here’s what happens:

  1. Simulated Attack: The command sends a request that looks like a common SQL injection, using the payload drop table.
  2. Request Blocked: ModSecurity detects this as a threat and blocks the request. It won’t reach your application.
  3. Response Message: You’ll likely see an HTTP 403 Forbidden response or a similar message showing the request was denied.

To confirm what happened, check the logs from the ModSecurity pod:

kubectl logs <modsecurity-pod-name> -n <namespace>

Getting insights

To understand how ModSecurity is working and what threats it is detecting, you can analyze the log events generated by the gateway deployment. These logs contain detailed information about blocked and allowed requests, making it easier to monitor activity and fine-tune your rules.

Logs from the ModSecurity gateway deployment are usually stored as JSON events, providing structured and readable data. To access these logs, use the following command:

kubectl logs <modsecurity-pod-name> -n <namespace>

Replace <modsecurity-pod-name> and <namespace> with the actual names of your ModSecurity pod and namespace.

Output of th logs is in JSON. For example for the previous test, we can see the message about what happened:

{
    ...
    "messages": [{
        "message":"Detects concatenated basic SQL injection and SQLLFI attempts", 
        ..
    }]
}

Grafana dashboard

By collecting the JSON log events generated by ModSecurity, you can create a Grafana dashboard to gain real-time insights into ModSecurity activity. This dashboard helps you monitor threats, blocked requests, and overall WAF performance.

Grafana dashboard for ModSecurity

Using a dashboards provides real-time threat monitoring, allowing you to quickly identify patterns and spikes in malicious activity. It delivers actionable insights by highlighting the most common attack vectors, enabling you to fine-tune ModSecurity rules for better protection. Additionally, it enhances visibility by giving your team a clear overview of ModSecurity’s performance and effectiveness within your environment.

Conclusion

In this post, we covered how to deploy a ModSecurity container in your Kubernetes environment to protect a backend endpoint. We explored how to expose activity logs and gain real-time insights into security events and scanners probing your endpoints. ModSecurity can be run as a proxy service or integrated with forward authentication on ingress controllers like nginx or Traefik to secure all endpoints.

While ModSecurity is a powerful tool for defense in depth, it should complement, not replace, strong security practices. Focus on secure development, hardened configurations, network policies, runtime protection, and strong authentication for a robust Kubernetes security strategy. By combining these measures, you can build a layered and effective defense for your applications.



Related Tags:
#kubernetes #security
7 min read
Share this post:

Related posts