ModSecurity, often referred to as Modsec, is a free, open-source web application firewall (WAF). ModSecurity was created as a module for the Apache HTTP Server. However, since its early days, the WAF has grown and now covers an array of HyperText Transfer Protocol request and response filtering capabilities for various platforms such as Microsoft IIS, Nginx, and Apache.
How the WAF works, the ModSecurity engine is deployed in front of the web application, allowing the engine to scan the incoming and outgoing HTTP connections. ModSecurity is most commonly used in conjunction with the OWASP Core Rule Set (CRS), an open-source set of rules written in ModSecurity’s SecRules language, and is highly regarded in the security industry.
OWASP Rule Set with ModSecurity can almost instantly help protect your server against the following:
- Bad user agents
- DDOS
- Cross website scripting
- SQL injection
- Session hijacking
- Other Threats
The following tutorial will teach you how to install ModSecurity with Nginx on Fedora Linux, such as a server, along with the core rule setup, which features various options such as importing the currently nightly build rules for OWASP core rule set or using the standard stable release schedule rules.
Install Nginx or Nginx Mainline
The first step is installing the Nginx, which can be done with the following terminal command. This section can be skipped for users with Nginx installed, and you can begin downloading the Nginx source.
sudo dnf install nginx
Confirm the installation by checking the build version.
nginx -v
Example output:
nginx version: nginx/1.22.1
The standard installation of Nginx with Fedora will always install the stable version first. For users who want to install Nginx mainline instead, follow on to learn how to switch the versions.
dnf module list nginx
Example output:
As you can see, the Fedora repository contains both stable and mainline.
If you want to use the Nginx mainline, remove the regular version.
Back up configuration files before removing Nginx if it was an existing installation. This is useful if you require configuration files, given that some users have many configurations. I recommend doing this before removing or re-installing in case these get lost.
sudo cp /etc/nginx/ /etc/nginx-backup/
Once you have backed up your Nginx folder, run the following removal command.
sudo dnf autoremove nginx
Now enable Nginx mainline.
sudo dnf module enable nginx:mainline -y
Once enabled, proceed to install the Nginx mainline.
sudo dnf install nginx -y
Confirm the installation by checking the build version:
nginx -v
Example output:
nginx version: nginx/1.23.2
At the time of this tutorial, you can see the difference between Nginx mainline being at 1.23.2 and the stable version at 1.22.1.
Next, you must start and enable Nginx by using the following command.
sudo systemctl enable nginx --now
Example of successfully enabling (symlink):
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
Now, check the status of your Nginx service with the following terminal command.
systemctl status nginx
Now, you can confirm that your Nginx webserver is operational by entering (HTTP://server-ip) or (HTTP://domain-name if setup) in your Internet Browser, and you should get the following:

Configure Firewalld for Nginx
If you are not replacing an existing Nginx service and installing Nginx for the first time, you may need to configure the firewall for HTTP and HTTPS traffic. An example of how to do this is below:
Allow HTTP traffic with the following command
sudo firewall-cmd --permanent --zone=public --add-service=http
Allow HTTPS traffic with the following command
sudo firewall-cmd --permanent --zone=public --add-service=https
Once done, you need to make the changes effective by reloading the firewall:
sudo firewall-cmd --reload
Download Nginx Source
You must download the Nginx source code to compile the ModSecurity dynamic module. You must download and store the source package in the directory location /etc/local/src/nginx.
Create and Configure Directories
Create the location as follows:
sudo mkdir /usr/local/src/nginx && cd /usr/local/src/nginx
Optional – Assign permission to the directory if needed as below.
sudo chown $USER:$USER /usr/local/src/ -R
Download Source Archive
The next step is to download the Nginx source archive from the downloads page to match the Nginx version you identified earlier. Even if you did not update to the latest version of stable or mainline Nginx and use an older version, you should be able to find a source to match your own.
Download the source using the wget command. The tutorial will demonstrate using Nginx Mainline from the Fedora repository.
wget http://nginx.org/download/nginx-{version}.tar.gz
For example, do not copy:
wget https://nginx.org/download/nginx-1.23.2.tar.gz
Next, extract the archive as follows.
tar -xvzf nginx-1.23.2.tar.gz
Verify Source Version
Next, list the directories files with the ls command.
ls
Example output in your /usr/src/local/nginx directory.
Next, confirm that the source package is the same as the Nginx version installed on your system in case you already had Nginx installed. It is worth double-checking before proceeding to ensure you have not downloaded the wrong version and waste time.
Use the following nginx -v command.
nginx -v
You should get the same output version as the source as follows:
nginx version: nginx/1.23.2
Install libmodsecurity3 for ModSecurity
The package libmodsecurity3 is the fundamental part of the WAF that does the HTTP filtering for your web applications. You will compile from the source.
Clone ModSecurity Repository from GitHub
The first step is the clone from Github, and if you do not have git installed, you will need to execute the following command:
sudo dnf install git -y
Next, clone the libmodsecurity3 GIT repository as follows:
git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity /usr/local/src/ModSecurity/
Once cloned, you must navigate to the directory you just cloned.
cd /usr/local/src/ModSecurity/
Install libmodsecurity3 Dependencies
To compile, you will need to install the following dependencies as follows:
sudo dnf install gcc-c++ flex GeoIP-devel doxygen yajl-devel bison yajl curl-devel zlib-devel pcre-devel autoconf automake git curl make libxml2-devel pkgconfig libtool httpd-devel redhat-rpm-config wget openssl openssl-devel nano -y
Now you need to initialize the submodule with the following command.
git submodule init
When this command is completed, you should see a similar output.
[[email protected] ModSecurity]$ git submodule init
Submodule 'bindings/python' (https://github.com/SpiderLabs/ModSecurity-Python-bindings.git) registered for path 'bindings/python'
Submodule 'others/libinjection' (https://github.com/libinjection/libinjection.git) registered for path 'others/libinjection'
Submodule 'test/test-cases/secrules-language-tests' (https://github.com/SpiderLabs/secrules-language-tests) registered for path 'test/test-cases/secrules-language-tests'
Then update the submodules using the submodule update command.
git submodule update
If the command was successful, you should see a similar output.
[[email protected] ModSecurity]$ git submodule update
Cloning into '/usr/local/src/ModSecurity/bindings/python'...
Cloning into '/usr/local/src/ModSecurity/others/libinjection'...
Cloning into '/usr/local/src/ModSecurity/test/test-cases/secrules-language-tests'...
Submodule path 'bindings/python': checked out 'bc625d5bb0bac6a64bcce8dc9902208612399348'
Submodule path 'others/libinjection': checked out 'bfba51f5af8f1f6cf5d6c4bf862f1e2474e018e3'
Submodule path 'test/test-cases/secrules-language-tests': checked out 'a3d4405e5a2c90488c387e589c5534974575e35b'
Building the ModSecurity Environment
The next step is now actually to build the environment first. Use the following command:
./build.sh
Note you will possibly see the following error
fatal: No names found, cannot describe anything.
This can be safely ignored and now move on to the next step.
Now run the configure command.
./configure
This may take a minute or two. Once done, you should see a similar output.
Example:
ModSecurity - for Linux
Mandatory dependencies
+ libInjection ....v3.9.2-46-gbfba51f
+ SecLang tests ....a3d4405
Optional dependencies
+ GeoIP/MaxMind ....found
* (GeoIP) v1.6.12
-lGeoIP , -I/usr/include/
+ LibCURL ....found v7.85.0
-lcurl, -DWITH_CURL_SSLVERSION_TLSv1_2 -DWITH_CURL
+ YAJL ....found v2.1.0
-lyajl , -DWITH_YAJL
+ LMDB ....not found
+ LibXML2 ....found v2.10.3
-lxml2 , -I/usr/include/libxml2 -DWITH_LIBXML2
+ SSDEEP ....not found
+ LUA ....not found
+ PCRE2 ....not found
Other Options
+ Test Utilities ....enabled
+ SecDebugLog ....enabled
+ afl fuzzer ....disabled
+ library examples ....enabled
+ Building parser ....disabled
+ Treating pm operations as critical section ....disabled
[[email protected] ModSecurity]$
Compiling the ModSecurity Source Code
Now that you have built and configured the environment for libmodsecurity3, it is time to compile it with the command make.
make
A handy trick is to specify the -j <number of cpu> as this can significantly increase compiling speed if you have a powerful server. For example, the Computing post test server has 6 CPUs, and I can use all 6 or at least 4 to 5 to increase speed.
Example only:
make -j 6
After compiling the source code, run the installation command in your terminal.
sudo make install
Note the installation is done in the /usr/local/modsecurity/, which you will reference later in the guide.
Install ModSecurity-nginx Connector
The ModSecurity-Nginx connector is the connection point between Nginx and libmodsecurity. It is the component that communicates between Nginx and ModSecurity (libmodsecurity3).
Clone ModSecurity-nginx Repository from GitHub
Similar to the previous step of cloning the libmodsecurity3 repository, you will need to clone the connector repository again using the following command.
git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git /usr/local/src/ModSecurity-nginx/
Compile ModSecurity-nginx Dynamic Module
Next, navigate the directory into the Nginx source directory with the following command. Remember, your path may vary depending on your Nginx version.
For example, ensure you change to your Nginx version.
cd /usr/local/src/nginx/nginx-1.23.2
Note, replace the version of the guide with the current Nginx version in your system.
Next, you will compile the ModSecurity-nginx Connector module only with the –with-compat flag as follows:
./configure --add-dynamic-module=/usr/local/src/ModSecurity-nginx --with-compat
Example output if the above command worked correctly.
Configuration summary
+ using system PCRE library
+ OpenSSL library is not used
+ using system zlib library
nginx path prefix: "/usr/local/nginx"
nginx binary file: "/usr/local/nginx/sbin/nginx"
nginx modules path: "/usr/local/nginx/modules"
nginx configuration prefix: "/usr/local/nginx/conf"
nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
nginx pid file: "/usr/local/nginx/logs/nginx.pid"
nginx error log file: "/usr/local/nginx/logs/error.log"
nginx http access log file: "/usr/local/nginx/logs/access.log"
nginx http client request body temporary files: "client_body_temp"
nginx http proxy temporary files: "proxy_temp"
nginx http fastcgi temporary files: "fastcgi_temp"
nginx http uwsgi temporary files: "uwsgi_temp"
nginx http scgi temporary files: "scgi_temp"
Now make (create) the dynamic modules with the following command:
make modules
Next, in the Nginx source directory, use the following command to move the dynamic module you created that was saved at the location objs/ngx_http_modsecurity_module.so and copy it to the /usr/share/nginx/modules/ directory.
sudo cp objs/ngx_http_modsecurity_module.so /usr/share/nginx/modules/
Load and Configure ModSecurity-nginx Connector with Nginx
Now that you have compiled the dynamic module and located it accordingly, you need to edit your /etc/nginx/nginx.conf configuration file to get ModSecurity operating with your Nginx webserver.
Enable ModSecurity in nginx.conf
Firstly, you need to specify load_module and the path to your modsecurity module.
Open up nginx.conf with any text editor. For the tutorial, nano will be used:
sudo nano /etc/nginx/nginx.conf
Next, add the following line to the file near the top.
load_module /usr/share/nginx/modules/ngx_http_modsecurity_module.so;
If you have located the module elsewhere, include the full path.
Now add the following code under the HTTP {} section as follows:
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/modsec-config.conf;
Example only:
If you have located the module elsewhere, include the full path.
Save the nginx.conf file (CTRL+O), then exit (CTRL+X).
Create and Configure Directory and Files for ModSecurity
For the tutorial, you will need to create a directory to store the configuration files and future rules, OWASP CRS.
Use the following command to create the /etc/nginx/modsec directory as follows:
sudo mkdir /etc/nginx/modsec/
You must copy the sample ModSecurity configuration file from our cloned GIT directory.
sudo cp /usr/local/src/ModSecurity/modsecurity.conf-recommended /etc/nginx/modsec/modsecurity.conf
Using your favorite text editor, open the modsecurity.conf file as follows.
sudo nano /etc/nginx/modsec/modsecurity.conf
By default, ModSecurity configuration has the rule engine specified as (DetectionOnly), which in other words, runs ModSecurity and detects all malicious behavior but does not action blocks or bans and logs all the HTTP transactions that it flags. This should only be used if you have lots of false positives or have increased the security level settings to an extreme level and testing to see if any false positives occur.
To change this behavior to (on), find the following on line 7.
SecRuleEngine DetectionOnly
Change the line to this to enable ModSecurity:
SecRuleEngine On
Example:
Now, you need to locate the following, which is located on line 224.
# Log everything we know about a transaction.
SecAuditLogParts ABIJDEFHZ
This isn’t correct and needs to be changed. Modify the line to the following:
SecAuditLogParts ABCEFHJKZ
Now save the modsecurity.conf file using (CTRL+O) then exit (CTRL+X).
The next part is to create the following file modsec-config.conf. Here you will add the modsecurity.conf file along and later on other rules such as OWASP CRS, and if you are using WordPress, the WPRS CRS
Use the following command to create the file and open it:
sudo nano /etc/nginx/modsec/modsec-config.conf
Once inside the file, add the following line:
include /etc/nginx/modsec/modsecurity.conf
Save the modsec-config.conf file with (CTRL+O) then (CTRL+X) exit.
Lastly, copy ModSecurity’s unicode.mapping file with the CP command.
sudo cp /usr/local/src/ModSecurity/unicode.mapping /etc/nginx/modsec/
Now before moving on, you should give your Nginx service a dry run with the following terminal command:
sudo nginx -t
If you have set everything up correctly, you should get the following output:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
To make the changes live, restart your Nginx service using the systemctl command:
sudo systemctl restart nginx
Install OWASP Core Rule Set for ModSecurity
ModSecurity does not protect your web server, and you need to have rules. One of the most famous, respected, and well-known rules is the OWASP CRS rule set. The rules are the most widely used amongst web servers and other WAFs, and most other similar systems base most of their rules on this CRS. Installing this ruleset will automatically give you a great source of protection against most emerging threats on the Internet by detecting malicious actors and blocking them.
Using the wget command, download the OWASP CRS 3.3.4 archive. Remember, this may be outdated. Visit the official GitHub page to find the latest version.
wget https://github.com/coreruleset/coreruleset/archive/refs/tags/v3.3.4.zip
You can download the nightly build for those who want to live on the edge. Only use the nightly if you are prepared to keep re-compiling and checking the CoreRuleSet Github frequently for updates and be more confident at figuring out issues. Technically the nightly can be more secure but potentially can create problems.
For novice users, use the stable version and do not use the below version.
wget https://github.com/coreruleset/coreruleset/archive/refs/tags/nightly.zip
Install the unzip package if you do not have this installed on your Fedora system.
sudo dnf install unzip -y
Now unzip the master.zip archive with the following command.
sudo unzip v3.3.4.zip -d /etc/nginx/modsec
As before, like the modsecurity.conf sample configuration, OWASP CRS comes with a sample configuration file you need to rename. It is best to use the CP command and keep a backup for the future in case you need to restart again.
sudo cp /etc/nginx/modsec/coreruleset-3.3.4/crs-setup.conf.example /etc/nginx/modsec/coreruleset-3.3.4/crs-setup.conf
To enable the rules, open the /etc/nginx/modsec/modsec-config.conf using any text editor again:
sudo nano /etc/nginx/modsec/modsec-config.conf
Once inside the file again, add the following two additional lines:
include /etc/nginx/modsec/coreruleset-3.3.2/crs-setup.conf
include /etc/nginx/modsec/coreruleset-3.3.2/rules/*.conf
Example:
Save the file (CTRL+O) and exit (CTRL+T).
As per before, you need to test any new additions to your Nginx service before making it live:
sudo nginx -t
You should get the following output which means everything is working correctly.
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Restart your Nginx service to make the changes live as follows:
sudo systemctl restart nginx
Using and Understanding OWASP CRS
OWASP core rule has many options. The default settings, however, out of the box, will protect most servers immediately without hurting your natural visitors and good SEO bots. Below, some areas will be covered to help explain. Further reading would be best to investigate all the options in the configuration files themselves, as they have quite a bit of text data to present.
Open up your CRS-setup.conf file as follows.
sudo nano /etc/nginx/modsec/coreruleset-3.3.4/crs-setup.conf
Note this is the dev version configuration with additional items compared to version 3.3.
From here, you can modify most of your OWASP CRS settings.
OWASP CRS Scoring
To break it down, ModSecurity has two modes:
Anomaly Scoring Mode
# -- [[ Anomaly Scoring Mode (default) ]] --
# In CRS3, anomaly mode is the default and recommended mode, since it gives the
# most accurate log information and offers the most flexibility in setting your
# blocking policies. It is also called "collaborative detection mode".
# In this mode, each matching rule increases an 'anomaly score'.
# At the conclusion of the inbound rules, and again at the conclusion of the
# outbound rules, the anomaly score is checked, and the blocking evaluation
# rules apply a disruptive action, by default returning an error 403.
Self-Contained Mode
# -- [[ Self-Contained Mode ]] --
# In this mode, rules apply an action instantly. This was the CRS2 default.
# It can lower resource usage, at the cost of less flexibility in blocking policy
# and less informative audit logs (only the first detected threat is logged).
# Rules inherit the disruptive action that you specify (i.e. deny, drop, etc).
# The first rule that matches will execute this action. In most cases this will
# cause evaluation to stop after the first rule has matched, similar to how many
# IDSs function.
Anomaly Scoring is generally, for most users, the best mode to use.
There are four paranoia levels:
- Paranoia Level 1 – Default level and recommended for most users.
- Paranoia Level 2 – Advanced users only.
- Paranoia Level 3 – Expert users only.
- Paranoia Level 4 – Not recommended at all, except for exceptional circumstances.
# -- [[ Paranoia Level Initialization ]] ---------------------------------------
#
# The Paranoia Level (PL) setting allows you to choose the desired level
# of rule checks that will add to your anomaly scores.
#
# With each paranoia level increase, the CRS enables additional rules
# giving you a higher level of security. However, higher paranoia levels
# also increase the possibility of blocking some legitimate traffic due to
# false alarms (also named false positives or FPs). If you use higher
# paranoia levels, it is likely that you will need to add some exclusion
# rules for certain requests and applications receiving complex input.
#
# - A paranoia level of 1 is default. In this level, most core rules
# are enabled. PL1 is advised for beginners, installations
# covering many different sites and applications, and for setups
# with standard security requirements.
# At PL1 you should face FPs rarely. If you encounter FPs, please
# open an issue on the CRS GitHub site and don't forget to attach your
# complete Audit Log record for the request with the issue.
# - Paranoia level 2 includes many extra rules, for instance enabling
# many regexp-based SQL and XSS injection protections, and adding
# extra keywords checked for code injections. PL2 is advised
# for moderate to experienced users desiring more complete coverage
# and for installations with elevated security requirements.
# PL2 comes with some FPs which you need to handle.
# - Paranoia level 3 enables more rules and keyword lists, and tweaks
# limits on special characters used. PL3 is aimed at users experienced
# at the handling of FPs and at installations with a high security
# requirement.
# - Paranoia level 4 further restricts special characters.
# The highest level is advised for experienced users protecting
# installations with very high security requirements. Running PL4 will
# likely produce a very high number of FPs which have to be
# treated before the site can go productive.
#
# All rules will log their PL to the audit log;
# example: [tag "paranoia-level/2"]. This allows you to deduct from the
# audit log how the WAF behavior is affected by paranoia level.
#
# It is important to also look into the variable
# tx.enforce_bodyproc_urlencoded (Enforce Body Processor URLENCODED)
# defined below. Enabling it closes a possible bypass of CRS.
Test OWASP CRS on your Server
Now, you can test if the OWASP CRS rules are working correctly on your web server, use an example such as below to replace your domain name with your web server name, and it should block this basic example of a malicious attack.
https://www.yourdomain.com/index.html?exec=/bin/bash
You should receive a 403 forbidden error. If not, then a step has been missed.
The most common problem is missing to change DetectionOnly to On, as covered earlier in the tutorial.
Example:
Dealing with False Positives & Custom Rules Exclusion
One of the often never-ending tasks is dealing with false positives, ModSecurity and OWASP CRS do a great job together, but it comes at the cost of your time; given the protection you get, it is worth it. For starters, never putting the paranoia level high is the golden rule.
A good rule of thumb is to run the rule set for a few weeks to months with hardly any false positives, then increase, for example, paranoia level 1 to paranoia level 2, so you are not swamped with a ton simultaneously.
Excluding False Positives known Applications
Modsecurity, by default, can whitelist everyday actions that lead to false positives as below:
#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"
Another example, you can enable WordPress, phpBB, and phpMyAdmin as you use all three, uncomment the lines and leave the (1) number intact, and change the other services you do not use, for instance, Xenforo to (0) as you do not want to whitelist these rules. Example below:
SecAction \
"id:900130,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.crs_exclusions_cpanel=0,\
setvar:tx.crs_exclusions_dokuwiki=0,\
setvar:tx.crs_exclusions_drupal=0,\
setvar:tx.crs_exclusions_nextcloud=0,\
setvar:tx.crs_exclusions_phpbb=1,\
setvar:tx.crs_exclusions_phpmyadmin=1,\
setvar:tx.crs_exclusions_wordpress=1,\
setvar:tx.crs_exclusions_xenforo=0"
You can also modify the syntax, which would be cleaner.
Example:
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"
As you can see, removed are the options not needed and added (“) at the end of WordPress for correct syntax.
Excluding Rules Before CRS
To deal with custom exclusions, firstly, you need to change the name from the REQUEST-900-EXCLUSION-RULES-BEFORE-CRS-SAMPLE.conf file with the cp command. This will give you a backup file, just in case, instead of renaming the file.
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
Remember, when creating exclusion rules, each one must have id:<rule number> and be unique, or else when you test your Nginx service, you will get an error. For example, “id:1544,phase:1,log,allow,ctl:ruleEngine=off”, the id 1544 cannot be used for a second rule.
For example, some REQUEST_URI’s will raise false positives. The example below is two with Google pagespeed beacon and WMUDEV plugin for WordPress:
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"
As you can see, any URL that begins with the path will be automatically allowed.
Another option is to whitelist IP addresses. Two examples are provided below.
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"
The @ipMatch can be used more extensively for subnets. If you want to deny a subnet or IP address change, allow to deny. With some know-how, you can also create blacklists and whitelists and configure this with fail2ban. The possibilities can often be endless.
WordPress WPRS Rule Set for ModSecurity
Another option for WordPress users is to install and run alongside your OWASP CRS rule set, a well-known project entitled WPRS rule set. As this is optional and not for everyone, the tutorial will not cover it in this section.
However, if you want to install this for extra protection using WordPress on your server, please visit our tutorial on Installing WordPress ModSecurity Rule Set (WPRS).
Create ModSecurity LogRotate file:
Given how many lines and information it can log, ModSecurity will grow quite quickly. As you are compiling the module and it isn’t installed through any official repository, you will need to create your own log rotate file.
First, create and open your ModSecurity rotate file modsec.
sudo nano /etc/logrotate.d/modsec
Add the following code by copying and pasting.
/var/log/modsec_audit.log
{
rotate 31
daily
missingok
compress
delaycompress
notifempty
}
This will keep logs for 31 days. If you prefer to have less, change 31 to 7 days, equally a week’s worth of logs. You should be rotating daily for ModSecurity. If you need to review the log files having a weekly file will be a disaster to sift through, given how large it will be.
Note about Upgrading Nginx (Important)
Given that you have downloaded and compiled the dynamic module with a specific version of Nginx, if an upgrade comes out for any version, you must run the upgrade and re-compile the dynamic module.
For most users, it’s pretty quick once you have done this a few times. All you need to replace is the module, and all your configuration files do not need modifying. Repeat downloading the nginx source to move the dynamic module.
Comments and Conclusion
In the tutorial, you have a grasp of installing the Nginx source, compiling ModSecurity, and setting up the OWASP Rules among the top parts. Overall, deploying ModSecurity to your server will provide instant protection. However, patience, time, and dedication to learning will be a great security feature. The last thing you want is to block SEO bots or, more importantly, real users that could be potential customers.