How to Install ModSecurity 3, OWASP CRS with Nginx on Debian 12, 11, or 10

For those aiming to secure their web applications robustly, learning how to install Modsecurity 3, OWASP CRS with Nginx on Debian 12 Bookworm, Debian 11 Bullseye, or Debian 10 Bullseye is essential. This powerful combination provides a comprehensive Web Application Firewall (WAF) solution, crucial for safeguarding your web applications effectively.

Key Features of ModSecurity 3:

  • Performance: With its codebase rewritten in C, ModSecurity 3 offers enhanced speed and scalability, ensuring swift and efficient performance.
  • Compatibility: It extends support beyond Apache to accommodate other web servers, including NGINX and IIS, broadening its applicability.
  • Modularity: ModSecurity 3 can function as either a standalone program or integrate as a library within other software, providing flexibility in its deployment.

NGINX ModSecurity 3 Connector Features:

  • Intermediary Role: This connector bridges the interaction between NGINX and ModSecurity, facilitating seamless communication and functionality between the two.
  • Traffic Access: It enables ModSecurity to scrutinize the HTTP traffic processed by NGINX, allowing for meticulous monitoring and management of web traffic.

OWASP Core Rule Set (CRS) Features:

  • Broad-Spectrum Defense: CRS offers protection against various web application security risks, providing a fortified defense mechanism.
  • Detection Mechanisms: It is adept at identifying prevalent vulnerabilities, including SQL Injection and Cross-Site Scripting, safeguarding your applications from common threats.

This combination of ModSecurity 3, OWASP CRS, and NGINX on Debian provides a fortified security solution for your web applications. The forthcoming guide will delineate the steps necessary to install Modsecurity 3, OWASP CRS with Nginx on Debian 12 Bookworm, Debian 11 Bullseye, or Debian 10 Bullseye, empowering you with enhanced web application security.

Pre-Installation Steps with ModSecurity 3 with Nginx on Debian 12, 11, or 10

Before diving into the installation of ModSecurity, it is paramount to prepare our server adequately. This involves updating our system and ensuring we’re working with the latest iteration of NGINX, a high-performance web server and reverse proxy server. These preliminary actions create a conducive environment for a seamless installation process, drastically reducing potential compatibility issues and plugging security vulnerabilities.

Step 1: Update Debian System Packages Before ModSecurity 3 with Nginx Installation

The path to a secure and efficient server is regularly updating it. Regular updates ensure all software packages have the latest security patches and performance improvements. To keep your system up-to-date, execute the following command:

sudo apt update && sudo apt upgrade

This command first updates the package list for upgrades, ensuring that your system is aware of all new updates (sudo apt update).

Step 2: Remove Existing NGINX Installation (Situational)

This step is optional if you’ve already installed Nginx. If you decide to remove it and you have a complex setup, make sure to back up your configuration files.

If you have an existing NGINX installation, we recommend removing it to pave the way for the latest version from a custom PPA maintained by Ondřej Surý. This version boasts additional dynamic modules, such as the Brotli module, promising improved compression.

To achieve this, first, bring the current NGINX service to a halt with the following:

sudo systemctl stop nginx

Next, remove the existing NGINX installation with:

sudo apt purge nginx
sudo apt autoremove nginx

In this command, the purge option ruthlessly eradicates the NGINX package alongside its configuration files. The autoremove command deletes any packages that were automatically installed to satisfy dependencies for NGINX but now serve no purpose.

Step 3: Import NGINX PPA for ModSecurity 3 and Debian for Latest Version (Optional)

This step is optional but highly recommended. If you choose not to follow this method and instead use the standard Debian version of Nginx, make sure to download the matching source files. This should be easy to determine later in the guide.

After discarding the previous NGINX service, incorporate a new, up-to-date Personal Package Archive (PPA) for NGINX. Choose between a stable or mainline version. Generally recommended, the mainline version offers the latest features and improvements.

To add the new PPA, execute the following command:

curl -sSL | sudo bash -x

Step 4: Refresh APT Cache after Nginx PPA Import on Debian

After the desired repository’s inclusion, updating your APT sources list becomes essential. This step ensures the system recognizes the new packages in the added repository. Update your sources list with the following:

sudo apt update

With the updates in place, proceed to install NGINX with the following:

sudo apt install nginx-core nginx-common nginx

During the installation, you may encounter a prompt requesting whether to keep or replace your existing /etc/nginx/nginx.conf configuration file. To avoid any unforeseen disruptions, it is generally advisable to retain your current configuration file by pressing n.

Step 5: Import NGINX Source Code PPA Configuration File on Debian

The PPA installation doesn’t bundle the NGINX source code by default. However, you must enable this feature to manually download the NGINX source code, which is necessary for compiling ModSecurity in subsequent steps of this guide.

Start this process by opening the configuration file located in /etc/apt/sources.list.d.

sudo nano /etc/apt/sources.list.d/nginx-mainline.list

