ModSecurity 3 NGINX Quick Start Guide
ModSecurity 3 NGINX Quick Start Guide
0
& NGINX: Quick Start Guide
01
MODSECURITY 3.0
& NGINX: Quick Start Guide
by Faisal Memon, Owen Garrett, and Michael Pleshakov
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
A Brief History of ModSecurity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
How ModSecurity Works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
What’s Changed with ModSecurity 3.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Caveats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2. Installing ModSecurity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Open Source NGINX Installation Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
NGINX Plus Installation Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Appendix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
i
Preface
For a very long time, the NGINX community waited for ModSecurity. The popular
plug-in for the Apache HTTP server seemed like a natural fit to be ported over
to NGINX, but it's never as easy as it sounds to port something over to a different
platform. In 2017, the wait finally ended, and the long-awaited ModSecurity 3.0
was finally released. ModSecurity 3.0 is the first version of ModSecurity to
work natively with NGINX.
This ebook was created to help you get up and running with ModSecurity 3.0
and NGINX as easily as possible. It covers how to install, enable the major
features of, and troubleshoot ModSecurity 3.0. Please use other resources
available online, including the brilliant ModSecurity Handbook, if you need more
information about ModSecurity before you put it into production.
I hope this guide will be helpful to you in your journey with ModSecurity 3.0
and NGINX.
– Faisal Memon
Product Marketer, NGINX, Inc.
ii
1
Introduction
Ristić then set out to create this solution as a hobbyist side project. He created
it as a plugin for the Apache HTTP Server. By November 2002 he put out the
first open source release, calling his work ModSecurity. ModSecurity quickly
gained in popularity, as it provided instant value as a tool for protecting web-
based applications.
SQL injection is one of the most common exploits, accounting for over 51%
of known web application attacks, according to the report, Akamai State of the
Internet – Security. This type of attack exploits improper validation of user
input fields, such as forms. As a simple example, consider an attacker entering
the following into a login form (the password field is unmasked for clarity):
Username
someone_else
Username
1' or '1'='1
Log In
Because the statement '1' = '1' is always true, this query bypasses the
password check and allows the attacker to log in as someone_else (or any
other account).
The CRS SQL injection rules in the OWASP CRS test input parameters and
cookies for all requests against this and other patterns that attackers use to
insert malicious SQL queries into forms. If a request matches any of the SQL
injection rules, ModSecurity can drop the packet and/or log it, as configured.
There are similar rules in the CRS to detect and stop other common attacks,
such as XSS and LFI.
This new architecture in version 3.0 moves the core functionality into a
stand‑alone engine called libmodesecurity. The libmodesecurity
component interfaces with NGINX through an optimized connector called
the NGINX connector. There is also a separate connector for Apache.
The new module is considerably faster and more stable than the legacy module
has been with open source NGINX, and is actively supported by the NGINX, Inc.
and Trustwave teams.
Caveats
ModSecurity 3.0 does not yet have feature parity with the previous version,
ModSecurity 2.9. Please be aware of the following limitations:
• Rules that inspect the response body are not supported and are ignored if
included in the configuration.
• Inclusion of the request and response body in the audit log is not supported
• Some directives are not implemented; you may get an error if you try to use
them. The ModSecurity Reference Manual lists all the available directives in
ModSecurity and whether or not they are supported in libModSecurity.
There is no set date for ModSecurity 3.0 to reach feature parity with
ModSecurity 2.9, but it is under active development, and each new release
reduces the gap.
This chapter will cover how to install ModSecurity 3.0 for both open source
NGINX and NGINX Plus. Open source NGINX users will have to compile
ModSecurity from source. NGINX Plus users benefit from using the precompiled
ModSecurity 3.0 dynamic module provided by NGINX Inc.
ModSecurity 3.0 and NGINX: Quick Start Guide 5 Ch. 2 – Installing ModSecurity
Open Source NGINX Installation Instructions
Installation Overview
In NGINX 1.11.5 and later, you can compile individual dynamic modules without
compiling the complete NGINX binary. After covering the compilation process
step by step, we’ll explain how to load the ModSecurity dynamic module into
NGINX and run a basic test to make sure it’s working.
The instructions in this chapter assume that you have installed NGINX from
our official repository. They might work with NGINX as obtained from other
sources, but that has not been tested.
Note: NGINX 1.11.5 or later is required.
ModSecurity 3.0 and NGINX: Quick Start Guide 6 Ch. 2 – Installing ModSecurity
To compile libmodsecurity:
$ cd ModSecurity
$ git submodule init
$ git submodule update
$ ./build.sh
$ ./configure
$ make
$ make install
ModSecurity 3.0 and NGINX: Quick Start Guide 7 Ch. 2 – Installing ModSecurity
B. Determine which version of NGINX is running on the host where the
ModSecurity module will be loaded:
$ nginx -v
nginx version: nginx/1.13.7
$ wget http://nginx.org/download/nginx-1.13.7.tar.gz
$ tar zxvf nginx-1.13.7.tar.gz
$ cd nginx-1.13.7
$ ./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
$ make modules
$ cp objs/ngx_http_modsecurity_module.so /etc/nginx/modules
load_module modules/ngx_http_modsecurity_module.so;
ModSecurity 3.0 and NGINX: Quick Start Guide 8 Ch. 2 – Installing ModSecurity
NGINX Plus Installation Instructions
This section explains how to install the NGINX web application firewall (WAF).
The NGINX WAF is built on ModSecurity 3.0.
Prerequisites
Install NGINX Plus R12 or later following these instructions:
nginx.com/resources/admin-guide/installing-nginx-plus/.
load_module modules/ngx_http_modsecurity_module.so;
ModSecurity 3.0 and NGINX: Quick Start Guide 9 Ch. 2 – Installing ModSecurity
3. Run the following command to verify that the module loads successfully,
as confirmed by the indicated output:
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
server {
listen localhost:8085;
location / {
default_type text/plain;
return 200 "Thank you for requesting ${request_uri}\n";
}
}
ModSecurity 3.0 and NGINX: Quick Start Guide 10 Ch. 2 – Installing ModSecurity
2. Test the application by reloading the NGINX configuration and making
a request:
server {
listen 80;
location / {
proxy_pass http://localhost:8085;
proxy_set_header Host $host;
}
}
Note: If any other virtual servers (server blocks) in your NGINX configuration listen on
port 80, you need to disable them for the reverse proxy to work correctly. For example, the
/etc/nginx/conf.d/default.conf file provided in the nginx package includes such a server block.
Comment out or remove the server block, but do not remove or rename the default.conf file
itself – if the file is missing during an upgrade, it is automatically restored, which can break the
reverse‑proxy configuration.
ModSecurity 3.0 and NGINX: Quick Start Guide 11 Ch. 2 – Installing ModSecurity
2. Reload the NGINX configuration:
$ curl -D - http://localhost
HTTP/1.1 200 OK
Server: nginx/1.11.10
Date: Wed, 3 May 2017 08:58:02 GMT
Content-Type: text/plain
Content-Length: 27
Connection: keep-alive
$ cd /etc/nginx/modsec
$ sudo wget https://raw.githubusercontent.com/SpiderLabs/
ModSecurity/v3/master/modsecurity.conf-recommended
$ sudo mv modsecurity.conf-recommended modsecurity.conf
ModSecurity 3.0 and NGINX: Quick Start Guide 12 Ch. 2 – Installing ModSecurity
3. Enable execution of rules by commenting out the existing SecRuleEngine
directive in modsecurity.conf and adding the indicated directive. We will
define the sample rule in the next step:
# SecRuleEngine DetectionOnly
SecRuleEngine On
# A test rule
SecRule ARGS:testparam "@contains test" "id:1234,deny,log,status:403"
ModSecurity 3.0 and NGINX: Quick Start Guide 13 Ch. 2 – Installing ModSecurity
5. Change the reverse proxy configuration file
(/etc/nginx/conf.d/proxy.conf) to enable the ModSecurity 3.0:
server {
listen 80;
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/main.conf;
location / {
proxy_pass http://localhost:8085;
proxy_set_header Host $host;
}
}
ModSecurity 3.0 and NGINX: Quick Start Guide 14 Ch. 2 – Installing ModSecurity
7. Verify that the rule configured in Step 4 works correctly, by making a
request that includes the string test in the value of the query string
testparam parameter:
$ curl -D - http://localhost/foo?testparam=thisisatestofmodsecurity
HTTP/1.1 403 Forbidden
Server: nginx/1.11.10
Date: Wed, 3 May 2017 09:00:48 GMT
Content-Type: text/html
Content-Length: 170
Connection: keep-alive
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr/><center>nginx/1.11.10</center>
</body>
</html>
The request returns status code 403, confirming that the WAF is enabled and
executing the rule.
Setting Up Logging
By default, the ModSecurity 3.0 logs its activity to the NGINX Plus error log,
at the warn level for blocked requests and the info level for other messages.
The error_log directive in the main /etc/nginx/nginx.conf file provided
with NGINX Plus is configured to write messages to /var/log/nginx/error.log
at the warn level and higher. If you want to capture all messages from the
ModSecurity 3.0, you need to set the logging level to info instead:
Note: Your existing configuration might include definitions for multiple error logs, in files other
than nginx.conf and placed in more specific contexts, such as a location block. Make sure
to update all the relevant error_log directives.
ModSecurity 3.0 and NGINX: Quick Start Guide 15 Ch. 2 – Installing ModSecurity
Controlling Audit and Debug Logging
ModSecurity also supports audit logging as configured with the SecAudit*
set of directives. Audit logging is enabled in the recommended configuration
that we downloaded to /etc/nginx/modsec/modsecurity.conf (in Step 2 of
Protecting the Demo Web Application), but we recommend disabling it in
production environments, both because audit logging affects ModSecurity
performance and because the log file can grow large very quickly and
exhaust disk space. To disable audit logging, change the value of the
SecAuditEngine directive in modsecurity.conf to off:
SecAuditEngine off
If you experience problems with the ModSecurity 3.0, you can enable
debug logging by changing the SecDebugLog and SecDebugLogLevel
directives in modsecurity.conf to the following values. Like audit logging,
debug logging generates a large volume of output and affects ModSecurity
performance, so we recommend disabling it in production.
SecDebugLog /tmp/modsec_debug.log
SecDebugLogLevel 9
Conclusion
In this section, we installed ModSecurity 3.0 for NGINX and NGINX Plus, created
a simple rule for quick testing, and set up logging of ModSecurity 3.0 activity.
The simple rule works correctly, In the next chapter we will cover how to install
the OWASP Core Rule Set (CRS).
ModSecurity 3.0 and NGINX: Quick Start Guide 16 Ch. 2 – Installing ModSecurity
3
Installing the
OWASP Core
Rule Set
After installing the ModSecurity 3.0 software, the next step is to install
ModSecurity's rule set(s). The rules define the attack patterns and determine
what ModSecurity will block.
The OWASP Core Rule Set (CRS) is the base rule set that all ModSecurity users
should install. The CRS is community-maintained and contains rules to help
stop common attack vectors, such as SQL injection, cross-site scripting, and
many others. It also has rules to integrate with Project Honeypot (Chapter 4)
as well as rules to detect bots and scanners.
On top of the CRS you can install the Trustwave SpiderLabs commercial rules,
which provide additional protections. You can find a detailed description of the
commercial rules in Appendix A.
This chapter will cover installation of the OWASP Core Rule Set (CRS).
ModSecurity 3.0 and NGINX: Quick Start Guide 17 Ch. 3 – Installing the OWASP Core Rule Set
We’re using the Nikto scanning tool to generate malicious requests, including
probes for the presence of files known to be vulnerable, cross‑site scripting
(XSS), and other types of attack. The tool also reports which requests passed
through to the application, revealing potential vulnerabilities in the application.
Run the following commands to get the Nikto code and run it against the web
application. The 324 item(s) in the output are potential vulnerabilities,
revealed by requests that passed through to the application.
Next we enable the CRS, and then test how it blocks most of Nikto’s requests
and so decreases the number of items reported.
1. Download the latest OWASP CRS from GitHub and extract the rules into
/usr/local or another location of your choice:
$ wget https://github.com/SpiderLabs/owasp-modsecurity-crs/archive/
v3.0.2.tar.gz
$ tar -xzvf v3.0.2.tar.gz
$ sudo mv owasp-modsecurity-crs-3.0.2 /usr/local
ModSecurity 3.0 and NGINX: Quick Start Guide 18 Ch. 3 – Installing the OWASP Core Rule Set
2. Create the crs‑setup.conf file as a copy of crs‑setup.conf.example:
$ cd /usr/local/owasp-modsecurity-crs-3.0.2
$ sudo cp crs-setup.conf.example crs-setup.conf
ModSecurity 3.0 and NGINX: Quick Start Guide 19 Ch. 3 – Installing the OWASP Core Rule Set
Disabling Blocking of Requests Based on the User‑Agent Header
The CRS recognizes requests from scanners, including Nikto, by inspecting
the User‑Agent header. As shown in the following output, the CRS comes
preconfigured to block requests that have the default User‑Agent header
for Nikto (Nikto).
(If you want to see exactly how the CRS ranks and blocks requests based on
the User‑Agent header and related characteristics of requests from scanners,
you can correlate the rule ID numbers found in the NGINX error log with the
rules in the CRS’s Scanner Detection rule set (REQUEST-913-SCANNER-
DETECTION.conf).)
During this testing phase we don’t want to block all requests from Nikto,
because we’re using them to detect possible vulnerabilities in our demo app.
To stop the CRS from blocking requests just because their User‑Agent header
is Nikto, we reconfigure Nikto not to include Nikto and related values in the
header. Comment out the current setting for USERAGENT in program/nikto.conf
and replace it with the value shown:
ModSecurity 3.0 and NGINX: Quick Start Guide 20 Ch. 3 – Installing the OWASP Core Rule Set
Eliminating Requests for Vulnerable Files
When we rerun Nikto against the web application, we see that only 116 of
Nikto’s requests get through to the application server, compared to 324 when
the CRS wasn’t enabled. This indicates that the CRS is protecting our application
from a large proportion of the vulnerabilities exposed by Nikto’s requests.
The output from Nikto is very long, and so far we have been truncating it to
show just the final line, where the number of items is reported. When we look
at the output more closely, we see that many of the remaining 116 items refer
to a vulnerable file in the application, as in this example:
ModSecurity 3.0 and NGINX: Quick Start Guide 21 Ch. 3 – Installing the OWASP Core Rule Set
Blocking Requests with XSS Attempts
When we rerun Nikto again, it reports only 26 items:
Most of the 26 items arise because the OWASP CRS is not currently configured
to block requests that contain XSS attempts in the request URL, such as:
<script>alert('Vulnerable')</script>
To block requests with XSS attempts, edit rules 941160 and 941320 in the CRS’s
XSS Application Attack rule set (REQUEST-941-APPLICATION-ATTACK-XSS.
conf) by adding REQUEST_URI at the start of the variables list for each rule:
Reload the NGINX Plus configuration to read in the revised rule set:
ModSecurity 3.0 and NGINX: Quick Start Guide 22 Ch. 3 – Installing the OWASP Core Rule Set
When we rerun Nikto, it reports only four items, and they are false positives for
our application:
Limitations
Inspecting the response body is not supported, so rules that do so have
no effect.
Conclusion
We used the OWASP ModSecurity Core Rule Set (CRS) to protect our web
application against a wide range of generic attacks and saw how the CRS
blocks malicious requests generated by the Nikto scanning tool.
For information about another supported ModSecurity rule set, see Appendix A:
Installing the TrustWave SpiderLabs Commercial Rule Set.
ModSecurity 3.0 and NGINX: Quick Start Guide 23 Ch. 3 – Installing the OWASP Core Rule Set
4
Enabling
Project Honeypot
To help fight crime, the FBI maintains a public Ten Most Wanted list of the
most dangerous criminals out there. Anyone who sees someone on the list
will know to call the police, making it more difficult for these criminals to
commit more crimes.
ModSecurity 3.0 and NGINX: Quick Start Guide 24 Ch. 4 – Enabling Project Honeypot
the site with a web browser. When the scanner follows the honeypot link
and attempts to interact with the page – harvesting, for example, an embedded
honeypot email address – the IP address is added to the database.
Project Honeypot lookups are done in real time when an HTTP request is
received, so there will likely be a performance impact for enabling this
functionality. The results are cached, however, to minimize the performance
impact. Before enabling Project Honeypot integration in a production
environment, please be sure to test the potential performance impact it will
have on your applications.
In this scenario, we use PHP for the scripting language. If your preferred
language is not supported by Project Honeypot, PHP is a good choice,
because it’s very easy to configure NGINX and NGINX Plus to run PHP scripts
using PHP‑FPM.
There are plenty of tutorials online on how to install PHP‑FPM. For Ubuntu 16.04
and later, you can use these commands:
$ apt-get update
$ apt-get -y install php7.0-fpm
ModSecurity 3.0 and NGINX: Quick Start Guide 25 Ch. 4 – Enabling Project Honeypot
You can then configure the Project Honeypot PHP script by adding this
server block:
server {
server_name www.example.com;
location ~ \.php$ {
modsecurity off;
root /code;
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass localhost:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_
script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
Notes:
• In the server_name directive, for www.example.com substitute the domain name
you registered with Project Honeypot.
• ModSecurity must be disabled on the honeypot script for it to function properly.
• In the root directive, for /code, substitute the directory where you placed the
honeypot script.
Once the script is installed, access it in a web browser and click the activation
link to activate the honeypot.
ModSecurity 3.0 and NGINX: Quick Start Guide 26 Ch. 4 – Enabling Project Honeypot
2. Add the Honeypot Link to All Pages
The next step is to configure NGINX or NGINX Plus to add the honeypot link to
all pages.
To catch bots and scanners, insert a link to the honeypot script on every page.
The link is invisible to regular people using a web browser but visible to bots and
scanners. Here, we use the sub_filter directive to add the link to the bottom
of each page:
location / {
proxy_set_header Host $host;
proxy_pass http://my_upstream;
sub_filter '</html>'
'<a href="http://www.example.com/weddingobject.php">
<!-- hightest --></a></html>';
}
ModSecurity 3.0 and NGINX: Quick Start Guide 27 Ch. 4 – Enabling Project Honeypot
2. In the file /usr/local/owasp-modsecurity-crs-3.0.0/crs-setup.conf,
which you installed according to the Installing the OWASP Core Rule Set,
locate the SecHttpBlKey block:
SecHttpBlKey my_api_key
SecAction "id:900500,\
phase:1,\
nolog,\
pass,\
t:none,\
:tx.block_search_ip=0,\
setvar:tx.block_suspicious_ip=1,\
setvar:tx.block_harvester_ip=1,\
setvar:tx.block_spammer_ip=1"
4. Verify It Works
The Project Honeypot queries are based off the client source IP address. It’s not
easy to spoof a source IP address, so a good way to test that the functionality
is working is by adding this custom rule to /etc/nginx/modsec/main.conf.
ModSecurity 3.0 and NGINX: Quick Start Guide 28 Ch. 4 – Enabling Project Honeypot
It sends the value of the IP address argument, passed in as part of the request,
to Project Honeypot:
Then run the following curl command to test the rule with an IP address from
Project Honeypot’s list of known bad IP addresses (projecthoneypot.org/
list_of_ips.php) (substitute that address for the sample address used here,
203.0.113.20, which is a standard address reserved for documentation). If the
rule works correctly, the request is blocked with status code 403:
Conclusion
In this chapter, we covered the steps for configuring ModSecurity 3.0 to work
with Project Honeypot. Project Honeypot is a very useful tool for automatically
blocking known bad IP addresses. It’s free and is powered by a community of
users setting up honeypots on their own sites.
ModSecurity 3.0 and NGINX: Quick Start Guide 29 Ch. 4 – Enabling Project Honeypot
5
Debugging, Logging,
and Troubleshooting
When something is not working as you expect it to, logs are always the first
place to look. Good logs can provide valuable insights to help you trouble
shoot the problems you’re facing. One of the reasons Ivan Ristić originally
created ModSecurity is that he was frustrated with the lack of visibility in the
tools he was using. It’s no surprise, then, that ModSecurity has extensive
logging and debugging capabilities.
The audit log is useful for learning not just why an individual attack was
blocked, but for finding out more about overall attack patterns. You might be
surprised by how much bot and scanner traffic you get just by exposing
ports 80 and/or 443 to the Internet.
ModSecurity 3.0 and NGINX: Quick Start Guide 30 Ch. 5 – Debugging, Logging, and Troubleshooting
Audit Log
The main log in ModSecurity is the audit log, which logs all attacks, including
potential attacks, that occur. If you’ve followed our installation instructions in
Installing ModSecurity, then by default, ModSecurity will log all transactions
that triggered a warning or error, as well as all transactions that resulted in 5xx
and 4xx responses, except for 404. (For an Ubuntu 16.04 system only, the
audit log is in /var/log/modsec_audit.log.)
The ModSecurity audit log is partitioned into sections. This makes it easier to
scan the log and find the information you’re looking for. The table below
outlines what each section contains:
Section Description
A Audit log header (mandatory)
B Request headers
C Request body
D Reserved
E Response body
F Response headers
G Reserved
H Audit log trailer, which contains additional data
I Compact request body alternative (to part C), which excludes files
J Information on uploaded files
K Contains a list of all rules that matched for the transaction
Z Final boundary (mandatory)
Each transaction that triggers an audit log entry will have any or all of the
above sections logged. You can configure which sections are logged.
ModSecurity 3.0 and NGINX: Quick Start Guide 31 Ch. 5 – Debugging, Logging, and Troubleshooting
Audit Log Example
A sample ModSecurity audit log entry might look like this:
---ICmPEb5c---A--
[04/Oct/2017:21:45:15 +0000] 150715351558.929952 141.212.122.16 64384
141.212.122.16 80
---ICmPEb5c---B--
GET / HTTP/1.1
Host: 54.183.57.254
User-Agent: Mozilla/5.0 zgrab/0.x
Accept-Encoding: gzip
---ICmPEb5c---D--
---ICmPEb5c---F--
HTTP/1.1 200
Server: nginx/1.13.4
Date: Wed, 04 Oct 2017 21:45:15 GMT
Content-Type: text/html
Connection: keep-alive
---ICmPEb5c---H--
ModSecurity: Warning. Matched "Operator `Rx' with parameter
`^[\d.:]+$' against variable `REQUEST_HEADERS:Host' (Value:
`54.183.57.254' ) [file "/root/owasp
-v3/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "733"] [id
"920350"] [rev "2"] [msg "Host header is a numeric IP address"]
[data "54.183.57.254"] [s
everity "4"] [ver "OWASP_CRS/3.0.0"] [maturity "9"] [accuracy "9"]
[tag "application-multi"] [tag "language-multi"] [tag "platform-
multi"] [tag "attack-prot
ocol"] [tag "OWASP_CRS/PROTOCOL_VIOLATION/IP_HOST"] [tag "WASCTC/
WASC-21"] [tag "OWASP_TOP_10/A7"] [tag "PCI/6.5.10"] [ref
"o0,13v21,13"]
---ICmPEb5c---I--
---ICmPEb5c---J--
---ICmPEb5c---Z--
ModSecurity 3.0 and NGINX: Quick Start Guide 32 Ch. 5 – Debugging, Logging, and Troubleshooting
Though it’s not immediately apparent from the table above, the best section
to find information on why a particular request was blocked is section H, not
section K. From the above audit log example, if we scan through section H,
we can see the message "Host header is a numeric IP address", which
indicates someone tried to access our site by IP address rather than by
hostname. This may be indicative of a scanner.
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4(?!04))"
SecAuditLogParts ABIJDEFHZ
where
• SecAuditEngine – Controls what should be logged. Options are:
• Off – Disable the audit log.
• On – Log all transactions, which can can useful when debugging.
• RelevantOnly – Log only transactions that have triggered a
warning/error, or have a status code that matches what’s in the
SecAuditLogRelevantStatus directive.
• SecAuditLogRelevantStatus – If SecAuditEngine is set to RelevantOnly,
then this directive controls what HTTP response status codes should be
logged. It’s regular expression‑based. The above value will log all 5xx and
4xx responses, excluding 404s.
• SecAuditLogParts – Controls what sections should be included in the
access log. Removing sections you’re not interested in reduces the size of
the audit log and make it easier to scan.
ModSecurity 3.0 and NGINX: Quick Start Guide 33 Ch. 5 – Debugging, Logging, and Troubleshooting
Debug Log
When the debug log is turned on, it provides a wealth of information on every
thing ModSecurity does. For troubleshooting issues as to why something is
not working the way you expect it to, the debug log is your go‑to resource.
It’s also great if you’re getting started with ModSecurity and want to observe
why it does things a certain way.
[4]
(Rule: 1234) Executing operator "Contains" with param "test"
against ARGS:testparam.
[9] Target value: "test" (Variable: ARGS:testparam)
[9] Matched vars updated.
[4] Running [independent] (non-disruptive) action: log
[9] Saving transaction to logs
[4] Rule returned 1.
[9] (SecDefaultAction) Running action: log
[9] Saving transaction to logs
[9] (SecDefaultAction) Running action: auditlog
[4]
(SecDefaultAction) ignoring action: pass (rule contains a
disruptive action)
[4] Running (non-disruptive)
action: auditlog
[4] Running (disruptive) action: deny
The debug log lists the rule ID number for easy searching. In this example, the
output is from our test rule with ID number 1234.
ModSecurity 3.0 and NGINX: Quick Start Guide 34 Ch. 5 – Debugging, Logging, and Troubleshooting
Debug Log Configuration
By default, the debug log is disabled, as it can negatively affect performance.
Just as with audit logging, the debug log is configured in /etc/nginx/modsec/
modsecurity.conf. In that file, there are two configuration directives that are
commented out. To enable debug logging, uncomment them and change
them to the following:
SecDebugLog /var/log/modsec_debug.log
SecDebugLogLevel 9
where
• SecDebugLog – Specifies the path to the debug log file.
• SecDebugLogLevel – 0–9 indicates how much information to log, with 9 being
the most. If you’re troubleshooting, setting this value to 9 is the most helpful.
Conclusion
In this chapter, we covered how to get started using the extensive logging
capabilities within ModSecurity. ModSecurity has both audit logs, which
contain information about all blocked transactions, and a debug log to further
assist you if you’re having trouble using ModSecurity.
ModSecurity 3.0 and NGINX: Quick Start Guide 35 Ch. 5 – Debugging, Logging, and Troubleshooting
Appendix A:
Installing the
TrustWave SpiderLabs
Commercial Rule Set
The TrustWave SpiderLabs Commercial Rule Set provides additional
protections, such as application specific rule sets for WordPress, Joomla,
SharePoint, and others. Learn more about the TrustWave SpiderLabs
Commercial Rule Set at: trustwave.com/Products/Application-Security/
ModSecurity-Rules-and-Support.
Overview
NGINX Plus Release 12 and NGINX 1.11.5 and later support ModSecurity 3.0.
The ModSecurity WAF protects web applications against various Layer 7
attacks; provides DDoS mitigation, real‑time blacklisting, audit logging; and
enables PCI‑DSS 6.6 compliance.
ModSecurity 3.0 also supports the OWASP CRS as described in Installing the
OWASP Core Rule Set.
ModSecurity 3.0 and NGINX: Quick Start Guide 36 Appendix A: Installing the TrustWave SpiderLabs Commercial Rule Set
Prerequisites
You must purchase the Trustwave SpiderLabs Rules directly from Trustwave.
To configure the Trustwave SpiderLabs Rules for the demo application, first
create a profile (or use the default one) that includes selected rules for protecting
the application. Then modify the local ModSecurity configuration to make the
ModSecurity dynamic module download and apply the rules. The instructions
use the Configuration Wizard on the Dashboard for creating a profile.
Detailed instructions for using the Dashboard are not provided here. For more
information, log in to the ModSecurity Dashboard at: dashboard.modsecurity.org.
ModSecurity 3.0 and NGINX: Quick Start Guide 37 Appendix A: Installing the TrustWave SpiderLabs Commercial Rule Set
Using the Configuration Wizard
To configure the Trustwave SpiderLabs Rules for the demo application,
perform the following steps:
The Wizard does not provide an interface for adding the directive, so you need
to edit /etc/nginx/modsec/main.conf manually and add the SecRemoteRules
directive presented by the Wizard (we created the file in Step 4 of Protecting
the Demo Web Application). Comment out any other rules that might already
exist in the file, such as the SecRule directive from that section:
ModSecurity 3.0 and NGINX: Quick Start Guide 38 Appendix A: Installing the TrustWave SpiderLabs Commercial Rule Set
4. By default, the Trustwave SpiderLabs Rules only detect malicious requests
and don’t block them. To block the requests, add the following lines to
/etc/nginx/modsec/main.conf, below the SecRemoteRules directive you
added in the previous step:
SecDefaultAction "phase:2,log,auditlog,deny,status:403"
SecDefaultAction "phase:1,log,auditlog,deny,status:403"
The SecDefaultAction directive defines the default list of actions for the rules,
with the deny action blocking malicious requests and returning status code 403.
Reloading takes time as the rules are being downloaded from the remote server.
6. Once the Wizard reports that NGINX downloaded the rules, you can close
the wizard and start testing the rules.
ModSecurity 3.0 and NGINX: Quick Start Guide 39 Appendix A: Installing the TrustWave SpiderLabs Commercial Rule Set
• Every time you reload the NGINX configuration or restart NGINX, the rules are
freshly downloaded from a remote server. The SecRemoteRulesFailAction
directive controls what happens when the download fails – for example, when
connectivity to the remote server is lost. The directive supports two values:
Abort, which forces the reload or restart of NGINX to fail, and Warn, which
lets NGINX reload or restart successfully but with no remote rules enabled.
The SecRemoteRulesFailAction directive must appear above SecRemoteRules
directives in a ModSecurity configuration file.
• Downloading the rules takes some time, which delays the reload or
restart operation.
• Each SecRemoteRules definition leads to a separate download, further
increasing the reload/restart time. To avoid that, try to minimize the
number of SecRemoteRules definitions. Note that even if you define
SecRemoteRules only in one file (as in the /etc/nginx/modsec/main.conf
file modified in Step 3 above), each time you include this file into NGINX
configuration using the modsecurity_rules_file directive (as in the
/etc/nginx/conf.d/proxy.conf file created in Configuring NGINX as
a Reverse Proxy), ModSecurity treats it as a separate definition.
• Merging rules from different contexts (http, server, location) also adds
time to the reload/restart operation and consumes a lot of CPU, especially
for a huge rule set such as the Trustwave SpiderLabs Rules. In addition to
minimizing the number of SecRemoteRules definitions, try to include all rule
definitions in a single context.
The Trustwave SpiderLabs rule set contains more than 16,000 rules for
protecting various applications. The more rules there are, the worse the
WAF performs, so it’s crucial that you enable only rules that are relevant
for your application.
Limitations
Inspecting the response body is not supported, so rules that do so have
no effect.
Conclusion
In this chapter, we configured ModSecurity Rules from Trustwave SpiderLabs to
protect our application against WordPress‑related attacks. We also reviewed
caveats for the SecRemoteRules directive.
ModSecurity 3.0 and NGINX: Quick Start Guide 40 Appendix A: Installing the TrustWave SpiderLabs Commercial Rule Set
Appendix B:
Document Revison
History
Version Date Description
1.0 2017-12-14 Initial release
ModSecurity 3.0 and NGINX: Quick Start Guide 41 Appendix B: Document Revision History