ModSecurity 3 is a powerful open-source Web Application Firewall (WAF) that safeguards web applications from various threats. This guide will walk you through the steps to install Modsecurity 3, OWASP CRS with Nginx on Ubuntu 22.04 Jammy Jellyfish or its older stable release of Ubuntu 20.04 Focal Fossa.
Key Advantages of ModSecurity 3:
- Advanced Protection: ModSecurity 3 defends web applications against attacks, including SQL injection, Cross-Site Scripting (XSS), and Local File Inclusion (LFI).
- Seamless NGINX Integration: It integrates seamlessly with NGINX, enhancing security without sacrificing performance.
- Custom Rule Support: Users can implement custom rulesets, tailoring security measures to meet the specific needs of each web application.
- Detailed Logging: With comprehensive logs of all HTTP transactions, it facilitates efficient traffic monitoring and the identification of potential security threats.
- Open-Source & Community-Driven: Supported by a vibrant community, ModSecurity 3 is continuously improved, providing a transparent and adaptable security solution.
Deploying ModSecurity 3 with NGINX on Ubuntu 22.04 Jammy Jellyfish or Ubuntu 20.04 Focal Fossa offers an effective security solution for your web applications. Follow this guide for detailed installation instructions, laying the groundwork for robust web application security.
Pre-installation Steps For Modsecurity 3 with Nginx on Ubuntu 22.04 or 20.04
Before beginning the ModSecurity installation, prepare your server for the upcoming tasks. Update your system and ensure you have the latest version of Nginx, a high-performance web server and reverse proxy server, to minimize compatibility issues and security vulnerabilities, smoothing the installation process.
Step 1: Update Ubuntu Before Modsecurity 3 Installation
The first step towards a secure and efficient server is keeping it up-to-date. This ensures all software packages have the latest security patches and performance improvements. Execute the following command to update your system:
sudo apt update && sudo apt upgrade
This command first updates the package lists for upgrades (sudo apt update
).
Step 2: Remove Pre-existing Nginx Installation (Situational)
If you have a pre-existing Nginx installation, we recommend removing it and installing the latest version from a custom PPA maintained by Ondřej Surý. This version has additional dynamic modules, such as the Brotli module, for improved compression.
First, stop the current Nginx service with the following:
sudo systemctl stop nginx
Then, remove the existing Nginx installation with the following commands:
sudo apt purge nginx -y && sudo apt autoremove nginx -y
Here, the purge
option completely removes the Nginx package and its configuration files. The autoremove
command removes any packages that were automatically installed to satisfy Nginx’s dependencies but are no longer needed.
Step 3: Add the Latest Nginx PPA (Optional)
Remove the outdated Nginx service, then add a new, current PPA (Personal Package Archive) for Nginx. Choose between a stable or mainline version; opt for the mainline version to access the latest features and improvements.
To add the stable PPA, execute:
sudo add-apt-repository ppa:ondrej/nginx-stable -y
Or for the mainline PPA, use:
sudo add-apt-repository ppa:ondrej/nginx-mainline -y
Step 4: Update Packages Index After Nginx PPA Import on Ubuntu
After importing the desired repository, updating your APT sources list is necessary. This ensures the system knows about the new packages in the added repository. Update your sources list with the following:
sudo apt update
Now, install Nginx with the following command:
sudo apt install nginx
During the installation, you may be prompted to keep or replace your existing /etc/nginx/nginx.conf
configuration file. It’s generally recommended to keep your current configuration file by pressing n
.
Step 5: Uncomment DEB-SRC Nginx Source on Ubuntu
The PPA installation process does not include the Nginx source code by default. You must enable a specific feature and manually download the Nginx source code to compile Modsecurity later in this tutorial.
Open the configuration file located in /etc/apt/sources.list.d
:
sudo nano /etc/apt/sources.list.d/ondrej-ubuntu-nginx-mainline-*.list
Find the line that starts with # deb-src
and uncomment it (i.e., remove the #
). If you use a different third-party repository, replace the path in the command with the appropriate one:
# deb-src http://ppa.launchpad.net/ondrej/nginx-mainline/ubuntu/ jammy main
Once done, save the file by pressing CTRL+O
and then exit by pressing CTRL+X
.
If you’re more comfortable with command-line utilities, you can also use the sed
command to uncomment the source line:
sudo sed -i 's/# deb-src/deb-src/g' /etc/apt/sources.list.d/ondrej-ubuntu-nginx-mainline-*.list
Finally, update the repository list using the following command:
sudo apt update
This command ensures that your system acknowledges adding the Nginx source code to the repository, making it available for further operations.
Download Nginx Source Code on Ubuntu
To seamlessly integrate ModSecurity with Nginx, we must compile the ModSecurity dynamic module against the Nginx source code. To do this, we first need to download and store the Nginx source code in a specific directory (/usr/local/src/nginx
). This section walks you through creating the necessary directories, installing dependencies, downloading the source code, and verifying that the source version matches the installed Nginx version.
Step 1: Create Directory Structure
First, create a directory to download and store the Nginx source code. Here’s the command to create the directory and navigate into it:
sudo mkdir /usr/local/src/nginx && cd /usr/local/src/nginx
This command creates the directory /usr/local/src/nginx
and then changes the current directory to this newly created directory.
Step 2: Install Required Packages and Download Nginx Source
Before we can download the source code, we need to install a package called dpkg-dev
. This package provides several development tools to unpack, build, and upload Debian source packages. Install it with the following command:
sudo apt install dpkg-dev -y
We’re ready to download the Nginx source code with the necessary tools. Use the following command to accomplish this:
sudo apt source nginx
While running this command, you might encounter an error message. Don’t worry; this error message can be safely ignored.
Step 3: Verifying the Source Version on Ubuntu
After downloading the source code, it’s essential to ensure that the downloaded source version matches the installed Nginx version. Differences between these versions can lead to compatibility issues, so this verification step is crucial.
First, list the files in the current directory to confirm you have downloaded the source code:
ls
You should see several files and directories related to Nginx in the output.
Next, confirm that the source package matches the Nginx version installed on your Ubuntu system. You can check the installed Nginx version with the following command:
The output will display your installed Nginx version. Ensure this version matches the source version you’ve downloaded. If they don’t match, you’ll need to download the correct version of the Nginx source code.
nginx -v
The output will display your installed Nginx version. Ensure this version matches the source version you’ve downloaded. If they don’t match, you’ll need to download the correct version of the Nginx source code.
Install libmodsecurity3 for ModSecurity 3 on Ubuntu 22.04 or 20.04
ModSecurity is an effective firewall for web applications, and libmodsecurity3 is its core component that handles HTTP filtering. This section will guide you through obtaining and installing this essential software package.
Step 1: Clone the ModSecurity 3 Repository on Ubuntu
First, fetch the libmodsecurity3 source code from its GitHub repository using Git, a popular distributed version control system. If your system doesn’t already have Git installed, use the following command to add it:
sudo apt install git
Before we clone the repository, it’s a good practice to adjust the ownership of the directory to avoid the need for root privileges (sudo
) for most commands:
sudo chown -R $user:$user /usr/local/src/
his command recursively changes the ownership of /usr/local/src/
directory to the current user.
Next, let’s clone the libmodsecurity3
repository. We’ll use a shallow clone (--depth 1
) to save bandwidth and storage. This means we’ll only fetch the latest revision of the v3/master
branch:
git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity /usr/local/src/ModSecurity/
After cloning the repository, change your working directory to the newly cloned repository:
cd /usr/local/src/ModSecurity/
Step 2: Install libmodsecurity3 Dependencies on Ubuntu
The compilation of libmodsecurity3
requires several dependencies. Install them with the following command:
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 libpcre++-dev libpcre2-16-0 libpcre2-dev libpcre2-posix3 -y
To successfully compile Nginx with ModSecurity 3 from version 1.21.4 onwards, you must have these dependencies. Although this step can cause issues, installing the correct dependencies will resolve them in nearly all circumstances.
Next, initialize and update the Git submodules with the following commands:
git submodule init
git submodule update
Step 3: Build ModSecurity Environment on Ubuntu
Now that we’ve prepared our workspace, it’s time to build the ModSecurity environment. First, run the build script:
./build.sh
Then, configure the environment:
./configure
During this process, you may encounter an error stating fatal: No names found, cannot describe anything
. Don’t worry this error message can be safely ignored.
Step 4: Compile the ModSecurity Source Code on Ubuntu
Having built and configured the environment for libmodsecurity3
, we’re ready to compile it. Here’s the command to do so:
make
For those working on high-performance servers, you can speed up the compilation process by running make
with the -j
option followed by the number of CPU cores your server has. For instance, if your server has six CPU cores, you could use:
make -j 6
Step 5: Install Compiled Code For Modsecurity 3 on Ubuntu
After compiling the source code, the last step is to install it:
sudo make install
This command installs libmodsecurity3
to /usr/local/modsecurity/
, which is the directory you’ll reference later in this guide.
Install ModSecurity-nginx Connector on Ubuntu 22.04 or 20.04
In this section, we’ll guide you through installing the ModSecurity-nginx connector. This vital component is the liaison between Nginx, a popular web server software, and ModSecurity, ensuring seamless communication.
Step 1: Clone the ModSecurity-nginx Repository on Ubuntu
First, we need to fetch the source code of the ModSecurity-nginx connector. We do this by cloning the repository from GitHub. Similar to the previous step of cloning the libmodsecurity3
repository, use the following command to clone the ModSecurity-nginx repository:
git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git /usr/local/src/ModSecurity-nginx/
This command fetches only the latest revision of the ModSecurity-nginx repository, saving bandwidth and storage.
Step 2: Install ModSecurity-nginx Dependencies on Ubuntu
Next, we need to navigate to the Nginx source directory. You can do this by executing the following cd
command:
cd /usr/local/src/nginx/nginx-1.*.*
In the Nginx source directory, we’ll install the dependencies required for the ModSecurity-nginx connector. Run this command to fetch and install the necessary dependencies:
sudo apt build-dep nginx && sudo apt install uuid-dev
Step 3: Compile ModSecurity-nginx Connector
With the dependencies in place, we can compile the ModSecurity-nginx connector. For this, we need to run 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 ensures compatibility with various systems, while the --add-dynamic-module
option specifies the location of the ModSecurity-nginx connector.
After configuring the environment, create the dynamic modules by running the make
command:
make modules
At the end of the process, your terminal should see something similar:
Step 4: Moving the Dynamic Module on Ubuntu
The final step in this process is moving the dynamic module to the appropriate directory. The make modules
command creates a dynamic module at the location objs/ngx_http_modsecurity_module.so
. You need to move this module to the /etc/nginx/modules/
directory. Use the following command to accomplish this:
sudo cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules/
It’s important to note that you can store the dynamic module anywhere, provided you specify the full path when loading it.
Configure the ModSecurity-nginx Connector with Nginx on Ubuntu 22.04 or 20.04
After successfully installing the ModSecurity-nginx connector, load and appropriately configure it into Nginx. Edit your Nginx configuration file at /etc/nginx/nginx.conf to make ModSecurity 3 operational with your Nginx web server.
Step 1: Enable ModSecurity in nginx.conf
To start, you need to specify the location of the ModSecurity module in the nginx.conf
file. To do this, open the nginx.conf
file using a text editor. For this example, we’ll be using nano
:
sudo nano /etc/nginx/nginx.conf
At the top of the file, add the following line:
load_module modules/ngx_http_modsecurity_module.so;
This command instructs Nginx to load the ModSecurity module. If you stored the module in a different location, include the full path in this command.
Next, add the following code under the http {}
section:
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/modsec-config.conf;
The above commands enable ModSecurity and specify the location of the ModSecurity rules file. Save the changes (Ctrl+O
) and exit the file (Ctrl+X
).
Step 2: Create Directory and Files for ModSecurity 3 on Ubuntu
You need to create a directory to store configuration files and future rules. The following command will create the /etc/nginx/modsec
directory:
sudo mkdir /etc/nginx/modsec/
Next, copy the sample ModSecurity configuration file from the cloned Git directory to the directory you’ve just created:
sudo cp /usr/local/src/ModSecurity/modsecurity.conf-recommended /etc/nginx/modsec/modsecurity.conf
Now, let’s modify the modsecurity.conf
file. By default, the ModSecurity rule engine operates in DetectionOnly
mode, which detects malicious behavior but does not block it. To change this behavior, open the modsecurity.conf
file:
sudo nano /etc/nginx/modsec/modsecurity.conf
Locate the line SecRuleEngine DetectionOnly
and change it to:
SecRuleEngine On
Next, locate the SecAuditLogParts
line:
# Log everything we know about a transaction.
SecAuditLogParts ABIJDEFHZ
The current configuration is not correct. Modify the line to the following:
SecAuditLogParts ABCEFHJKZ
Now, save (Ctrl+O
) and exit (Ctrl+X
) the file.
Step 3: Create modsec-config.conf File on Ubuntu
The next step is to create a modsec-config.conf
file. This file will include the modsecurity.conf
file and other rule sets, such as the OWASP CRS, later on. Create and open the file with this command:
sudo nano /etc/nginx/modsec/modsec-config.conf
Once inside the file, add the following line:
Include /etc/nginx/modsec/modsecurity.conf
Save (Ctrl+O
) and exit (Ctrl+X
) the file.
Finally, copy ModSecurity’s unicode.mapping
file using the cp
command:
sudo cp /usr/local/src/ModSecurity/unicode.mapping /etc/nginx/modsec/
Step 4: Validating Nginx Modsecurity 3 Configuration on Ubuntu
Before proceeding, it’s crucial to validate your configuration. Run the following command to perform a dry run of the Nginx service:
sudo nginx -t
If you have set up everything correctly, 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 confirms that the syntax in your Nginx configuration file is correct, signaling a successful configuration test. Review the previous steps, ensuring accurate command entry and file paths should you encounter errors.
Step 5: Apply Configuration Changes with Nginx on Ubuntu
Once you’ve validated your configuration and ensured no syntax errors, you need to restart the Nginx service for the changes to take effect. This is a critical step in making ModSecurity operational.
Use the systemctl
command to restart the Nginx service:
sudo systemctl restart nginx
This command instructs your system to stop and immediately start the Nginx service. With this, your Nginx service should now have the ModSecurity WAF enabled and operational.
Install OWASP Core Rule Set for ModSecurity 3 on Ubuntu 22.04 or 20.04
This section will enhance our web server’s security by deploying the OWASP Core Rule Set (CRS) for ModSecurity. While ModSecurity 3 is powerful, it requires a set of rules to function effectively.
The OWASP CRS offers a respected and widely accepted set of rules for web application firewalls (WAFs), serving as a robust protective barrier against most emerging internet threats. It identifies and blocks potential attacks, providing a fundamental resource upon which many similar systems build their rules. Adopting the OWASP CRS sets you on the right path to securing your server.
Step 1: Navigate to ModSecurity 3 Directory on Ubuntu
To begin, we need to navigate back to the ModSecurity directory we created in the previous steps:
cd /etc/nginx/modsec
Optionally, you can change the ownership of this directory to your current user to avoid having to use the sudo
command for subsequent steps:
sudo chown -R $USER:$USER /etc/nginx/modsec/
Step 2: Download OWASP CRS Archive on Ubuntu
Next, we’ll download the OWASP CRS archive using the wget
command. The latest stable release is 3.3.4 at the time of writing, but you should check the OWASP Release tag page for the most recent version.
wget https://github.com/coreruleset/coreruleset/archive/refs/tags/v3.3.4.tar.gz
Be sure to change the above command’s v3.3.4 to either 3.3.5 or 3.3.6 in the future, always confirm you have the latest stable release! The command provided above serves as an example only.”
Download the nightly build version to stay updated with the latest developments. This version includes the most recent changes and improvements. However, it may be less stable and will require frequent updates. Only advanced users should use this version.
wget https://github.com/coreruleset/coreruleset/archive/refs/tags/nightly.tar.gz
Opt for the nightly version only if you are confident in your ability to navigate through frequent updates and false positives vigilantly. Under most circumstances, it is advisable to use the latest stable release.
Step 3: Extract OWASP Core Rule Set Archive on Ubuntu
Once the download is complete, extract the archive using the tar
command:
tar -xvf v3.3.4.tar.gz
Remember to replace v3.3.4.tar.gz
with the name of the file you downloaded if you’re using a different version.
Step 4: Configure OWASP CRS on Ubuntu
Like the ModSecurity configuration we dealt with earlier, the OWASP CRS has a sample configuration file we need to rename. Using the cp
command, we’ll create a copy of this file, preserving the original as a 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 OWASP CRS Rules with Modsecurity 3 on Ubuntu
To enable the OWASP CRS rules, we need to modify the modsec-config.conf
file:
sudo nano /etc/nginx/modsec/modsec-config.conf
In this file, add the following two lines to include 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
Save the file (CTRL+O) and exit (CTRL+T).
Remember to replace coreruleset-3.3.4
with the version you downloaded if it’s different.
Save the changes (Ctrl+O) and exit the text editor (Ctrl+X).
sudo nginx -t
Step 6: Validating the Configuration and Restarting Nginx
Now that we’ve made these significant changes to our Nginx configuration, we must validate everything to ensure no syntax errors or misconfigurations. This validation step is like a “dress rehearsal” for the actual launch of the updated service.
To perform this “dry run”, use the following command:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
This message tells us that our configuration is correct and that our changes will not disrupt service.
However, if you encounter error messages, carefully review them for clues about what might have gone wrong. The error messages are often informative and can guide you toward the problematic section of your configuration files.
We are ready to make these changes live with the successful dry run. For the new configuration to take effect, we need to restart the Nginx service:
sudo systemctl restart nginx
Understanding and Utilizing the OWASP Core Rule Set with Modsecurity 3 and Ubuntu
With the installation and setup of ModSecurity and the OWASP Core Rule Set (CRS) on your Nginx web server completed, it’s time to delve deeper into understanding and making use of the CRS. The CRS is rich with options, and while the default settings provide immediate, broad-spectrum protection for most servers, thoroughly exploring its capabilities will help you fine-tune its functionality to suit your specific needs.
Navigate CRS Configuration
For a start, let’s familiarize ourselves with the CRS configuration file. This is where you can tweak the various settings provided by the CRS. To open the configuration file, use the following command:
sudo nano /etc/nginx/modsec/coreruleset-3.3.4/crs-setup.conf
This file contains many options, each with detailed comments explaining their functions. Dive into this wealth of information to gain invaluable insights into the CRS’s operation and discover how to tailor it to meet your requirements.
Scoring Modes in OWASP CRS
The CRS operates using a scoring system. There are two primary modes of operation:
Anomaly Scoring Mode
# -- [[ Anomaly Scoring Mode (default) ]] --
The recommended mode is the default. Each matching rule for a request or response in this mode increases an ‘anomaly score’. After evaluating all inbound and outbound rules, the system checks the total anomaly score against a threshold. If the score surpasses the threshold, it triggers a disruptive action—typically returning an HTTP 403 error. This mode allows for flexible blocking policy settings and generates informative audit logs.
Self-Contained Mode
# -- [[ Self-Contained Mode ]] --
When a rule matches this mode, the system immediately stops further evaluation. This mode reduces resource usage, offers less flexibility in blocking policy, and produces less informative audit logs. The system logs only the first detected threat, mirroring many Intrusion Detection Systems (IDS). Generally, we recommend Anomaly Scoring Mode for most users for its flexibility and informative nature.
Paranoia Levels: Balancing Security and Usability
A unique feature of the CRS is its paranoia levels. These levels allow you to control how many rule checks contribute to your anomaly scores, essentially letting you tune the sensitivity of the CRS.
There are four paranoia levels:
- Paranoia Level 1: The default level recommended for most users. It enables most core rules and should rarely trigger false positives (FPs) or legitimate requests mistakenly identified as malicious.
- Paranoia Level 2: Designed for advanced users, this level enables additional rules, such as regex-based SQL and XSS injection protections. Some false positives may occur at this level.
- Paranoia Level 3: For expert users, this level enables even more rules and limits on special characters used. Expect to handle more false positives at this level.
- Paranoia Level 4: Only recommended for exceptional circumstances. This level restricts special characters further and is likely to produce many false positives.
Paranoia levels help strike a balance between security and usability. While high paranoia levels offer enhanced security, they may block legitimate traffic and trigger false alarms. If you choose to increase the paranoia level, plan to implement exclusion rules for specific requests and applications to minimize false positives.
Customizing OWASP CRS Rules (Additional Learning)
An advantage of the OWASP CRS is its flexibility, allowing you to create and modify rules to meet your needs. Let’s take a closer lLet’st how you might approach this task.
Opening the Rule Files
The rule files are located in the rules
directory under the coreruleset-3.3.4
directory. These files contain rules the CRS uses to inspect incoming and outgoing HTTP traffic. You can open these files to view the existing rules and add custom ones.
sudo nano /etc/nginx/modsec/coreruleset-3.3.4/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
This opens the file containing the exclusion rules processed before the CRS rules.
Understanding Rule Structure
Each rule in ModSecurity has a unique structure. A typical rule might look like this:
SecRule ARGS "@rx attack" "id:1234,phase:2,t:none,log,deny,msg:'Attempted attack'"
Here’s a brief breakdown of the rules components:
SecRule
: The directive that begins the rule.ARGS
: The variable to be inspected.ARGS
refers to all arguments, including GET, POST, and cookies."@rx attack"
: The operator and its argument.@rx
is a regular expression match, andattack
is the pattern to match."id:1234,phase:2,t:none,log,deny,msg:'Attempted attack'"
: The rule’s action list. Includes a unique ID for the rule, the phase in which the rule operates, transformations to apply (t:none
means no transformations), the action to take if the rule matches (in this case, log the event and deny the request), and a message to log if the rule matches.
Creating Custom Rules
To create a custom rule, decide which variable to inspect, identify the pattern to search for, and determine the action to take upon finding a match. For instance, if you wish to block requests with a particular suspicious user-agent string, create a rule that examines the USER_AGENT variable for the suspicious string and denies 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 will block requests with the ‘suspicious-user-agent” string in its user-‘gent header.
To create custom rules, you must thoroughly understand HTTP, the OWASP CRS, and your application’s behavior and adjust as needed to prevent disruption to legitimate traffic.
Verifying OWASP CRS Implementation with Modsecurity 3 on Ubuntu 22.04 or 20.04
After successfully setting up the OWASP CRS on your server, it’s vital to test implementation to ensure it’s functioning as intended. This step is crucial as it verifies the effective deployment of the security rules and allows troubleshooting any potential issues that might have occurred during the setup.
Performing a Test Request to the Webserver
To confirm the efficacy of the OWASP CRS, craft a specific URL designed to trigger an alert with correct rule implementation. This URL should include a query string that tries to execute a command, clearly violating security rules.
https://www.yourdomain.com/index.html?exec=/bin/bash
Replace yourdomain.com
with your actual domain name. This URL attempts to pass the /bin/bash
command through the exec
parameter in the query string.
Interpreting the Response
If OWASP CRS is correctly set up and operational, it should identify this malicious request and respond with a 403 Forbidden
error. This error implies that the server understood the request but refused to authorize it, which in this case, is a result of the ModSecurity rule violation.
The image above shows a 403 Forbidden error page, which you should see if you’ve properly confiyou’veModSecurity and OWASP CRS. This configuration actively protects your server from malicious requests.
Troubleshooting
If you don’t receive a 403 Forbidden
error indicates that something is amiss. The most common issue is forgetting to switch ModSecurity from DetectionOnly
mode to On
. DetectionOnly
mode logs the threats but doesn’t block them.
Dealing with False Positives and Custom Rule Exclusions with Modsecurity 3, OWASP CRs on Ubuntu 22.04 or 20.04
In the realm of cybersecurity, the deployment of the OWASP CRS alongside ModSecurity often serves as an effective line of defense. However, it can lead to instances of false positives, which can consume a significant amount of your time to manage. Though potentially overwhelming, this time expenditure is often justified by the valuable protection provided.
Navigating False Positives
Striking a delicate balance between security and usability is crucial. Setting the paranoia level of ModSecurity rules too high may yield many false positives. Therefore, it is wise to begin with a lower paranoia level. This approach minimizes false positives, allowing the rule set to operate for several weeks to months. You will become familiar with the system’s behavior and systems during this initial phase. Once comfortable with the output, gradually increase the paranoia level to prevent a sudden flood of false positives.
Excluding Common False Positives
ModSecurity offers a mechanism for whitelisting common actions that often trigger false positives. This feature proves especially useful for applications interacting frequently with your server.
Below is an example of a default rule that whitelists these actions:
#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 whitelist certain applications, uncomment the corresponding lines and leave the (1)
number intact. For services that you do not use, for instance, Xenforo, change the (1)
to (0)
. This action ensures that you do not whitelist unnecessary rules.
Streamlining the Syntax
For a cleaner syntax, you can modify the command to include only the applications you wish to whitelist. For example, if you use WordPress, phpBB, and phpMyAdmin, the command would look like this:
SecAction \
"id:900130,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.crs_exclusions_phpbb=1,\
setvar:tx.crs_exclusions_phpmyadmin=1,\
setvar:tx.crs_exclusions_wordpress=1"
This streamlined syntax makes it easier to read and maintain.
Addressing Custom Exclusions
To handle custom exclusions, you need to activate a specific file. This step involves renaming the REQUEST-900-EXCLUSION-RULES-BEFORE-CRS-SAMPLE.conf
file using the cp
command:
sudo cp /etc/nginx/modsec/coreruleset-3.4-dev/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example /etc/nginx/modsec/coreruleset-3.4-dev/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
Each exclusion rule must have a unique id. Repeating a rule id will cause an error during the Nginx service testing phase.
Whitelisting Specific Paths and IP Addresses
There are instances where specific paths, often associated with certain applications, tend to trigger false positives. In such situations, you can whitelist these paths to eliminate unnecessary alerts. Here’s how you can do it:
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"
The specified path will automatically allow any URL that begins with it, reducing false positives in the above example.
You may occasionally need to whitelist certain IP addresses known to be safe. ModSecurity offers options for this task.
SecRule REMOTE_ADDR "^195\.151\.128\.96" "id:1004,phase:1,nolog,allow,ctl:ruleEngine=off"
## or ###
SecRule REMOTE_ADDR "@ipMatch 127.0.0.1/8, 195.151.0.0/24, 196.159.11.13" "phase:1,id:1313413,allow,ctl:ruleEngine=off"
In these examples, the @ipMatch
directive can be used to whitelist entire subnets, increasing the versatility of your whitelisting strategy. If you need to blacklist a specific IP address or subnet, replace allow
with deny
.
Refining Rule Exclusions
While whitelisting entire paths or IP addresses can reduce false positives, it might also unintentionally allow potentially harmful requests. A more precise approach is to disable specific rules that trigger false positives, rather than whitelisting entire paths. However, this approach requires more time and testing to fine-tune.
For instance, let’s say the rules wlet’sDs 941000 and 942999 keep triggering false alerts for your /admin/
area. You can disable these specific rules by using the ruleRemoveById
directive as shown below:
SecRule REQUEST_FILENAME "@beginsWith /admin" "id:1004,phase:1,pass,nolog,ctl:ruleRemoveById=941000-942999"
With this configuration, only the specified rules will be disabled for the /admin/
path, maintaining high protection for the rest of your application.
Configure Log Rotation for ModSecurity 3 on Ubuntu 22.04 or 20.04
When working with a web application firewall like ModSecurity 3, keeping an eye on the logs is crucial. However, these logs can quickly grow, potentially taking up significant storage space on your server. This growth can also make it more difficult to find specific entries when troubleshooting or analyzing security events. To manage this, we can set up a process known as log rotation.
Creating the ModSecurity Log Rotation File
To begin with, let’s create a configuration file for the log rotation process. This file will define how and when the log rotation happens. We can place this file in the /etc/logrotate.d/
directory, which is where the logrotate
utility looks for its configuration files.
Use the following command to create and open a new file called modsec
:
sudo nano /etc/logrotate.d/modsec
The nano
command launches a text editor in the terminal, allowing you to create and edit the file directly.
Defining the Log Rotation Rules
In this file, we will define rules for rotating the ModSecurity logs. Copy and paste the following block of code into the file:
/var/log/modsec_audit.log
{
rotate 31
daily
missingok
compress
delaycompress
notifempty
}
Let’s break down what each line in this block of code does:
/var/log/modsec_audit.log
: This is the file that we want to rotate. It’s the location of the ModSecurity audit log.rotate 31
: This directive means thatlogrotate
should keep 31 rotated log files before discarding the oldest ones.daily
: This instructslogrotate
to rotate the log file once every day.missingok
: If the log file is missing,logrotate
will not output an error message.compress
: This directive tellslogrotate
to compress the rotated log files to save space.delaycompress
: This postpones compression of the previous log file to the next rotation cycle. This can be helpful if some programs are still writing to the file.notifempty
: If the log file is empty,logrotate
will not rotate it.
These settings rotate your ModSecurity logs daily, maintaining a month’s worth of logs the settings to meet your needs. For instance, to keep only a week’s worth of logs, weeks rotate from 31 to 7. However, managing and analyzing a weekly log file can be cumbersome due to its potentially large size, so daily rotation is recommended for ModSecurity.
Prevent Nginx Updates with APT-HOLD on Ubuntu 22.04 or 20.04
As we navigate the complex world of managing web servers, it’s important to recognize that while generally beneficial, automated system updates can sometimes interfere with our carefully configured setups. This is especially true when we have customized or highly specific configurations, like Nginx with ModSecurity. In such cases, automated updates to Nginx can potentially overwrite our configurations or introduce compatibility issues with the current setup. Hence, it might be beneficial to prevent automatic updates to Nginx. We can achieve this by using the APT package management system feature known as “APT-HOLD”.
Understanding APT-“OLD
The apt-mark command, a utility within the APT package management system, lets users manipulate package status. Its “hold” option marks “packages” as held back, preventing their update.
Applying APT-HOLD to Nginx
To put Nginx on hold and thus prevent it from being automatically updated, we can use the apt-mark
command as follows:
sudo apt-mark hold nginx
After running this command, the system will hold back any updates for the Nginx package until you manually change this setting. This will ensure that automatic system updates keep your configuration intact and unaffected.
Reverting APT-HOLD
You may need to update Nginx at some point, perhaps to leverage new features or implement security patches. Remove the hold on Nginx updates by using the unhold option:
sudo apt-mark unhold nginx
This action returns the package to regular status, allowing updates the next time you upgrade your system’s packages and systems any issues between Nginx and Modsecurity, such as recompiling.
Closing Thoughts
Through our proactive journey, we have effectively incorporated ModSecurity 3, installed it seamlessly with Nginx, and implemented the OWASP CRS on an Ubuntu Linux system, establishing a sturdy, open-source firewall for our server. This integration not only fortifies our defense against various web-based attacks but also significantly enhances the security of our web applications, ensuring the safekeeping of our operations and data. Each stage of this process was crucial, from prerequisite setup and ModSecurity installation to Nginx configuration and OWASP CRS implementation. We also developed proficiency in managing ModSecurity-generated logs and optimizing their sizes for peak performance while securing our specific Nginx configuration by deactivating automatic updates. This comprehensive and meticulous approach was indispensable in achieving the highest level of security for our setup.