How to Install ModSecurity for Nginx on Debian/Ubuntu

It is every developer’s desire to deploy secure web applications which are safe from threats. On most occasions, this is effortless said than done. The frequency of websites being hacked keeps rising as hackers continue to exploit all attack vectors at their disposal.

WebApp security can be a huge challenge especially with the prevalence of malicious tools such as rootkits, scanners, bots, and other malware. Although getting breached may seem a matter of when if not if, it is prudent to implement some decent security measures to safeguard your web applications.

[ You might also like: 5 Tools to Scan a Linux Server for Malware and Rootkits ]

One of the tools that can provide a decent level of security against attacks is called ModSecurity. This is a free and open-source Web Application Firewall (WAF) that protects your web applications from a vast array of layer 7 attacks such as cross-site scripting (XSS), SQL injection, session hijacking, and many more.

In this guide, we will show you how to install and configure ModSecurity to work with Nginx on Debian-based Linux distributions such as Ubuntu.

Step 1: Install Dependencies

To begin the installation, a number of software dependencies are required for the installation to be successful. But first, update the package lists and refresh the repositories as follows.

$ sudo apt update

Next, install the dependencies as follows.

$ sudo apt install make gcc build-essential autoconf automake libtool libfuzzy-dev ssdeep gettext pkg-config libcurl4-openssl-dev liblua5.3-dev libpcre3 libpcre3-dev libxml2 libxml2-dev libyajl-dev doxygen libcurl4 libgeoip-dev libssl-dev zlib1g-dev libxslt-dev liblmdb-dev libpcre++-dev libgd-dev

Step 2: Install Latest Nginx Version


The next step will be to install the Nginx web browser. To install the latest version, we are going to install it from the
ondrej/nginx-mainline PPA w that is currently being maintained by a Debian developer since 2000.

To add the PPA to your local Ubuntu system execute the command:

$ sudo add-apt-repository ppa:ondrej/nginx-mainline -y

Next, update the package lists and install the latest version of Nginx as follows

$ sudo apt update
$ sudo apt install nginx-core nginx-common nginx nginx-full

Typically, only the default repository is enabled. It’s prudent to enable the source code repository so that you can, later on, download the Nginx source code in the next step.

To achieve this, modify the Nginx repository file.

$ sudo vim /etc/apt/sources.list.d/ondrej-ubuntu-nginx-mainline-*.list

Locate and uncomment this line to enable the source code repository:

# deb-src http://ppa.launchpad.net/ondrej/nginx-mainline/ubuntu/ focal main

The file should now appear as shown.

Enable Ondřej PPA
Enable Ondřej PPA

Save the changes and exit.

Then update the package index.

$ sudo apt update

Step 3: Download Nginx Source Package

To compile the ModSecurity dynamic module, we need to download the Nginx source code package. To do this, we will, first, create an Nginx directory in the /usr/local/src/ path to accommodate the Nginx source code package file.

$ sudo mkdir -p /usr/local/src/nginx 

Next, assign the directory permissions as shown. Be sure to replace the username with your actual sudo username.

$ sudo chown username:username -R /usr/local/src/

Thereafter, navigate into the Nginx source directory:

$ cd /usr/local/src/nginx 

Proceed and download the Nginx source file packages:

$ sudo apt source nginx
Download Nginx Source
Download Nginx Source

You will most likely get into the following error:

W: Download is performed unsandboxed as root as file 'nginx_1.19.5.orig.tar.gz' couldn't be accessed by user '_apt'. - pkgAcquire::Run (13: Permission denied)

This is nothing to get you worked up. So, simply ignore the error.

You can have a peek at the source file using the ls command.

$ ls -l
List Nginx Source Files
List Nginx Source Files

Be sure that the source code version coincides with the version of Nginx installed.

$ nginx -v
Check Nginx Version
Check Nginx Version

Step 4: Install the Libmodsecurity3 Library

Libmodesecurity is a Modsecurity library that handles HTTP filtering for your applications. There are two ways of installing it. You can use the apt package manager as shown

$ sudo apt install libmodsecurity3

The other approach is to install it from a source which is preferable since it provides you with the latest version. To start the installation of Libmodsecurity from the source, clone the git repository as shown:

$ git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity /usr/local/src/ModSecurity/

Navigate into the cloned directory:

$ cd /usr/local/src/ModSecurity/

Make a point to install the submodules

$ sudo git submodule init
$ sudo git submodule update
Install Libmodsecurity3 in Ubuntu
Install Libmodsecurity3 in Ubuntu

Afterward, build the environment using the commands below.

$ sudo ./build.sh 
$ sudo ./configure

Once again, ignore the error displayed below.

fatal: No names found, cannot describe anything.

Then compile the source code and install other utilities using the following make command. This takes around 25 minutes, and some patience is required.

$ sudo make -j4

Once completed, install the libraries.

$ sudo make install

Step 5: Download and Compile ModSecurity v3 Nginx Connector

The next step is to download and compile the ModSecurity Nginx connector. The connector, as the name suggests, links the Libmodsecurity library to the Nginx webserver. To download the Modsecurity connector, Clone it from the GitHub repository as follows.

$ git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git /usr/local/src/ModSecurity-nginx/

Navigate into the cloned directory.

$ cd /usr/local/src/nginx/nginx-1.21.3/

Proceed and install build dependencies

$ sudo apt build-dep nginx
$ sudo apt install uuid-dev

Next, compile the ModSecurity Nginx Connector module with the --with-compat flag. The --with-compat option makes the ModSecurity Nginx Connector module binary-compatible with the current Nginx library.

$ sudo ./configure --with-compat --add-dynamic-module=/usr/local/src/ModSecurity-nginx

Once that is done, build the ModSecurity Nginx Connector module using the make command.

$ sudo make modules

The module is saved as objs/ngx_http_modsecurity_module.so. You need to copy this module to the /usr/share/nginx/modules/ directory as follows.

$ sudo cp objs/ngx_http_modsecurity_module.so /usr/share/nginx/modules/

Step 6: Load the ModSecurity Nginx Connector Module

To load the Nginx connector module, First, access the main Nginx configuration file.

$ sudo vim /etc/nginx/nginx.conf

Append the following line just below the first few lines

load_module modules/ngx_http_modsecurity_module.so;

In addition, append the following lines in the http {...} section. This enables ModSecurity for all Nginx virtual hosts.

modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/main.conf;
Enable Mod_Security for Nginx vHosts
Enable Mod_Security for Nginx vHosts

Save the changes and exit the file.

Next up, create the /etc/nginx/modsec/ directory which will store ModSecurity configuration.

$ sudo mkdir /etc/nginx/modsec/

Next, copy the ModSecurity configuration file as follows.

$ sudo cp /usr/local/src/ModSecurity/modsecurity.conf-recommended /etc/nginx/modsec/modsecurity.conf

Then open the configuration file.

$ sudo vim /etc/nginx/modsec/modsecurity.conf

Locate the line beginning with the SecRuleEngine directive.

SecRuleEngine DetectionOnly

This line instructs ModSecurity to only log HTTP transactions but takes no action in the face of a web app attack. You need to change this so that Modsecurity will not only detect but also block web attacks.

Change the line to the line below

SecRuleEngine On
Enable Mod_Security Rules
Enable Mod_Security Rules

Save the changes and exit the file.

Next, create the /etc/nginx/modsec/main.conf file.

$ sudo vim  /etc/nginx/modsec/main.conf

Append this line to reference the /etc/nginx/modsec/modsecurity.conf configuration file.

Include /etc/nginx/modsec/modsecurity.conf

Save the changes and exit the file.

Additionally, copy the Unicode mapping file.

$ sudo cp /usr/local/src/ModSecurity/unicode.mapping /etc/nginx/modsec/

Then test Nginx configuration.

$ sudo nginx -t
Test Nginx Configuration
Test Nginx Configuration

The test should be successful. If not, head back and check if all the changes made are correct.

Then finally, restart Nginx to apply all the changes made.

$ sudo systemctl restart nginx

And verify that Nginx is running as expected.

$ sudo systemctl status nginx

Step 7: Download OWASP Corerule Set

