WAF with ModSecurity on Linux

Maciej
9 min readMay 19, 2021
Photo by Sigmund on Unsplash

Introduction

General, when we viewed from the Internet side, the firewall is in the foreground, the IDS/IPS is in the second place, the WAF is in the third, and the Web server is finally reached. Since each layer and attack can be defended differently, it is not enough to take measures against cyber attacks because one of them is included.

Firewall protects us at the network level by restricting access based on the source/destination IP address and port number. It will be prevents port scans, but cannot handle with attacks that pretend to be normal communications, such as communications to ports 80 and 443. Some attacks that exploit vulnerabilities in IDS/IPS platforms and attacks on file sharing services are detected and defended by pattern matching based on signatures. It prevents DoS attacks, Syn flood attacks, etc., but cannot deal with attacks that utilize vulnerabilities in Web applications.

WAF it specializes in protecting web applications, and is also effective in protecting against vulnerabilities in web servers like Apache, IIS, etc. , middleware like Tomcat, etc. , languages ​​like PHP, JavaScript, etc. . It inspects the content of communication HTTP/HTTPS between the access source and the Web server, detects attacks based on signatures, and protects against them. It also checks with a white list, checks the validity of screen transitions, and protects hidden parameters and cookies. Prevents attacks such as SQL injection, cross-site scripting, OS command injection, password list attacks, and parameter tampering.

We can classified WAF into 3 types according to the installation type:

Network type WAF

  • WAF is placed as a network device
  • Are appliance products or offered as software
  • Are placed as reverse proxy or bridge
  • Cost performance depends on the number of servers. If there are many of them, the price will be high

Hosted type WAF

  • WAF that is installed as software on a Web server
  • WAFs provided as Apache modules include the open source ModSecurity
  • Hosted WAFs have the advantage of having almost no latency because the number of network devices does not increase
  • Cost is often low
  • Since it is installed for each Web server, the cost may increase when the number of servers is large

SaaS type WAF

  • Provided as SaaS
  • It provides a network type WAF usually reverse proxy as a shared service
  • The feature is that the initial investment can be suppressed and the operational load is low

Test Environment

Let’s start

Add an epel repository which is needed to install ModSecurity.

[root@localhost vagrant]# yum install epel-release
Loaded plugins: fastestmirror
Determining fastest mirrors
* base: ftp.ps.pl
* extras: centos2.hti.pl
* updates: centos2.hti.pl
base | 3.6 kB 00:00:00
extras | 2.9 kB 00:00:00
updates | 2.9 kB 00:00:00
(1/4): base/7/x86_64/group_gz | 153 kB 00:00:00
(2/4): extras/7/x86_64/primary_db | 236 kB 00:00:00
(3/4): base/7/x86_64/primary_db | 6.1 MB 00:00:01
(4/4): updates/7/x86_64/primary_db | 8.0 MB 00:00:02
Resolving Dependencies
--> Running transaction check
---> Package epel-release.noarch 0:7-11 will be installed
--> Finished Dependency Resolution
Dependencies Resolved================================================================================================================================================================
Package Arch Version Repository Size
================================================================================================================================================================
Installing:
epel-release noarch 7-11 extras 15 k
Transaction Summary
================================================================================================================================================================
Install 1 Package
Total download size: 15 k
Installed size: 24 k
Is this ok [y/d/N]: y
Downloading packages:
epel-release-7-11.noarch.rpm | 15 kB 00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : epel-release-7-11.noarch 1/1
Verifying : epel-release-7-11.noarch 1/1
Installed:
epel-release.noarch 0:7-11
Complete!

Now we can Install following packages

  • mod_security: ModSecurity
  • mod_security_crs: Core Rule Set

The Core Rule Set is developed by OWASP and defines rules for detecting attacks on websites.