This will be a different filename if you installed or have another third-party source for your Nginx installation.

Now add the following line directly under the original source line:

deb-src [signed-by=/usr/share/keyrings/] bookworm main
Screenshot showing how to add deb-src for Debian 12, 11, or 10 during Modsecurity 3 presetup.Pin
Example of adding deb-src repositories for Debian 12, 11, or 10 in preparation for Modsecurity 3 installation.

Once completed, preserve the changes by pressing CTRL+O and then exit the editor by pressing CTRL+X.

To conclude this stage, refresh the repository list with:

sudo apt update

This command guarantees that your system recognizes the inclusion of the NGINX source code in the repository, making it accessible for subsequent operations.

Download Nginx Source For ModSecurity 3 on Debian 12, 11, or 10

We must compile the ModSecurity dynamic module leveraging the Nginx source code to establish a fluid integration between ModSecurity and Nginx. This requires us to fetch and store the Nginx source code in a specific directory (designated as /usr/local/src/nginx for our purposes).

In this section, we will guide you through creating the requisite directories, installing the dependencies, fetching the source code, and finally validating that the fetched source version aligns with the Nginx version installed in your system.

Step 1: Create Directory Structure for Nginx Source on Debian

First, establish the directory to fetch and store the Nginx source code. Use the following command to create and enter the directory:

sudo mkdir /usr/local/src/nginx && cd /usr/local/src/nginx

Step 2: Install Initial Packages and Fetch the Nginx Source Code

Before downloading the source code, install the dpkg-dev package. This package includes various development tools for unpacking, constructing, and uploading Debian source packages. Install it with the following command:

sudo apt install dpkg-dev -y

After setting up the essential tools, we are now ready to fetch the Nginx source code using:

sudo apt source nginx

If you receive an error message while running this command, don’t worry; you can safely discard it.

Screenshot of an ignorable error message during Nginx source download for Modsecurity 3 on Debian 12, 11, or 10.Pin
Example of an error message that can be ignored when downloading Nginx source for Modsecurity 3 installation on Debian 12, 11, or 10.

Step 3: Verifying the Source Version on Debian

This part is crucial. Using a different Nginx source version than the current Nginx binary installed on your Debian system will result in errors and prevent compilation. Pay close attention here.

Download the source code and ensure it syncs with the Nginx version installed on your system. Any version discrepancies can cause compatibility issues, making this verification step crucial.

Begin by listing the files in the current directory to confirm successful source code download with the following command:


The output should comprise several files and directories pertinent to Nginx.

Screenshot showing the presence of Nginx source files required to continue with Modsecurity 3 installation on Debian 12, 11, or 10.Pin
You should have an example of the Nginx source files before proceeding with Modsecurity 3 installation on Debian 12, 11, or 10.

Ensure the source package version matches the Nginx version installed on your Debian system. Use the following command to check the installed Nginx version:

nginx -v

The output will project your installed Nginx version. It is crucial to ascertain that this version corresponds with the source version that you’ve downloaded. If they don’t align, you’ll need to fetch the correct version of the Nginx source code.

Install libmodsecurity3 on Debian 12, 11, or 10

ModSecurity functions as a robust firewall for web applications, and libmodsecurity3 acts as its central component in facilitating HTTP filtering. This section focuses on helping you procure and set up this crucial software package.

Step 1: Fetch ModSecurity 3 Repository on Debian

Start by fetching the source code for libmodsecurity3 from its GitHub repository using Git, a widely used distributed version control system. If your system lacks Git, install it using the following command:

sudo apt install git -y

Before cloning the repository, modify the directory ownership to avoid needing root privileges (sudo) for most commands:

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

This command recursively alters the ownership of /usr/local/src/ directory to the current user.

The next step involves cloning the libmodsecurity3 repository. We’ll execute a shallow clone (–depth 1) to conserve bandwidth and storage, implying that we’ll only fetch the latest revision of the v3/master branch:

git clone --depth 1 -b v3/master --single-branch /usr/local/src/ModSecurity/

Having cloned the repository, switch your working directory to the newly cloned repository:

cd /usr/local/src/ModSecurity/

Step 2: Install libmodsecurity3 Initial Packages on Debian

Compiling libmodsecurity3 requires several dependencies. Install them with the following:

sudo apt install gcc make build-essential autoconf automake libtool libcurl4-openssl-dev liblua5.3-dev libfuzzy-dev ssdeep gettext pkg-config libpcre3 libpcre3-dev libxml2 libxml2-dev libcurl4 libgeoip-dev libyajl-dev doxygen libpcre2-16-0 libpcre2-dev libpcre2-posix3 -y

Indispensable dependencies are necessary to compile Nginx with ModSecurity successfully from version 1.21.4 onward. Though some users report issues during this step, installing the correct dependencies will resolve these issues in most scenarios.

Afterward, initialize and update the Git submodules using the following commands:

