[Kubernetes (K8S) Kind] Use Homebrew (brew) to install Kind Kubernetes (K8S) cluster on macOS

Ingress Nginx with ModSecurity

ModSecurity, sometimes called Modsec, is an open-source web application firewall (WAF). Originally designed as a module for the Apache HTTP Server, it has evolved to provide an array of Hypertext Transfer Protocol request and response filtering capabilities along with other security features across a number of different platforms including Apache HTTP Server,[1][2] Microsoft IIS and Nginx.[3] It is a free software released under the Apache license 2.0.

ibmodsecurity is one component of the ModSecurity v3 project. The library codebase serves as an interface to ModSecurity Connectors taking in web traffic and applying traditional ModSecurity processing. In general, it provides the capability to load/interpret rules written in the ModSecurity SecRules format and apply them to HTTP content provided by your application via Connectors.

Prerequisites

  • Kubernetes (K8S)

    Kubernetes (K8s) is an open-source system for automating deployment, scaling, and management of containerized applications.

    For more information about installing and using Kubernetes (K8s), see the Kubernetes (K8s) Docs.

  • Helm

    Helm is the best way to find, share, and use software built for Kubernetes.

    1
    2
    # Mac OS X
    $ brew install helm

    For more information about installing and using Helm, see the Helm Docs.

  • NGINX Ingress Controller

    ingress-nginx is an Ingress controller for Kubernetes using NGINX as a reverse proxy and load balancer.

    See [Installation Guide - NGINX Ingress Controller - https://kubernetes.github.io/ingress-nginx/deploy/] to learn more.

Option 1 Enable ModSecurity via Ingress Nginx

First, enables ModSecurity functionality within Ingress Nginx.

1
2
3
4
5
6
7
8
9
10
11
12
# values.yaml

controller:
config:

# ModSecurity Web Application Firewall - NGINX Ingress Controller
# https://kubernetes.github.io/ingress-nginx/user-guide/third-party-addons/modsecurity/

# Enables ModSecurity functionality
enable-modsecurity: 'true'
# Enables loading the core rule set (optional, can be enabled on specific ingresses only instead)
enable-owasp-modsecurity-crs: 'true'

Install or upgrade Ingress Nginx:

1
2
3
$ helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --values values.yaml

Then, apply these annotations on your ingress to make

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Ingress.yaml

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:

# ModSecurity with ingress-nginx
nginx.ingress.kubernetes.io/modsecurity-transaction-id: "$request_id"
nginx.ingress.kubernetes.io/modsecurity-snippet: |
# SecRuleEngine On

# SecRuleEngine Off

# SecRuleEngine DetectionOnly

SecRuleRemoveById 920350
# Or
# SecRuleRemoveByMsg "Host header is a numeric IP address"
...
  • Option 2. Enable ModSecurity via Ingress

Enable ModSecurity for just some ingress by using the following annotations:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Ingress.yaml

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:

# ModSecurity with ingress-nginx
nginx.ingress.kubernetes.io/enable-modsecurity: "true"
nginx.ingress.kubernetes.io/enable-owasp-core-rules: "true"
nginx.ingress.kubernetes.io/modsecurity-transaction-id: "$request_id"
nginx.ingress.kubernetes.io/modsecurity-snippet: |
# SecRuleEngine On

# SecRuleEngine Off

# SecRuleEngine DetectionOnly

# [Core Rule Set Inventory – Welcome to netnea - https://www.netnea.com/cms/core-rule-set-inventory/](https://www.netnea.com/cms/core-rule-set-inventory/)
SecRuleRemoveById 920350
# Or
# SecRuleRemoveByMsg "Host header is a numeric IP address"
...

I’d recommend first running ModSecurity on a staging or test environment, and running your test sets against this. You may need to disable some rules for your application to work properly with ModSecurity enabled. For example:

1
2
3
4
5
6
nginx.ingress.kubernetes.io/modsecurity-snippet: |

# [Core Rule Set Inventory – Welcome to netnea - https://www.netnea.com/cms/core-rule-set-inventory/](https://www.netnea.com/cms/core-rule-set-inventory/)
SecRuleRemoveById 920350
# Or
# SecRuleRemoveByMsg "Host header is a numeric IP address"

When a request is blocked, you will see a log event detailing which rule was triggered:

1
[error] 574#574: *378 [client 0.0.0.0] ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `30' ) [file "/etc/nginx/owasp-modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "80"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 30)"] [data ""] [severity "2"] [ver "OWASP_CRS/3.3.0"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-generic"] [hostname "10.233.96.247"] [uri "/"] [unique_id "162773426746.083102"] [ref ""], client: 0.0.0.0, server: example.containerinfra.com, request: "GET /?path=..%2F..%2Fdrop%20table;&orgId=3 HTTP/2.0", host: "example.containerinfra.com"

Note the ID 949110 in the log message. You can disable this rule by using the modsecurity-snippet annotation:

1
2
3
4
5
nginx.ingress.kubernetes.io/modsecurity-snippet: |
SecRuleEngine On

# [Core Rule Set Inventory – Welcome to netnea - https://www.netnea.com/cms/core-rule-set-inventory/](https://www.netnea.com/cms/core-rule-set-inventory/)
SecRuleRemoveById 949110

Disable Audit Engine

By default Ingress Nginx and ModSecurity log audit events in /var/log/audit. You will find each request that triggered a rule present there. This may end up eating disk space, and while useful for debugging purpose, you may wish to disable this.

You can configure the following setting:

1
2
modsecurity-snippet: |
SecAuditEngine Off

Mount modsecurity.conf from ConfigMap

Export modsecurity.conf from ingress nginx controller

1
2
3
$ POD_NAME=$(kubectl get pods --namespace ingress-nginx -l "app.kubernetes.io/component=controller,app.kubernetes.io/name=ingress-nginx" -o jsonpath="{.items[0].metadata.name}")

$ kubectl exec -it $POD_NAME -n ingress-nginx -- cat /etc/nginx/modsecurity/modsecurity.conf > modsecurity.conf

Change modsecurity.conf configuration to support JSON and serial log

1
2
3
4
5
6
7
Change configuration to support JSON and serial log
# SecAuditLogType Concurrent
# SecAuditLog /var/log/modsec_audit.log

SecAuditLogType Serial
SecAuditLog /dev/stdout
SecAuditLogFormat JSON

Create a configmap to use customized modsecurity.conf settings

1
$ kubectl create configmap modsecurity --from-file=modsecurity.conf=modsecurity.conf -n=ingress-nginx

Update ingress nginx helm values

1
2
3
4
5
6
7
8
9
10
11
12
extraVolumeMounts:
## Additional volumeMounts to the controller main container.
- name: modsecurity
mountPath: /etc/nginx/modsecurity/modsecurity.conf
subPath: modsecurity.conf
readOnly: true

extraVolumes:
## Additional volumes to the controller pod.
- name: modsecurity
configMap:
name: modsecurity
1
$ helm upgrade <name> ingress-nginx/ingress-nginx -n ingress-nginx -f nginx_values.yaml

References

[1] ModSecurity with ingress-nginx | ContainerInfra - https://containerinfra.com/blog/cloud/2021-07-30-using-nginx-ingress-waf/

[2] ModSecurity Web Application Firewall - NGINX Ingress Controller - https://kubernetes.github.io/ingress-nginx/user-guide/third-party-addons/modsecurity/

[3] SpiderLabs/ModSecurity-nginx: ModSecurity v3 Nginx Connector - https://github.com/SpiderLabs/ModSecurity-nginx

[4] OWASP Foundation | Open Source Foundation for Application Security - https://owasp.org/

[5] OWASP ModSecurity Core Rule Set - https://owasp.org/www-project-modsecurity-core-rule-set/

[6] Enable WAF with Modsecurity from Ingress Nginx - https://msazure.club/enable-waf/

[7] Kubernetes Nginx Ingress Controller WAF with ModSecurity | by Jorge Guerrero | Medium - https://medium.com/@jorge.guerrero/kubernetes-nginx-ingress-controller-waf-with-modsecurity-6add37840e3b

[8] Core Rule Set Inventory – Welcome to netnea - https://www.netnea.com/cms/core-rule-set-inventory/

[9] Welcome - NGINX Ingress Controller - https://kubernetes.github.io/ingress-nginx/