Secure Apache using ModSecurity on Ubuntu 18/19/20

ModSecurity is an open-source, cross-platform web application firewall (WAF) module. Known as the "Swiss Army Knife" of WAFs, it enables web application defenders to gain visibility into HTTP(S) traffic and provides a power rules language and API to implement advanced protections. ModSecurity is a toolkit for real-time web application monitoring, logging, and access control.

The following is a list of the most important usage scenarios:

Real-time application security monitoring and access control
At its core, ModSecurity gives you access to the HTTP traffic stream, in real-time, along with the ability to inspect it. This is enough for real-time security monitoring. There's an added dimension of what's possible through ModSecurity's persistent storage mechanism, which enables you to track system elements over time and perform event correlation. You are able to reliably block if you so wish because ModSecurity uses full request and response buffering.

Full HTTP traffic logging
Web servers traditionally do very little when it comes to logging for security purposes. They log very little by default, and even with a lot of tweaking you are not able to get everything that you need. I have yet to encounter a web server that is able to log full transaction data. ModSecurity gives you the ability to log anything you need, including raw transaction data, which is essential for forensics. In addition, you get to choose which transactions are logged, which parts of a transaction are logged, and which parts are sanitized.

Continuous passive security assessment
A security assessment is largely seen as an active scheduled event, in which an independent team is sourced to try to perform a simulated attack. The continuous passive security assessment is a variation of real-time monitoring, where, instead of focusing on the behavior of the external parties, you focus on the behavior of the system itself. It's an early warning system of sorts that can detect traces of many abnormalities and security weaknesses before they are exploited.

Web application hardening
One of my favorite uses for ModSecurity is attack surface reduction, in which you selectively narrow down the HTTP features you are willing to accept (e.g., request methods, request headers, content types, etc.). ModSecurity can assist you in enforcing many similar restrictions, either directly, or through collaboration with other Apache modules. They all fall under web application hardening. For example, it is possible to fix many session management issues, as well as cross-site request forgery vulnerabilities.

This guide will help you to set up ModSecurity for Apache webserver running on an Ubuntu or Debian server.


You will need one (physical or virtual) machine installed with Ubuntu or Debian having a non-root user sudo privileges. This guide assumes that you have already set up Apache on your Ubuntu or Debian server.

Install ModSecurity

Type below command to install ModSecurity on Ubuntu:
sudo apt-get install libapache2-mod-security2
Restart apache service to take mod-security module into account:
sudo systemctl restart apache2
Type below command to install ModSecurity on Debian:
sudo apt install libapache2-modsecurity
sudo systemctl restart apache2
Type below command to install ModSecurity on CentOS/RHEL 7
sudo yum -y install epel-release
sudo yum -y install mod_security
sudo systemctl restart httpd
Type below command to install ModSecurity on CentOS/RHEL 8
sudo dnf -y install epel-release
sudo dnf -y install mod_security
sudo systemctl restart httpd

Configure ModSecurity

The following steps are for Ubuntu or Debian based distributions. If you are on CentOS/RHEL, file paths and commands will differ slightly.