git submodule init
git submodule update

Step 3: Build the ModSecurity 3 Environment on Debian

Having prepared our workspace, we can now construct the ModSecurity environment. Initially, execute the build script:

Screenshot showing the build environment setup for Modsecurity 3 and Nginx on Debian 12, 11, or 10.Pin
Example of setting up the build environment for Modsecurity 3 and Nginx on Debian 12, 11, or 10 Linux.

Subsequently, configure the environment:


During this process, you might encounter an error message stating “fatal: No names found, cannot describe anything.” You can safely disregard this error message.

Screenshot showing how to configure the environment for Modsecurity 3 and Nginx connector on Debian 12, 11, or 10.Pin
Example of configuring the necessary environment for Modsecurity 3 and Nginx connector on Debian 12, 11, or 10 Linux.

Step 4: Compile the ModSecurity 3 Source Code on Debian

With the environment for libmodsecurity3 constructed and configured, we are ready to compile it. The following command serves this purpose:


To expedite the compilation process on high-performance servers, execute make with the -j option, followed by the number of CPU cores your server has. For example, for a server with six CPU cores, use the command:

make -j 6
Screenshot of the 'make' output during Modsecurity and Nginx connector build on Debian 12, 11, or 10.Pin
Example showing the output of the ‘make’ command during the build process for Modsecurity and Nginx connector on Debian 12, 11, or 10.

Step 5: Install the Compiled Code of ModSecurity 3 on Debian

Having compiled the source code, we now reach the final step, which involves the installation of the compiled code:

sudo make install

This command installs libmodsecurity3 into the /usr/local/modsecurity/ directory, which subsequent parts of this guide will reference.

Screenshot showing the 'make install' command for Nginx connector build with Modsecurity 3 on Debian 12, 11, or 10.Pin
Example of using the ‘make install’ command to build the Nginx connector for Modsecurity 3 on Debian 12, 11, or 10.

Install ModSecurity-nginx Connector on Debian 12, 11 or 10

The successful installation of ModSecurity-nginx, the vital mediator between the widely-used Nginx web server and ModSecurity, can significantly boost your web applications’ security. In this section, we’ll walk you through the meticulous steps of setting up this connector on your Debian server.

Step 1: Fetch ModSecurity-nginx Connector Source on Debian

Our journey commences with obtaining the source code for the ModSecurity-nginx connector. The GitHub repository provides this source code. If this sounds familiar, the method is similar to the earlier process of fetching the source code for libmodsecurity3. Use the following command to clone the ModSecurity-nginx repository:

git clone --depth 1 /usr/local/src/ModSecurity-nginx/

This command does a shallow repository clone, drawing in only the latest revision. This efficient cloning saves on bandwidth and storage consumption.

Step 2: Install ModSecurity-nginx Connector Initial Packages

After successfully fetching the source code, we must navigate to the Nginx source directory next. Execute the cd command as follows to do this:

cd /usr/local/src/nginx/nginx-1.*.*

Once inside the Nginx source directory, our next step is to install the dependencies required for the ModSecurity-nginx connector. The following command will not only fetch the necessary dependencies but also install them:

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

Step 3: Build ModSecurity-nginx Connector Environment on Debian

With all dependencies installed, we’re ready to compile the ModSecurity-nginx connector. This involves running the configure command with the --with-compat flag and --add-dynamic-module option:

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

The --with-compat flag assures compatibility with different systems, while the --add-dynamic-module option dictates the location of the ModSecurity-nginx connector.

Screenshot of Nginx dynamic module example output for Modsecurity 3 on Debian 12, 11, or 10.Pin
Example showing the Nginx dynamic module output when using Modsecurity 3 on Debian 12, 11, or 10.

After configuring the environment, we’re ready to generate the dynamic modules. To do this, we execute the make command as follows:

make modules
Screenshot showing the 'make modules' output for Modsecurity 3 and Nginx on Debian 12, 11, or 10.Pin
Example of the ‘make modules’ output during the build process for Modsecurity 3 and Nginx on Debian 12, 11, or 10.

Step 4: Install ModSecurity 3 Dynamic Module on Debian

The last step in this setup process involves relocating the dynamic module to a suitable directory. The make modules command creates a dynamic module at the objs/ location. It is crucial to move this module to the /etc/nginx/modules/ directory, which can be achieved using the following command:

sudo cp objs/ /etc/nginx/modules/

Remember, you can store the dynamic module at any location, provided that you specify the full path during the loading process.

Depending on the source of your Nginx installation, the folder may not exist, so quickly create it if you cannot move it:

sudo mkdir /etc/nginx/modules/

Enable ModSecurity-nginx Connector with Nginx on Debian 12, 11 or 10

Upon successfully setting up the ModSecurity-nginx connector, the subsequent course entails loading it into Nginx and tailoring the configuration to your specific needs. This process will primarily involve manipulating the Nginx configuration file located at /etc/nginx/nginx.conf, ultimately rendering ModSecurity fully operational with your Nginx web server.