[root@localhost vagrant]# yum install mod_security mod_security_crs
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: ftp.ps.pl
* epel: ftp.icm.edu.pl
* extras: centos2.hti.pl
* updates: centos2.hti.pl
Resolving Dependencies
--> Running transaction check
---> Package mod_security.x86_64 0:2.9.2-1.el7 will be installed
--> Processing Dependency: httpd-mmn = 20120211x8664 for package: mod_security-2.9.2-1.el7.x86_64
--> Processing Dependency: httpd for package: mod_security-2.9.2-1.el7.x86_64
--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: mod_security-2.9.2-1.el7.x86_64
--> Processing Dependency: libapr-1.so.0()(64bit) for package: mod_security-2.9.2-1.el7.x86_64
---> Package mod_security_crs.noarch 0:2.2.9-1.el7 will be installed
--> Running transaction check
---> Package apr.x86_64 0:1.4.8-7.el7 will be installed
---> Package apr-util.x86_64 0:1.5.2-6.el7 will be installed
---> Package httpd.x86_64 0:2.4.6-97.el7.centos will be installed
--> Processing Dependency: httpd-tools = 2.4.6-97.el7.centos for package: httpd-2.4.6-97.el7.centos.x86_64
--> Processing Dependency: /etc/mime.types for package: httpd-2.4.6-97.el7.centos.x86_64
--> Running transaction check
---> Package httpd-tools.x86_64 0:2.4.6-97.el7.centos will be installed
---> Package mailcap.noarch 0:2.1.41-2.el7 will be installed
--> Finished Dependency Resolution
Dependencies Resolved================================================================================================================================================================
Package Arch Version Repository Size
================================================================================================================================================================
Installing:
mod_security x86_64 2.9.2-1.el7 base 249 k
mod_security_crs noarch 2.2.9-1.el7 base 91 k
Installing for dependencies:
apr x86_64 1.4.8-7.el7 base 104 k
apr-util x86_64 1.5.2-6.el7 base 92 k
httpd x86_64 2.4.6-97.el7.centos updates 2.7 M
httpd-tools x86_64 2.4.6-97.el7.centos updates 93 k
mailcap noarch 2.1.41-2.el7 base 31 k
Transaction Summary
================================================================================================================================================================
Install 2 Packages (+5 Dependent packages)
Total download size: 3.4 M
Installed size: 11 M
Is this ok [y/d/N]: y
Downloading packages:
(1/7): apr-util-1.5.2-6.el7.x86_64.rpm | 92 kB 00:00:00
(2/7): apr-1.4.8-7.el7.x86_64.rpm | 104 kB 00:00:00
(3/7): httpd-tools-2.4.6-97.el7.centos.x86_64.rpm | 93 kB 00:00:00
(4/7): mailcap-2.1.41-2.el7.noarch.rpm | 31 kB 00:00:00
(5/7): mod_security_crs-2.2.9-1.el7.noarch.rpm | 91 kB 00:00:00
(6/7): mod_security-2.9.2-1.el7.x86_64.rpm | 249 kB 00:00:00
(7/7): httpd-2.4.6-97.el7.centos.x86_64.rpm | 2.7 MB 00:00:01
----------------------------------------------------------------------------------------------------------------------------------------------------------------
Total 2.7 MB/s | 3.4 MB 00:00:01
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : apr-1.4.8-7.el7.x86_64 1/7
Installing : apr-util-1.5.2-6.el7.x86_64 2/7
Installing : httpd-tools-2.4.6-97.el7.centos.x86_64 3/7
Installing : mailcap-2.1.41-2.el7.noarch 4/7
Installing : httpd-2.4.6-97.el7.centos.x86_64 5/7
Installing : mod_security-2.9.2-1.el7.x86_64 6/7
Installing : mod_security_crs-2.2.9-1.el7.noarch 7/7
Verifying : mod_security_crs-2.2.9-1.el7.noarch 1/7
Verifying : mailcap-2.1.41-2.el7.noarch 2/7
Verifying : apr-1.4.8-7.el7.x86_64 3/7
Verifying : mod_security-2.9.2-1.el7.x86_64 4/7
Verifying : apr-util-1.5.2-6.el7.x86_64 5/7
Verifying : httpd-2.4.6-97.el7.centos.x86_64 6/7
Verifying : httpd-tools-2.4.6-97.el7.centos.x86_64 7/7
Installed:
mod_security.x86_64 0:2.9.2-1.el7 mod_security_crs.noarch 0:2.2.9-1.el7
Dependency Installed:
apr.x86_64 0:1.4.8-7.el7 apr-util.x86_64 0:1.5.2-6.el7 httpd.x86_64 0:2.4.6-97.el7.centos httpd-tools.x86_64 0:2.4.6-97.el7.centos
mailcap.noarch 0:2.1.41-2.el7
Complete!

Verify installation

[root@localhost vagrant]# rpm -q mod_security mod_security_crs
mod_security-2.9.2-1.el7.x86_64
mod_security_crs-2.2.9-1.el7.noarch
[root@localhost vagrant]#

Install Apache