Move and change the name of the default ModSecurity file:
sudo mv /etc/modsecurity/modsecurity.conf-recommended  /etc/modsecurity/modsecurity.conf
Download the OWASP ModSecurity CRS from Github:
cd ~
git clone
Move and rename crs-setup.conf.example to crs-setup.conf. Then move rules/ directory as well.
cd ~/owasp-modsecurity-crs
sudo mv crs-setup.conf.example /etc/modsecurity/crs-setup.conf
sudo mv rules/ /etc/modsecurity/
The configuration file should match the path above as defined in the IncludeOptional directive.
sudo nano etc/apache2/mods-available/security2.conf
Add another Include directive pointing to the ruleset:
<IfModule security2_module>
        # Default Debian dir for modsecurity's persistent data
        SecDataDir /var/cache/modsecurity

        # Include all the *.conf files in /etc/modsecurity.
        # Keeping your local configuration in that directory
        # will allow for an easy upgrade of THIS file and
        # make your life easier
        IncludeOptional /etc/modsecurity/*.conf
        Include /etc/modsecurity/rules/*.conf
Save and close the editor.

Restart Apache to take changes into effect:
sudo systemctl restart apache2

Test ModSecurity

The OWASP CRS builds on top of ModSecurity so that existing rules can be extended.

Edit the default Apache configuration file and add two additional directives, using the default configuration as an example:
sudo nano /etc/apache2/sites-available/000-default.conf

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    SecRuleEngine On
    SecRule ARGS:modsecparam "@contains test" "id:4321,deny,status:403,msg:'ModSecurity test rule has triggered'"
Save and close the editor.

Restart Apache to take changes into effect.
sudo systemctl restart apache2
Curl the index page to intentionally trigger the alarms:
curl localhost/index.html?modsecparam=test
The response code should be 403. There should be a message in the logs that shows the defined ModSecurity rule worked.

You can check using: sudo tail -f /var/log/apache2/error.log
ModSecurity: Access denied with code 403 (phase 2). String match “test” at ARGS:modsecparam. [file “/etc/apache2/sites-enabled/000-default.conf”] [line “24”] [id “1234”] [msg “ModSecurity test rule has triggered”] [hostname “localhost”] [uri “/index.html”] [unique_id “WenFd36AAAEAAEmQyEAAAAAD”]
Verify the OWASP CRS is in effect:
curl localhost/index.html?exec=/bin/bash
Check the error logs again: the rule has caught the attempted execution of an arbitrary bash script.
ModSecurity: Warning. Matched phrase “bin/bash” at ARGS:. [file “/etc/modsecurity/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf”] [line “448”] [id “932160”] [rev “1”] [msg “Remote Command Execution: Unix Shell Code Found”] [data “Matched Data: bin/bash found within ARGS:: exec/bin/bash”] [severity “CRITICAL”] [ver “OWASP_CRS/3.0.0”] [maturity “1”] [accuracy “8”] [tag “application-multi”] [tag “language-shell”] [tag “platform-unix”] [tag “attack-rce”] [tag “OWASP_CRS/WEB_ATTACK/COMMAND_INJECTION”] [tag “WASCTC/WASC-31”] [tag “OWASP_TOP_10/A1”] [tag “PCI/6.5.2”] [hostname “localhost”] [uri “/index.html”] [unique_id “WfnVf38AAAEAAEqya3YAAAAC”]

Wrapping up

Review the configuration files located in /etc/modsecurity/*.conf. Most of the files are commented with definitions of the available options. ModSecurity uses an Anomaly Scoring Level where the highest number (5) is most severe. Review the wiki for additional directives to update the rules when encountering false positives. You may wish to go through the following official resources for additional information on this topic.


  1. after including the directive in
    Trying to restart apache fails to error :
    Jun 12 18:52:23 vodacom apachectl[14315]: AH00526: Syntax error on line 773 of /etc/modsecurity/crs/crs-setup.conf:
    Jun 12 18:52:23 vodacom apachectl[14315]: Error parsing actions: Unknown action: "
    Jun 12 18:52:23 vodacom apachectl[14315]: Action 'start' failed.
    Jun 12 18:52:23 vodacom apachectl[14315]: The Apache error log may have more information.
    Jun 12 18:52:23 vodacom systemd[1]: apache2.service: Control process exited, code=exited status=1
    Jun 12 18:52:23 vodacom systemd[1]: apache2.service: Failed with result 'exit-code'.
    Jun 12 18:52:23 vodacom systemd[1]: Failed to start The Apache HTTP Server.
    -- Subject: Unit apache2.service has failed

    1. Pay attention to this and fix it first, then reload the apache service:

      Syntax error on line 773 of /etc/modsecurity/crs/crs-setup.conf

  2. Most likely some actions are loaded twice.
    (for debian)
    Make sure /etc/apache2/mods-available/security2.conf has
    #IncludeOptional /usr/share/modsecurity-crs/*.load commented out!
    If not, you're including /etc/modsecurity/crs/crs-setup.conf AND /etc/modsecurity/crs-setup.conf !!


Powered by Blogger.