Step 1: Activating ModSecurity within nginx.conf on Debian

Our first task is to define the ModSecurity module’s location within the nginx.conf file. This step can be accomplished by editing the nginx.conf file using a text editor. In this case, we’ll utilize nano:

sudo nano /etc/nginx/nginx.conf

At the file’s onset, incorporate the following line:

load_module modules/;

This directive instructs Nginx to load the ModSecurity module.

Remember to include the complete path in this directive if you’ve placed the module elsewhere elsewhere.

Subsequently, append the following directives within the http {} block:

modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/modsec-config.conf;

The directives above activate ModSecurity and define the location of the ModSecurity rules file. Save the changes (Ctrl+O) and then close the file (Ctrl+X).

Step 2: Create ModSecurity 3 Directories and Files on Debian

Creating a dedicated directory is necessary to accommodate configuration files and future rules. The command below will generate the /etc/nginx/modsec directory:

sudo mkdir /etc/nginx/modsec/

Next, replicate the sample ModSecurity configuration file from the cloned Git directory into the directory you’ve just created:

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

Now, let’s alter the modsecurity.conf file. By default, the ModSecurity rule engine operates in DetectionOnly mode, identifying malicious behavior but refraining from blocking it. To adjust this behavior, open the modsecurity.conf file:

sudo nano /etc/nginx/modsec/modsecurity.conf

Locate the line SecRuleEngine DetectionOnly and alter it to:

SecRuleEngine On

Then, find the SecAuditLogParts line:

# Log everything we know about a transaction.
SecAuditLogParts ABIJDEFHZ

The current configuration is inaccurate. Adjust the line as follows:

SecAuditLogParts ABCEFHJKZ

Now, save (Ctrl+O) and close (Ctrl+X) the file.

Step 3: Create modsec-config.conf on Debian

Subsequently, we need to create a modsec-config.conf file. This file will encapsulate the modsecurity.conf file and other rule sets, such as the OWASP CRS, at a later stage. To create and open the file, run this command:

sudo nano /etc/nginx/modsec/modsec-config.conf

Once inside the file, include the following line:

Include /etc/nginx/modsec/modsecurity.conf

Save (Ctrl+O) and close (Ctrl+X) the file.

Finally, duplicate ModSecurity’s unicode.mapping file using the cp command:

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

Step 4: Test ModSecurity 3 Configuration on Debian

Before we proceed, it is essential to verify your configuration. Execute the following command to conduct a dry run of the Nginx service:

sudo nginx -t

Once you accurately set up all configurations, the following message should appear:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

The output indicates that your Nginx configuration file has the correct syntax and passed the configuration test successfully. If errors occur, review the previous steps to ensure you entered all commands correctly and specified all file paths precisely.

Step 5: Restart Nginx to Enable ModSecurity 3 New Configuration on Debian

After verifying your configuration and ensuring there are no syntax errors, the next step is to restart the Nginx service so that the changes you’ve made will come into effect. This step is vital in rendering ModSecurity operational.

Use the systemctl command to restart the Nginx service:

sudo systemctl restart nginx

This command instructs your system to halt the Nginx service and then immediately start it up again. Consequently, your Nginx service should have an activated and operational ModSecurity WAF.

Install OWASP Core Rule Set within ModSecurity 3 on Debian 12, 11, or 10

This segment guides you through reinforcing the security of your web server by implementing the OWASP Core Rule Set (CRS) for ModSecurity. While ModSecurity is a potent tool, it doesn’t deliver protection in isolation. To function effectively, it requires a rule set.

The OWASP CRS is a renowned and trusted web application firewalls (WAFs) rule. Acting as a solid protective barrier against most contemporary threats on the internet, these rules are proficient at identifying potential attacks and preventing them. This fundamental resource is the basis for many similar systems, and by embracing it, you’re already embarking on the journey to secure your server.

Step 1: Returning to the ModSecurity Directory on Debian

As our first step, we’ll revisit the ModSecurity directory created in the previous steps. Run the command below:

cd /etc/nginx/modsec

To circumvent the need to utilize the sudo command for subsequent steps, you may optionally alter the ownership of this directory to your current user with this command:

sudo chown -R $USER:$USER /etc/nginx/modsec/

Step 2: Retrieving the OWASP CRS Archive

Next, use the wget command to fetch the OWASP CRS archive. The most recent stable release is 3.3.4 at the time of writing. However, check the OWASP Release tag page to confirm the current version.


Remember to visit the OWASP CRS release page to check for the latest stable versions. The command provided above is merely an example. Avoid copying it blindly as it may represent an outdated version.

If you prefer to stay updated with the latest developments, fetch the nightly build version. This version incorporates the most recent changes and improvements, though it may be less stable and requires frequent updates. Ideally, advanced users should use this version.