For ModSecurity to protect your web applications, you need to specify rules that are going to detect suspicious activities and block them. To get started, it’s preferable to install existing rule sets that will help you learn the ropes.

The OWASP Core Rule Set (CRS) is a free, open-source, and community-maintained rule set that provides rules to ward off common attack vectors such as SQL injection, Cross-site scripting (XSS).

Download the OWASP Core Rule Set from Github as shown using the wget command.

$ wget https://github.com/coreruleset/coreruleset/archive/v3.3.0.tar.gz

Extract the compressed file.

$ tar xvf v3.3.0.tar.gz

Ensure to move the uncompressed directory to the /etc/nginx/modsec/ path.

$ sudo mv coreruleset-3.3.0/ /etc/nginx/modsec/

Then rename the crs-setup.conf.example file to crs-setup.conf.

$ sudo mv /etc/nginx/modsec/coreruleset-3.3.0/crs-setup.conf.example /etc/nginx/modsec/coreruleset-3.3.0/crs-setup.conf

Again, head back to the ModSecurity configuration file.

$ sudo vim /etc/nginx/modsec/main.conf

And append the following lines.

Include /etc/nginx/modsec/coreruleset-3.3.0/crs-setup.conf
Include /etc/nginx/modsec/coreruleset-3.3.0/rules/*.conf

The file should now have 3 lines:

Configure ModSecurity Rules
Configure ModSecurity Rules

Save the file and, once again, restart Nginx.

$ sudo systemctl restart nginx

Step 8: Testing Out ModSecurity

Finally, We are going to carry out a test ModSecurity and confirm it can detect and block suspicious HTTP traffic.

We are going to edit the ModSecurity configuration file and create a blocking rule that will block access to a certain URL when accessed by a web browser.

$ sudo vim /etc/nginx/modsec/modsecurity.conf

Add this line just below the SecRuleEngine On directive

SecRule ARGS:testparam "@contains test" "id:254,deny,status:403,msg:'Test Successful'"

You can set the ‘id’ and ‘msg’ tags to your preferred values.

Test ModSecurity Rules
Test ModSecurity Rules

Save the changes and restart Nginx.

$ sudo systemctl restart nginx

Now launch your browser and visit the URL below with the ?testparam=test suffix

http://server-ip/?testparam=test

You should get a 403 ‘Forbidden’ error. This indicates that you are trying to access a forbidden resource on the webserver.

Nginx 403 Forbidden Error
Nginx 403 Forbidden Error

Additionally, you can check the Nginx error logs to confirm that the client was blocked

$ cat /var/log/nginx/error.log | grep "Test Successful"
Check Nginx ModSecurity Block
Check Nginx ModSecurity Block

[ You might also like: How to Set Up ModSecurity with Apache on Debian/Ubuntu ]

That was an overview of how you can set up Modsecurity with Nginx on Debian and Ubuntu. We hope that this has been beneficial.

James Kiarie
This is James, a certified Linux administrator and a tech enthusiast who loves keeping in touch with emerging trends in the tech world. When I'm not running commands on the terminal, I'm taking listening to some cool music. taking a casual stroll or watching a nice movie.

Each tutorial at TecMint is created by a team of experienced Linux system administrators so that it meets our high-quality standards.

Join the TecMint Weekly Newsletter (More Than 156,129 Linux Enthusiasts Have Subscribed)
Was this article helpful? Please add a comment or buy me a coffee to show your appreciation.

1 Comment

Leave a Reply
  1. I have an issue.

    nginx -t
    nginx: [emerg] dlopen() “/usr/share/nginx/modules/ngx_http_modsecurity_module.so” failed (libfuzzy.so.2: cannot open shared object file: No such file or directory) in /etc/nginx/nginx.conf:1

    nginx -v
    nginx version: nginx/1.18.0 (Ubuntu)

    Did anyone solve this problem?

    Reply

Leave a Reply to Robert Cancel reply

Thank you for taking the time to share your thoughts with us. We appreciate your decision to leave a comment and value your contribution to the discussion. It's important to note that we moderate all comments in accordance with our comment policy to ensure a respectful and constructive conversation.

Rest assured that your email address will remain private and will not be published or shared with anyone. We prioritize the privacy and security of our users.