Security

ModSecurity WAF

ModSecurity is a popular, open-source Web Application Firewall. In this section, you will learn how to manage ModSecurity in HAProxy Enterprise Kubernetes Ingress Controller to protect your container-based apps.

Enable ModSecurity for all Ingress routes Jump to heading

To enable ModSecurity with the Core Rule Set for all routes handled by the ingress controller:

  1. Download the latest version of the source code from the ModSecurity Core Rule Set GitHub page. The Core Rule Set contains a broad set of rules for detecting suspicious HTTP requests and is a good starting point for populating ModSecurity with sensible defaults. Later, you can customize these rules.

    The source code comes archived as a zip file or a tar, gzipped file. After downloading the archive, extract the files.

  2. Inside the extracted folder, rename the file crs-setup.conf.example to crs-setup.conf.

  3. Download two files from the OWASP ModSecurity GitHub page:

    • unicode.mapping
    • modsecurity.conf-recommended (rename it to modsecurity.conf)

    You can use the following wget commands:

    nix
    wget https://raw.githubusercontent.com/owasp-modsecurity/ModSecurity/v3/master/unicode.mapping \
    -o unicode.mapping
    wget https://raw.githubusercontent.com/owasp-modsecurity/ModSecurity/v3/master/modsecurity.conf-recommended \
    -o modsecurity.conf
    nix
    wget https://raw.githubusercontent.com/owasp-modsecurity/ModSecurity/v3/master/unicode.mapping \
    -o unicode.mapping
    wget https://raw.githubusercontent.com/owasp-modsecurity/ModSecurity/v3/master/modsecurity.conf-recommended \
    -o modsecurity.conf
  4. Copy crs-setup.conf, unicode.mapping, and modsecurity.conf to the rules folder inside the Core Rule Set folder.

  5. From inside the rules folder, use the command kubectl create secret generic to add all of the files in the folder to your Kubernetes cluster as a Secret object. The Secret will be named modsecuritycrs.

    nix
    kubectl create secret generic modsecuritycrs --namespace haproxy-controller --from-file .
    nix
    kubectl create secret generic modsecuritycrs --namespace haproxy-controller --from-file .
  6. Edit the ingress controller’s ConfigMap:

    nix
    kubectl edit configmap haproxy-kubernetes-ingress --namespace haproxy-controller
    nix
    kubectl edit configmap haproxy-kubernetes-ingress --namespace haproxy-controller

    Add the modsecurity key under the data section, setting it to the namespace and name of the secret you just created. After making your changes, save and close the file.

    haproxy-kubernetes-ingress.yaml
    yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
    annotations:
    ...
    data:
    modsecurity: haproxy-controller/modsecuritycrs
    haproxy-kubernetes-ingress.yaml
    yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
    annotations:
    ...
    data:
    modsecurity: haproxy-controller/modsecuritycrs

    This will enable ModSecurity for all applications behind the ingress controller.

    By default, ModSecurity is in detection-only mode and will not block threats. See the section Enable blocking mode.

Enable ModSecurity only for a specific Ingress Jump to heading

Available since

version 1.7

To enable ModSecurity for specific Ingress rules instead of for all routes, follow these steps:

  1. Download the latest version of the source code from the ModSecurity Core Rule Set GitHub page. The Core Rule Set contains a broad set of rules for detecting suspicious HTTP requests and is a good starting point for populating ModSecurity with sensible defaults. Later, you can customize these rules.

    The source code comes archived as a zip file or a tar, gzipped file. After downloading the archive, extract the files.

  2. Inside the extracted folder, rename the file crs-setup.conf.example to crs-setup.conf.

  3. Download two files from the OWASP ModSecurity GitHub page:

    • unicode.mapping
    • modsecurity.conf-recommended (rename it to modsecurity.conf)

    You can use the following wget commands:

    nix
    wget https://raw.githubusercontent.com/owasp-modsecurity/ModSecurity/v3/master/unicode.mapping \
    -o unicode.mapping
    wget https://raw.githubusercontent.com/owasp-modsecurity/ModSecurity/v3/master/modsecurity.conf-recommended \
    -o modsecurity.conf
    nix
    wget https://raw.githubusercontent.com/owasp-modsecurity/ModSecurity/v3/master/unicode.mapping \
    -o unicode.mapping
    wget https://raw.githubusercontent.com/owasp-modsecurity/ModSecurity/v3/master/modsecurity.conf-recommended \
    -o modsecurity.conf
  4. Copy crs-setup.conf, unicode.mapping, and modsecurity.conf to the rules folder inside the Core Rule Set folder.

  5. From inside the rules folder, use the command kubectl create secret generic to add all of the files in the folder to your Kubernetes cluster as a Secret object. The Secret will be named modsecuritycrs.

    nix
    kubectl create secret generic modsecuritycrs --namespace haproxy-controller --from-file .
    nix
    kubectl create secret generic modsecuritycrs --namespace haproxy-controller --from-file .
  6. Edit your Ingress definition and add the modsecurity annotation.

    example-ingress.yaml
    yaml
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
    name: example-ingress
    annotations:
    haproxy.org/modsecurity: haproxy-controller/modsecuritycrs
    spec:
    ingressClassName: haproxy
    rules:
    - host: "example.com"
    http:
    paths:
    - path: /
    pathType: Prefix
    backend:
    service:
    name: example-service
    port:
    number: 8080
    example-ingress.yaml
    yaml
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
    name: example-ingress
    annotations:
    haproxy.org/modsecurity: haproxy-controller/modsecuritycrs
    spec:
    ingressClassName: haproxy
    rules:
    - host: "example.com"
    http:
    paths:
    - path: /
    pathType: Prefix
    backend:
    service:
    name: example-service
    port:
    number: 8080
  7. Apply the change using kubectl apply.

    nix
    kubectl apply -f example-ingress.yaml
    nix
    kubectl apply -f example-ingress.yaml

    Note that this technique allows you to set different rule sets for each Ingress resource to tailor the rules for each application.

    By default, ModSecurity is in detection-only mode and will not block threats. See the section Enable blocking mode.

Enable blocking mode Jump to heading

By default, ModSecurity is in detection-only mode and will log, but not block, suspicious requests. To enable blocking of suspicious requests:

  1. Edit the file modsecurity.conf.

  2. Change the line SecRuleEngine DetectionOnly to SecRuleEngine On.

  3. Delete and recreate the modsecuritycrs Secret.

    nix
    kubectl delete secret modsecuritycrs --namespace haproxy-controller
    kubectl create secret generic modsecuritycrs --namespace haproxy-controller --from-file .
    nix
    kubectl delete secret modsecuritycrs --namespace haproxy-controller
    kubectl create secret generic modsecuritycrs --namespace haproxy-controller --from-file .
  4. Test to see if the rules are working. Make a request that violates a rule and verify that the response is Forbidden. Note that in this case, the NodePort for the ingress controller service is 30000.

    nix
    curl http://localhost:30000/?load=../../../../etc/passwd
    nix
    curl http://localhost:30000/?load=../../../../etc/passwd

Do you have any suggestions on how we can improve the content of this page?