Do not download the Nightly version unless you are very experienced and also have the spare time. You will need to download these almost daily constantly!

Step 3: Extract OWASP CRS Archive on Debian

Post-download completion, use the tar command to decompress the archive:

tar -xvf v3.3.4.tar.gz

Ensure to substitute v3.3.4.tar.gz with the name of the file you’ve downloaded in case you’re utilizing a different version.

Step 4: Configure the CRS on Debian and ModSecurity 3

The OWASP CRS, similar to the ModSecurity configuration we’ve handled previously, arrives with a sample configuration file. We need to rename this file. With the help of the cp command, we’ll duplicate this file, thereby retaining the original for backup:

sudo cp /etc/nginx/modsec/coreruleset-3.3.4/crs-setup.conf.example /etc/nginx/modsec/coreruleset-3.3.4/crs-setup.conf

Step 5: Enable the OWASP CRS Rules on Debian and ModSecurity 3

To activate the OWASP CRS rules, we need to modify the modsec-config.conf file:

sudo nano /etc/nginx/modsec/modsec-config.conf

Within this file, include the subsequent two lines to incorporate the CRS configuration and rules:

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

Subsequently, save the file (CTRL+O) and exit (CTRL+X).

Screenshot showing how to add CRS rules into the modsec configuration file for Nginx, Modsecurity 3, OWASP CRS on Debian 12, 11, or 10.Pin
Example of adding CRS rules into the modsec configuration file when setting up Nginx with Modsecurity 3 and OWASP CRS on Debian 12, 11, or 10.

Remember to replace “coreruleset-3.3.4” with the version you’ve actually downloaded. Be sure to check the current release page periodically; a new stable release typically appears every 3 to 6 months.

Preserve the changes (Ctrl+O) and quit the text editor (Ctrl+X).

Step 6: Verify the Configuration and Rebooting Nginx on Debian and ModSecurity 3

Having made these substantial changes to our Nginx configuration, ensuring everything is correct and devoid of syntax errors or misconfigurations is paramount. This validation step serves as a preparatory run for the actual launch of the updated service.

To execute this “dry run”, input the following command:

sudo nginx -t

If the configuration file syntax is correct, you should see this message:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

This confirms that our configuration is accurate and that our modifications won’t disrupt service. Nevertheless, if you encounter error messages, scrutinize them meticulously for hints about potential issues. The error messages are typically quite descriptive and can steer you toward the problematic segment of your configuration files.

After successfully executing the dry run, we are ready to implement these changes live. To activate the new configuration, restart the Nginx service:

sudo systemctl restart nginx

Getting Started with OWASP Core Rule Set on Debian 12, 11, or 10 with ModSecurity 3

After successfully installing and configuring ModSecurity and the OWASP Core Rule Set (CRS) on your Debian web server, delve into the CRS’s inner workings and nuances. Understand its array of customizable options to personalize your server’s protection beyond the broad-spectrum safety that the default settings offer.

Exploring the Core Rule Set Configuration on Debian and ModSecurity 3

Open the CRS configuration file to begin your exploration. In this file, you’ll discover various settings to tweak that cater to your server’s specific needs. Access this file using the following command:

sudo nano /etc/nginx/modsec/coreruleset-3.3.4/crs-setup.conf

You’ll discover numerous settings within this configuration file, each equipped with detailed explanatory comments. This file is indeed a treasure trove of knowledge. Investing time to understand these options is crucial in gaining insights into CRS operations and tailoring them to your specifications.

Understanding Scoring Modes in the CRS on Debian and ModSecurity 3

The CRS employs a scoring system for its operation, primarily having two modes:

Anomaly Scoring Mode

# -- [[ Anomaly Scoring Mode (default) ]] --

The recommended default mode utilizes an ‘anomaly score’. Each rule that matches a request or response adds to this score. Once all inbound and outbound rules are evaluated, the system compares the total anomaly score to a preset threshold. If the score exceeds the threshold, the system triggers a disruptive action, typically resulting in an HTTP 403 error. This mode allows for flexible blocking policy settings and produces detailed audit logs.

Self-Contained Mode

# -- [[ Self-Contained Mode ]] --

This mode triggers immediate action upon any rule match, stopping further evaluation. While this method conserves resources, it reduces flexibility in blocking policies and provides less informative audit logs, logging only the first detected threat—similar to many Intrusion Detection Systems (IDS). People generally prefer the Anomaly Scoring Mode for its flexibility and informative nature.

Leveraging Paranoia Levels: Striking a Balance Between Security and Usability

One of the unique facets of the CRS is the concept of paranoia levels. These levels let you control the number of rule checks contributing to your anomaly scores, tuning the CRS’s sensitivity.