[root@localhost vagrant]# yum install httpd
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: ftp.ps.pl
* epel: ftp.icm.edu.pl
* extras: centos2.hti.pl
* updates: centos2.hti.pl
Resolving Dependencies
--> Running transaction check
---> Package httpd.x86_64 0:2.4.6-97.el7.centos will be installed
--> Finished Dependency Resolution
Dependencies Resolved================================================================================================================================================================
Package Arch Version Repository Size
================================================================================================================================================================
Installing:
httpd x86_64 2.4.6-97.el7.centos updates 2.7 M
Transaction Summary
================================================================================================================================================================
Install 1 Package
Total download size: 2.7 M
Installed size: 9.4 M
Is this ok [y/d/N]: y
Downloading packages:
httpd-2.4.6-97.el7.centos.x86_64.rpm | 2.7 MB 00:00:01
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : httpd-2.4.6-97.el7.centos.x86_64 1/1
Verifying : httpd-2.4.6-97.el7.centos.x86_64 1/1
Installed:
httpd.x86_64 0:2.4.6-97.el7.centos
Complete!
[root@localhost vagrant]# systemctl enable httpd
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.
[root@localhost vagrant]# systemctl start httpd
[root@localhost vagrant]# systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: active (running) since Sun 2021-05-16 16:12:51 UTC; 10s ago
Docs: man:httpd(8)
man:apachectl(8)
Main PID: 18727 (httpd)
Status: "Total requests: 0; Current requests/sec: 0; Current traffic: 0 B/sec"
CGroup: /system.slice/httpd.service
├─18727 /usr/sbin/httpd -DFOREGROUND
├─18728 /usr/sbin/httpd -DFOREGROUND
├─18729 /usr/sbin/httpd -DFOREGROUND
├─18730 /usr/sbin/httpd -DFOREGROUND
├─18731 /usr/sbin/httpd -DFOREGROUND
└─18732 /usr/sbin/httpd -DFOREGROUND
May 16 16:12:51 localhost.localdomain systemd[1]: Starting The Apache HTTP Server...
May 16 16:12:51 localhost.localdomain httpd[18727]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using loca... message
May 16 16:12:51 localhost.localdomain systemd[1]: Started The Apache HTTP Server.
Hint: Some lines were ellipsized, use -l to show in full.

Setup ModSecurity

#Make backup configuration
[root@localhost vagrant]# cp -p /etc/httpd/conf.d/mod_security.conf /etc/httpd/conf.d/mod_security.conf.bak

Change SecRuleEngine On to SecRuleEngine DetectionOnly in file /etc/httpd/conf.d/mod_security.conf. Now we can restart Apache server and check logs.

