Kubernetes NGINX WAF (Part 1) - Ingress Hardening with Mod_Security and OWASP CRS
How to increase the security of your Kubernetes ingress with a web application firewall (mod_security) and the OWASP Core Rule Set.
“Kubernetes Ingress with mod_security and OWASP” – We show what all this means in today’s blog post.
In today’s blog post, we’ll show you a way to keep malicious traffic off your Kubernetes cluster. We grab a topic from the technical magic box of the “Zero Trust” and immediately disenchant the technical jargon.
The goal is to setup Nginx Ingress and WAF properly in order to protect all web services
opensight.ch – roman hüsler
Mod_Security is an open source web application firewall (WAF) that is supported by various web servers (NGINX, Apache, IIS) and has existed since 2002. The OWASP organization provides a corresponding Core Rule Set (CRS) for the firewall, which keeps all kinds of malicious traffic out.
Terms
Kubernetes (also “K8s”) is an open source contrainducer orchestration engine originally developed by Google.
Here is an example of a simplified reference architecture, which is often found in a similar form – with deviations depending on the cloud provider. Incoming traffic is first routed via a load balancer (in our bare metal test cluster “MetalLB”) to one of the two Kubernetes nodes shown. An “NGINX Ingress Controller” ensures that an NGINX service (container) is run on each Kubernetes node, which acts as SSL termination and reverse proxy and then ultimately forwards the traffic to the correct container via a so-called “Kubernetes Service”. The web services / micro services are executed on the container. These micro services make sensitive data available and we therefore do not want to expose them to unfiltered web traffic – zero trust.
We would therefore like to start today with the NGINX service (in green) and examine the incoming traffic using a Web Application Firewall (WAF) in order to increase general security in the cluster. We are using the open source WAF called “mod_security” and will be using the Open Web Application Security Project (OWASP) Core Ruleset (CRS) against which we will inspect incoming traffic.
Incidentally, in the case of Microsoft Azure, the “Azure Web Application Firewall” service is offered, which is also based on the OWASP rulesets described in this blog. The pricing of the Azure Service can be found on the linked website.
Open Web Application Security Project (OWASP)
The OWASP ModSecurity Core Rule Set (CRS) is a freely accessible collection of “Detection Rules” – i.e. rules that can be used to examine incoming traffic. These rules can then be used in combination with a compatible web application firewall such as Mod_Security.
The “Core Rule Set” was developed with the aim of protecting web applications from a wide range of known attacks, including the “OWASP Top Ten“. This is a top 10 list of the most frequently occurring security risks and security gaps in web applications, which is redefined every 3 years.
The core rule set currently contains rules that protect our web services from the following risks:
- SQL Injection (SQLi)
- Cross Site Scripting (XSS)
- Local File Inclusion (LFI)
- Remote File Inclusion (RFI)
- PHP Code Injection
- Java Code Injection HTTPoxy
- Shellshock
- Unix/Windows Shell Injection
- Session Fixation
- Scripting/Scanner/Bot Detection
- Metadata/Error Leakages
Houston, we have a problem
First of all, as a test, we send an HTTP request to one of our test web services. We design the request in such a way that it clearly looks like an SQL injection attack. You can also test this yourself with one of your own existing web services – we’ll just pretend that our micro service has a “users” endpoint and send an example SQL injection (“ExampleSQLInjection’–“). For this we use the well-known tool “Postman”. As you can see, we get a Swagger document from the Micro Service in response – so the traffic was sent unfiltered to the Micro Service – Houston, we have a problem.
Beam me up, Scotty
To increase security, we are now making a few changes to the NGINX ingress controller in Kubernetes.
We edit the config map of our NGINX Ingress Controller in Kubernetes and activate “mod_security”, as well as the OWASP CRS (Open Web Application Security Project – Core Rule Set). According to the documentation, with the help of the “modsecurity-snippet” line, we can write a few lines in the nginx.conf (“modsecurity_rule”) so that the engine is actually activated. (By default, the engine otherwise only runs in “DetectionOnly” mode).
PS: If desired, you can also define your own Mod_Security Rules in the ConfigMap, such as whitelisting an IP address you know: “SecRule REMOTE_ADDR “@streq 192.168.254.1” \allow,phase:1,nolog” or deactivate existing rules .
If we now connect to one of our NGINX Ingress Controller Pods in Kubernetes, we will find the core rule set under “/etc/nginx/owasp-modsecurity-crs” (here the corresponding GIT repository). In the nginx.conf we see that the corresponding config file has also been included:
...
modsecurity_rules_file /etc/nginx/owasp-modsecurity-crs/nginx-modsecurity.conf;
...
That looks good – now let’s run the above test again with Postman.
The traffic to the web service has now already been stopped by NGINX Ingress and Mod_Security – beautiful!
If we check the Mod_Security log file, we see that the request was blocked because an SQL injection was detected according to rule “942100” from the CRS (REQUEST-942-APPLICATION-ATTACK-SQLI.conf).
That was the basic config of the Kubernetes NGINX Ingress Controller. More configurations for Log Ingestion into Elasticsearch and Dashboard Creation in our next post.