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"If you want to adjust the Paranoia level or the Anomaly Score threshold, you’ll need to edit rules 900000 and 900110.
Paranoia levels control how strict the ruleset is. The higher the level, the more aggressive the checks. The anomaly threshold works the other way around: raise it, and the system becomes more forgiving; lower it and the system starts flagging and blocking more.
That’s the trade-off. Stricter rules catch more, but they also increase false positives. A higher threshold reduces noise, but you might let more slip through.
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.confCustomize 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
You can add custom configuration to ModSecurity with the modsecurity-snippet option. 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.confModify it as required and save the file in a ConfigMap.
kubectl -n ingress-nginx create configmap modsecurityconf --from-file=modsecurity.confIf 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: trueAnd then apply the patch file.
kubectl -n ingress-nginx patch deployment/ingress-nginx-controller --patch-file deployment-patch.ymlFurther reading
ConfigMap options for Ingress Nginx
Annotations options for Ingress objects
Handling False Positives with the OWASP ModSecurity Core Rule Set