[root@localhost vagrant]# systemctl restart httpd
[root@localhost vagrant]# tail -n 100 /var/log/httpd/modsec_audit.log
Accept-Language: en,en-US;q=0.9,pl;q=0.8,pl-PL;q=0.7
Cookie: screenResolution=1536x864; JSESSIONID.40199af1=node015g1cscv58wey8eeqla2ncr5t5.node0; JSESSIONID.f4224e6f=node019gnjnb79o0p01vs9ixp50cvk10.node0; JSESSIONID.a5662d19=node01q736uca9jc5rnlkx356qed9y0.node0; JSESSIONID.c68fb87a=node01r65fpuuopsucyy4z8jr6r60.node0; jenkins-timestamper-offset=-7200000; JSESSIONID.bdbdc4f7=node0q0y6a6yvws5juz005uuah9y20.node0
--08fff749-F--
HTTP/1.1 404 Not Found
Content-Length: 241
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1
--08fff749-E----08fff749-H--
Message: Warning. Pattern match "^[\\d.:]+$" at REQUEST_HEADERS:Host. [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_21_protocol_anomalies.conf"] [line "98"] [id "960017"] [rev "2"] [msg "Host header is a numeric IP address"] [data "192.168.123.123"] [severity "WARNING"] [ver "OWASP_CRS/2.2.9"] [maturity "9"] [accuracy "9"] [tag "OWASP_CRS/PROTOCOL_VIOLATION/IP_HOST"] [tag "WASCTC/WASC-21"] [tag "OWASP_TOP_10/A7"] [tag "PCI/6.5.10"] [tag "http://technet.microsoft.com/en-us/magazine/2005.01.hackerbasher.aspx"]
Message: Warning. Operator LT matched 5 at TX:inbound_anomaly_score. [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_60_correlation.conf"] [line "33"] [id "981203"] [msg "Inbound Anomaly Score (Total Inbound Score: 3, SQLi=1, XSS=0): Host header is a numeric IP address"]
Apache-Error: [file "apache2_util.c"] [line 271] [level 3] [client 192.168.123.1] ModSecurity: Warning. Pattern match "^[\\\\\\\\d.:]+$" at REQUEST_HEADERS:Host. [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_21_protocol_anomalies.conf"] [line "98"] [id "960017"] [rev "2"] [msg "Host header is a numeric IP address"] [data "192.168.123.123"] [severity "WARNING"] [ver "OWASP_CRS/2.2.9"] [maturity "9"] [accuracy "9"] [tag "OWASP_CRS/PROTOCOL_VIOLATION/IP_HOST"] [tag "WASCTC/WASC-21"] [tag "OWASP_TOP_10/A7"] [tag "PCI/6.5.10"] [tag "http://technet.microsoft.com/en-us/magazine/2005.01.hackerbasher.aspx"] [hostname "192.168.123.123"] [uri "/noindex/css/fonts/Light/OpenSans-Light.woff"] [unique_id "YKFF2gximFiNc8xrKDAqsgAAAAA"]
Apache-Error: [file "apache2_util.c"] [line 271] [level 3] [client 192.168.123.1] ModSecurity: Warning. Operator LT matched 5 at TX:inbound_anomaly_score. [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_60_correlation.conf"] [line "33"] [id "981203"] [msg "Inbound Anomaly Score (Total Inbound Score: 3, SQLi=1, XSS=0): Host header is a numeric IP address"] [hostname "192.168.123.123"] [uri "/noindex/css/fonts/Light/OpenSans-Light.woff"] [unique_id "YKFF2gximFiNc8xrKDAqsgAAAAA"]
Stopwatch: 1621181914693546 4645 (- - -)
Stopwatch2: 1621181914693546 4645; combined=2987, p1=125, p2=2718, p3=1, p4=28, p5=114, sr=10, sw=1, l=0, gc=0
Response-Body-Transformed: Dechunked
Producer: ModSecurity for Apache/2.9.2 (http://www.modsecurity.org/); OWASP_CRS/2.2.9.
Server: Apache/2.4.6 (CentOS)
Engine-Mode: "DETECTION_ONLY"
--08fff749-Z--

⚠️ If a false positive test in this case a legitimate user request is mistakenly judged as an attack is made, the id ([id “960017”]) is checked in the audit log, and an exception is set in mod_security.conf.

Audit Console

The contents of modsec_audit.log are difficult to understand intuitively and take time to analyze. Therefore, we will introduce a tool like Audit Console that allows you to view the contents of the log with a GUI.

AuditConsole will required installed Java and Tomcat. We can download the Audit Console from site below:

  • Install java and tomcat
[root@localhost vagrant]# yum install java-1.8.0-openjdk tomcat -y
[root@localhost vagrant]# java -version
openjdk version "1.8.0_292"
OpenJDK Runtime Environment (build 1.8.0_292-b10)
OpenJDK 64-Bit Server VM (build 25.292-b10, mixed mode)
[root@localhost vagrant]# tomcat version
Server version: Apache Tomcat/7.0.76
Server built: Nov 16 2020 16:51:26 UTC
Server number: 7.0.76.0
OS Name: Linux
OS Version: 3.10.0-1160.24.1.el7.x86_64
Architecture: amd64
JVM Version: 1.8.0_292-b10
JVM Vendor: Red Hat, Inc.
[root@localhost vagrant]# systemctl enable tomcat
Created symlink from /etc/systemd/system/multi-user.target.wants/tomcat.service to /usr/lib/systemd/system/tomcat.service.
[root@localhost vagrant]#
  • Install AuditConsole
[root@localhost vagrant]# cd /var/lib/tomcat/webapps/
[root@localhost vagrant]# systemctl stop tomcat
[root@localhost webapps]# wget https://auditconsole.com/downloads/auditconsole/0.4.7/AuditConsole-0.4.7.1-1.war
[root@localhost vagrant]# chown tomcat.tomcat AuditConsole-0.4.7.1-1.war
[root@localhost vagrant]# systemctl start tomcat

After login we need accept these terms and change Base Directory and Base URL as below:

For Storage we will need change Data Directory as below:

If the above settings are successful, the Audit Console will be available. If we want the logs to automatically appear in AuditConsole, we must configure the sensor and use ModSecurity Audit Log Collector, which will cause the logs to flow to AuditConsole. We can also manually send the file to AuditConsole to be able to read it in a more friendly form. An example below.

What we should Test before deployment in prod

When installing ModSecurity on a web server or web application server in a production environment, it is recommended to install and test in a test environment in advance, becasue when the WAF determines the content of the request, the determination is made mechanically, so there is a possibility of many false positives.

We can distinguish two types of false positives:

  • False positives Falsely
  • Missing false negative

If there is a false positive, the user’s correct request will be blocked, and you will not be able to browse the website or use the web application, but false negatives prevent you from defending against the missed attack.

I think so is good idea installing and testing in a test environment to check the operation of ModSecurity and find the ModSecurity and Core Rules Set settings that are suitable for our website and web application.

Source: https://giphy.com/

--

--

Maciej

DevOps Consultant. I’m strongly focused on automation, security, and reliability.