The four paranoia levels are:

  • Paranoia Level 1: The default level is most suitable for most users. It enables most core rules and minimizes the risk of false positives, i.e., legitimate requests mistakenly identified as malicious.
  • Paranoia Level 2: This level, designed for advanced users, enables extra rules such as regex-based SQL and XSS injection protections. This level may trigger some false positives.
  • Paranoia Level 3: Tailored for expert users, this level activates even more rules and imposes limits on special characters used. Be prepared to handle more false positives at this level.
  • Paranoia Level 4: This level is advised only under extraordinary circumstances. It further restricts special characters and is likely to produce many false positives.

Striking a balance between security and usability is crucial. Higher paranoia levels may offer better security but can also block legitimate traffic and trigger false alarms. If you raise the paranoia level, add exclusion rules for specific requests and applications to minimize false positives.

Customize OWASP CRS Rules to Your Needs on Debian and ModSecurity 3

The versatility of the OWASP CRS stems from its customizable nature, allowing for the creation and adjustment of rules that meet your unique requirements. Let’s explore the process of achieving this customization.

Access OWASP CRS Rule Configuration File on Debian

The CRS rules reside in the rules directory under the coreruleset-3.3.4 directory. These files house the CRS’s rules to inspect incoming and outgoing HTTP traffic. To view these files and add your custom rules, use the following command:

sudo nano /etc/nginx/modsec/coreruleset-3.3.4/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf

This command opens the file containing the exclusion rules processed before the CRS rules.

Deciphering OWASP CRS Rule Structure on Debian

Each rule within ModSecurity adheres to a unique structure. Here’s a glimpse into what a typical rule might look like:

SecRule ARGS "@rx attack" "id:1234,phase:2,t:none,log,deny,msg:'Attempted attack'"

Let’s break down the components of this rule:

  • SecRule: This directive initiates the rule.
  • ARGS: The variable under inspection. ARGS represents all arguments, including GET, POST, and cookies.
  • "@rx attack": This is the operator and its argument. @rx is a regular expression match, and attack is the pattern to match.
  • "id:1234,phase:2,t:none,log,deny,msg:'Attempted attack'": This is the action list of the rule. It includes a unique ID for the rule, the phase in which the rule operates, transformations to apply (t:none indicates no transformations), the action to be taken if the rule matches (log the event and deny the request in this case), and a message to log if the rule matches.

Create Custom Rules with OWASP CRS with ModSecurity 3 and Debian

Crafting a custom rule necessitates thoughtful consideration of the variable to inspect, the pattern to identify, and the appropriate action upon finding a match. For instance, create a rule if you wish to block requests with a specific suspicious user-agent string. This rule should scrutinize the USER_AGENT variable for the suspicious string and deny the request upon detection.

SecRule REQUEST_HEADERS:User-Agent "@rx suspicious-user-agent" "id:1235,phase:1,t:none,log,deny,msg:'Suspicious User-Agent Detected'"

This rule blocks any request with the ‘suspicious-user-agent’ string in its user-agent header.

Please remember that crafting custom rules necessitates a deep understanding of HTTP, the OWASP CRS, and your application’s behavior. Be prepared to thoroughly test and adjust your rules to avoid disrupting legitimate traffic.

Test OWASP Core Rule Set with ModSecurity 3 and Debian

After the successful configuration of OWASP CRS (Core Rule Set) on your Debian server, the next critical step is ensuring its proper implementation and functionality. This procedure lets us ascertain that the security rules we’ve deployed effectively guard our system. It is a crucial validation process that allows us to rectify any errors or issues arising during the setup process.

Step 1: Conducting a Test Request

To validate the effectiveness of our recently implemented OWASP CRS, we will use a specially designed URL intended to trigger an alert upon a rule violation. This URL contains a query string that tries to execute a specific command, an act that directly contravenes our security rules.

Here is an example of such a URL or IP Address, depending on your server setup:



Replace with your actual domain name in this URL. Try passing the /bin/bash command through the exec parameter in the query string. If your security measures work correctly, they should catch and block this action.

Understanding the Server’s Response with ModSecurity 3 and Debian

If the OWASP CRS is appropriately configured and operational on your server, it should successfully intercept this malicious request and return an 403 Forbidden error. The 403 Forbidden error signifies that the server comprehended the request but consciously refused to authorize it. In this scenario, the refusal stems from violating the ModSecurity rule.

Here’s a representation of how a 403 Forbidden response should look:

Screenshot showing a successful Modsecurity 3 block request on Debian 12, 11, or 10 using Nginx with the OWASP Core Rule Set.Pin
Example demonstrating that Modsecurity 3 correctly blocks requests when used with Nginx and the OWASP Core Rule Set on Debian 12, 11, or 10.

The image above is a visual guide illustrating the expected 403 Forbidden error page outcome. When you encounter this error during testing, it signifies the correct configuration of ModSecurity and OWASP CRS, effectively protecting your server from malicious requests.

Troubleshooting with ModSecurity 3 and Debian

If you don’t receive a 403 Forbidden error after sending a test request, you have a problem. Frequently, users forget to turn ModSecurity from DetectionOnly mode to On. In DetectionOnly mode, ModSecurity logs threats without blocking them, creating the appearance of a non-functional rule set.

