ModSecurity is an open source project started in 2002, currently backed and
maintained by SpiderLabs.
The main tools in the ModSecurity toolbox are parsing, and the rule engine.
At the start of the application, ModSecurity will parse and classify a set of rules.
For each request it will buffer the request and response headers/bodies, parse them against the
rule set and finally log all relevant information. The version used for Varnish WAF, is 3.0.3
.
To change the settings of ModSecurity edit /etc/varnish/modsec/modsecurity.conf
.
ModSecurity rules are called SecRules. The format for for a SecRule is:
SecRule VARIABLES "OPERATOR" "TRANSFORMATIONS,ACTIONS"
The variables can include specific headers, the request body, etc. The operator will check against the variables. This can be regex or a simple equals. Transformations and actions include id number, phase, hashing, block a request, or deny a request. Transformations are done before the operator comparison, while actions are done if the comparison was successful. Each rule must contain an ID number. An example of a simple rule to check if a request URL is equal to index.php is:
SecRule REQUEST_URI "@streq /index.php" "id:1,phase:1,t:lowercase,deny"
More information about SecRule formats can be found here and more information about what a SecRule is made up of can be found here. Some basic rules on creating a SecRule are:
@rx
is implied.SecDefaultAction
(default phase:2, log, auditlog, pass
).ModSecurity provides a tool, modsec-rules-check
, to determine the validity of rules and configuration files. There are a few different ways to use this program.
# Checking one file
modsec-rules-check /etc/varnish/modsec/owasp-crs-v3.1.1/rules/REQUEST-901-INITIALIZATION.conf
: /etc/varnish/modsec/owasp-crs-v3.1.1/rules/REQUEST-901-INITIALIZATION.conf -- Loaded 40 rules.
Test ok.
# Checking multiple files using globbing
modsec-rules-check /etc/varnish/modsec/owasp-crs-v3.1.1/rules/*.conf
: /etc/varnish/modsec/owasp-crs-v3.1.1/rules/crs-setup.conf -- Loaded 1 rules.
: /etc/varnish/modsec/owasp-crs-v3.1.1/rules/REQUEST-901-INITIALIZATION.conf -- Loaded 40 rules.
. . .
Test ok.
The SecRuleEngine
in modsecurity.conf
dictates how disruptive ModSecurity
can be:
off
: the engine is completely inactive, no detection is even done.DetectionOnly
: rules are active, but no disruptive action is undertaken.
It’s the default to allow you to analyze what ModSecurity will do once fully
activated.on
: fully active, traffic is analyzed and possibly blocked if issues are
found.If using the OWASP CRS, you can read how the disruptive actions occur here.
ModSecurity goes through a specific order of operations, called phases. The phases determine the risk of a request, ensuring protection of a backend. Each phase will either block and finish the request by logging, or continue to the next phase. The phases are as follows:
text/xml
, multipart/form-data
and
application/x-www-form-urlencoded
.SecRequestBodyAccess
set to On
.SecRequestBodyLimit
and SecRequestBodyLimitAction
.SecResponseBodyAccess
set to On
.SecResponsetBodyLimit
and SecResponseBodyLimitAction
.SecResponseBodyMimeType
.ModSecurity’s logging is generally verbose and resource expensive. It is suggested to use logging in the testing phase of an application but disable it once it reaches production. On a disruptive action Varnish will log information from ModSecurity about the request. There are two types of logs: debug and audit.
This is a verbose log on everything ModSecurity does for a request. This tool is best used testing
and troubleshooting. The path to the debug log is set with SecDebugLog
. There are 7 levels of logging, (1-6, 9) that can be set with
SecDebugLogLevel
:
This is a log to track the data of a HTTP request. This is less verbose than the debug log but still
resource expensive. SecAuditEngine
determines if the audit log should be used. It can be set to
On
, Off
or RelevantOnly
. RelevantOnly
will log for specific response codes set by
SecAuditLogRelevantStatus
. This defaults to ^(?:5|4(?!04))
. The audit log is broken down into
12 parts, A-K, and Z. All but two are optional. The parts are:
multipart/form-data
encoding.