June 26, 2022 (updated at: February 03, 2024)
Protect public URLs with ModSecurity for Nginx on a Kubernetes cluster
If you’re using Ingress Nginx to manage public endpoints, ModSecurity is already installed but disabled by default. To enable it, add the following to the ConfigMap ingress-nginx-controller
:
allow-snippet-annotations: "true"
enable-modsecurity: "true"
enable-owasp-modsecurity-crs: "true"
To customize the Paranoia and Anomaly Score threshold, you must change rules 900000 and 900110. But remember that higher Paranoia levels lead to stricter rules, and a lower anomaly threshold leads to a more tolerant setup.
modsecurity-snippet: |-
SecRuleEngine On
SecAuditEngine Off # Use RelevantOnly for debugging
SecAuditLog /dev/stdout
SecAuditLogFormat JSON
SecAuditLogType Serial
SecAuditLogParts ABIJDEFHZ
SecDebugLog /dev/stdout
SecDebugLogLevel 3
SecAction "id:900000,phase:1,nolog,pass,t:none,setvar:tx.paranoia_level=5"
SecAction "id:900110,phase:1,nolog,pass,t:none,setvar:tx.inbound_anomaly_score_threshold=4,setvar:tx.outbound_anomaly_score_threshold=3"
Include /etc/nginx/owasp-modsecurity-crs/nginx-modsecurity.conf
Customize ModSecurity rules on a per-host basis
It’s possible to adjust the ModSecurity configuration for each Ingress object on the cluster using annotations.
annotations:
nginx.ingress.kubernetes.io/enable-modsecurity: "true"
nginx.ingress.kubernetes.io/enable-owasp-core-rules: "false"
nginx.ingress.kubernetes.io/modsecurity-snippet: |
SecRuleRemoveById <rule_id>
How to completely customize modsecurity.conf
With the modsecurity-snippet
option, adding custom configuration to ModSecurity is possible. However, you can override the modsecurity.conf
entirely if you want.
To do so, first copy the file inside the pod.
kubectl -n ingress-nginx cp <ingress-controller-pod-name>:/etc/nginx/modsecurity/modsecurity.conf ./modsecurity.conf
Modify it as required and save the file in a ConfigMap.
kubectl -n ingress-nginx create configmap modsecurityconf --from-file=modsecurity.conf
If you need to change the file again locally, you can update the ConfigMap by doing the following.
kubectl -n ingress-nginx create configmap modsecurityconf \
--from-file=modsecurity.conf -o yaml \
--dry-run=client | kubectl apply -f -
To mount the ConfigMap to the controller deployment, create a patch file.
spec:
template:
spec:
volumes:
- name: modsecurityconf
configMap:
name: modsecurityconf
containers:
- name: controller
volumeMounts:
- name: modsecurityconf
mountPath: "/etc/nginx/modsecurity/modsecurity.conf"
subPath: modsecurity.conf
readOnly: true
And then apply the patch file.
kubectl -n ingress-nginx patch deployment/ingress-nginx-controller --patch-file deployment-patch.yml
Further reading
ConfigMap options for Ingress Nginx
Annotations options for Ingress objects
Handling False Positives with the OWASP ModSecurity Core Rule Set