Switch ModSecurity to On mode, as previously instructed in the tutorial. This change activates ModSecurity and OWASP CRS’s full protective capabilities, allowing them to actively intercept and block any request violating established rules. Follow these steps attentively to ensure your server remains well-protected against various web-based attacks.

Understand False OWASP CRS Positivies Custom Rule Exemptions with ModSecurity 3 and Debian 12, 11, or 10

One can occasionally encounter false positives when deploying OWASP CRS and ModSecurity as cybersecurity measures in the Debian environment. Managing these false positives may require a considerable amount of your time. Although this may seem demanding, its protection often justifies the time spent.

Fix False Positives with ModSecurity 3 and Debian

Striking a balance between security and usability is challenging. Setting the ModSecurity rules to an excessively high paranoia level can cause a surge in false positives. Start with a lower paranoia level. Let this setting run for weeks to months, where you’ll likely encounter few false positives. Understanding the system’s alerts and behavior during this phase is crucial. Once familiar with the system’s output, consider gradually increasing the paranoia level to prevent being overwhelmed by false positives.

Precluding Common False Positives with ModSecurity 3 and Debian

ModSecurity offers a mechanism to create an exclusion list for commonplace actions that frequently lead to false positives. This feature is particularly beneficial for applications that interact regularly with your server. The following is an example of a standard rule that formulates such exceptions:

#SecAction \
# "id:900130,\
#  phase:1,\
#  nolog,\
#  pass,\
#  t:none,\
#  setvar:tx.crs_exclusions_cpanel=1,\
#  setvar:tx.crs_exclusions_dokuwiki=1,\
#  setvar:tx.crs_exclusions_drupal=1,\
#  setvar:tx.crs_exclusions_nextcloud=1,\
#  setvar:tx.crs_exclusions_phpbb=1,\
#  setvar:tx.crs_exclusions_phpmyadmin=1,\
#  setvar:tx.crs_exclusions_wordpress=1,\
#  setvar:tx.crs_exclusions_xenforo=1"

To exempt specific applications from the rule, uncomment the corresponding lines and keep the (1) value. For applications or services you do not use, say Xenforo, modify the (1) to (0). This change ensures you do not exclude unnecessary rules.

Simplifying the Syntax with ModSecurity 3 and Debian

For a neater syntax, you can revise the command to include only the applications you intend to exempt from the rule. For instance, if your server is running WordPress, phpBB, and phpMyAdmin, the command would appear as follows:

SecAction \

Such a streamlined syntax facilitates more manageable maintenance and comprehension.

Managing Custom Exclusions with ModSecurity 3 and Debian

To accommodate custom exclusions, activate a specific file. Rename the REQUEST-900-EXCLUSION-RULES-BEFORE-CRS-SAMPLE.conf file using the cp command:

sudo cp /etc/nginx/modsec/coreruleset-3.3.4/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example /etc/nginx/modsec/coreruleset-3.3.4/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf

It’s important to note that each exclusion rule must possess a unique id. Duplication of a rule id will trigger an error during the Nginx service testing phase, causing potential disruptions to your workflow.

Whitelist Specific Paths and IP Addresses with ModSecurity 3 and Debian

Specific paths associated with some applications may consistently trigger false positives in specific scenarios. In such cases, you can whitelist these paths to prevent unnecessary alerts. Here’s how you can accomplish this:

SecRule REQUEST_URI "@beginsWith /wp-load.php?wpmudev" "id:1544,phase:1,log,allow,ctl:ruleEngine=off

SecRule REQUEST_URI "@beginsWith /ngx_pagespeed_beacon" "id:1554,phase:1,log,allow,ctl:ruleEngine=off"

In the example above, any URL that starts with the designated path will be automatically allowed, thereby minimizing false positives.

There might also be cases where you would want to whitelist specific IP addresses deemed safe. ModSecurity provides options for this:

SecRule REMOTE_ADDR "^195\.151\.128\.96" "id:1004,phase:1,nolog,allow,ctl:ruleEngine=off"

## or ###

SecRule REMOTE_ADDR "@ipMatch,," "phase:1,id:1313413,allow,ctl:ruleEngine=off"

In these examples, the @ipMatch directive can be utilized to whitelist entire subnets, adding versatility to your whitelisting approach. If you need to blacklist a specific IP address or subnet, replace allow with deny.

Perfecting Rule Exclusions

While whitelisting entire paths or IP addresses can reduce false positives, it might inadvertently permit potentially harmful requests. A more nuanced approach would be to disable specific rules that trigger false positives instead of whitelisting entire paths. This approach, although more time-consuming and testing-intensive, is often more precise.

For instance, if the rules with IDs 941000 and 942999 are continuously causing false alerts for your /admin/ area, you can disable these specific rules by using the ruleRemoveById directive as follows:

SecRule REQUEST_FILENAME "@beginsWith /admin" "id:1004,phase:1,pass,nolog,ctl:ruleRemoveById=941000-942999"

In this configuration, only the defined rules will be disabled for the /admin/ path, thereby maintaining a high degree of protection for the rest of your application.

Setup Log Rotation for ModSecurity 3 and Debian 12, 11, or 10

Properly managing your web application firewall, like ModSecurity, involves constant vigilance over the logs. Over time, these logs can swell, taking up valuable storage space on your server and complicating pinpointing specific entries for troubleshooting or security analysis. To handle this challenge, we will configure a mechanism known as log rotation.

Step 1: Create ModSecurity Log Rotation File with ModSecurity 3 and Debian

The first step in setting up log rotation is forming a configuration file. This file will establish the parameters of the log rotation. It should reside in the /etc/logrotate.d/ directory—this is where the logrotate utility scouts for its configuration files.

You can use the command below to create and edit a new file dubbed modsec:

sudo nano /etc/logrotate.d/modsec

The nano command initiates a terminal text editor, enabling you to instantly create and alter the file.

Step 2: Laying Out the Log Rotation Parameters

Within this file, we’re about to set the ground rules for the rotation of ModSecurity logs. Insert the ensuing block of code into the file:

        rotate 31

Here’s a clear breakdown of each line in the code:

  • /var/log/modsec_audit.log: Identifies the file we aim to rotate, the ModSecurity audit log.
  • rotate 31: Tells logrotate to retain 31 rotated log files before letting go of the oldest.
  • daily: Instructs logrotate to rotate the log file on a daily basis.
  • missingok: If the log file can’t be found, logrotate won’t produce an error message.
  • compress: Directs logrotate to compress the rotated log files, hence saving space.
  • delaycompress: Defers the compression of the previous log file until the next rotation cycle. Useful for when some programs are still writing to the file.
  • notifempty: If the log file is empty, logrotate will avoid rotating it.

The configuration ensures your ModSecurity logs rotate daily, with a backlog of a month’s logs. However, feel free to tweak these settings to suit your needs. If you’d prefer to maintain just a week’s logs, for instance, change rotate 31 to rotate 7. Remember, due to the enormous potential size of the logs, daily rotation for ModSecurity is recommended. Weekly log files could become quite cumbersome to manage and analyze.

Safeguarding Nginx from Updates with APT-HOLD with ModSecurity 3 and Debian 12, 11, or 10

If you neglect to use APT-HOLD and subsequently upgrade Nginx, which then breaks your webserver due to ModSecurity 3, don’t panic. Follow these steps to resolve the issue:

  1. Re-download the latest Nginx source.
  2. Re-compile the dynamic module using the upgraded version of Nginx.
  3. Move the newly built dynamic module to the same directory as before.
  4. Reboot your Nginx server.

Follow the initial steps in this guide, you can be back online in just a few minutes.

In the intricate realm of web server administration, we realize that automated system updates, although typically advantageous, may occasionally disrupt our meticulously set configurations. This is particularly true when we employ bespoke or highly specialized configurations, like the scenario of employing Nginx in conjunction with ModSecurity. Automated Nginx updates may overwrite our configurations or introduce compatibility conflicts with the existing setup. For this reason, it could be advantageous to inhibit automatic updates to Nginx. We can attain this by leveraging a function within the APT package management system called “APT-HOLD.”

Grasping the Concept of APT-HOLD

The apt-mark command is a handy utility that permits us to manage the package status within the APT package management system. One feature it provides is the “hold” option. When we mark a package with “hold,” it signifies that it’s held back—meaning it won’t be subjected to updates.

Applying APT-HOLD to Nginx

To set Nginx on hold, thus stopping it from being automatically updated, we can apply the apt-mark command as demonstrated below:

sudo apt-mark hold nginx

Following the execution of this command, the system will suppress any updates for the Nginx package until you alter this setting. This guarantees that automatic system updates keep your configuration undisturbed and unimpacted.

Reversing APT-HOLD

In the future, you might need to update Nginx to leverage new features or implement security patches. To permit updates to Nginx once more, you can lift the hold using the unhold option:

sudo apt-mark unhold nginx

This action reverts the package to its regular status, where it will be updated during your next system’s package update when you’re prepared to manage potential complications between Nginx and ModSecurity, such as recompiling.

Conclusion and Final Thoughts

In this comprehensive guide, we’ve successfully navigated the technical and intricate process of installing ModSecurity 3 and OWASP CRS with Nginx on a Debian distribution. This endeavor substantially enhanced our web server’s security, providing robust defense mechanisms against various vulnerabilities and malicious activities. We explored essential aspects, including configuration, tuning, logging, log rotation, and expertly handling package updates to safeguard our unique setups. Understanding that this guide is not the end but rather a stepping stone towards continually learning and refining your server management skills is pivotal.

Share to...