Use ModSecurity to protect your AEM site from DoS attacks
Learn how to enable ModSecurity to protect your site from Denial of Service (DoS) attacks using the OWASP ModSecurity Core Rule Set (CRS) on the ÃÛ¶¹ÊÓƵ Experience Manager (AEM) Publish Dispatcher.
Overview
The foundation provides the outlining the ten most critical security concerns for web applications.
ModSecurity is an open-source, cross-platform solution that provides protection from a range of attacks against web applications. It also allows for HTTP traffic monitoring, logging, and real-time analysis.
OWSAP® also provides the . The CRS is a set of generic attack detection rules for use with ModSecurity. Thus CRS aims to protect web applications from a wide range of attacks, including the OWASP Top Ten, with a minimum of false alerts.
This tutorial demonstrates how to enable and configure the DOS-PROTECTION CRS rule to protect your site from a potential DoS attack.
Add CRS to Dispatcher project module
-
Download and extract the .
code language-shell # Replace the X.Y.Z with relevent version numbers. $ wget https://github.com/coreruleset/coreruleset/archive/refs/tags/vX.Y.Z.tar.gz # For version v3.3.5 when this tutorial is published $ wget https://github.com/coreruleset/coreruleset/archive/refs/tags/v3.3.5.tar.gz # Extract the downloaded file $ tar -xvzf coreruleset-3.3.5.tar.gz
-
Create the
modsec/crs
folders withindispatcher/src/conf.d/
in your AEM project’s code. For example, in the local copy of the .{width="200" modal="regular"}
-
Copy the
coreruleset-X.Y.Z/rules
folder from the downloaded CRS release package into thedispatcher/src/conf.d/modsec/crs
folder. -
Copy the
coreruleset-X.Y.Z/crs-setup.conf.example
file from the downloaded CRS release package into thedispatcher/src/conf.d/modsec/crs
folder and rename it tocrs-setup.conf
. -
Disable all the copied CRS rules from the
dispatcher/src/conf.d/modsec/crs/rules
by renaming them asXXXX-XXX-XXX.conf.disabled
. You can use the below commands to rename all files at once.code language-shell # Go inside the newly created rules directory within the dispathcher module $ cd dispatcher/src/conf.d/modsec/crs/rules # Rename all '.conf' extension files to '.conf.disabled' $ for i in *.conf; do mv -- "$i" "$i.disabled"; done
See renamed CRS rules and config file in the WKND project code.
{width="200" modal="regular"}
Enable and configure Denial of Service (DoS) protection rule
To enable and configure the Denial of Service (DoS) protection rule, follow the below steps:
-
Enable the DoS protection rule by renaming the
REQUEST-912-DOS-PROTECTION.conf.disabled
toREQUEST-912-DOS-PROTECTION.conf
(or remove the.disabled
from rulename extension) within thedispatcher/src/conf.d/modsec/crs/rules
folder. -
Configure the rule by defining the DOS_COUNTER_THRESHOLD, DOS_BURST_TIME_SLICE, DOS_BLOCK_TIMEOUT variables.
- Create a
crs-setup.custom.conf
file within thedispatcher/src/conf.d/modsec/crs
folder. - Add the below rule snippet to the newly created file.
code language-none # The Denial of Service (DoS) protection against clients making requests too quickly. # When a client is making more than 25 requests (excluding static files) within # 60 seconds, this is considered a 'burst'. After two bursts, the client is # blocked for 600 seconds. SecAction \ "id:900700,\ phase:1,\ nolog,\ pass,\ t:none,\ setvar:'tx.dos_burst_time_slice=60',\ setvar:'tx.dos_counter_threshold=25',\ setvar:'tx.dos_block_timeout=600'"
- Create a
In this example rule configuration, DOS_COUNTER_THRESHOLD is 25, DOS_BURST_TIME_SLICE is 60 seconds, and DOS_BLOCK_TIMEOUT timeout is 600 seconds. This configuration identifies more than two occurrences of 25 requests, excluding static files, within 60 seconds qualify as a DoS attack, resulting in the requesting client to be blocked for 600 seconds (or 10 mins).
Initialize the CRS
To initialize the CRS, remove common false positives, and add local exceptions for your site follow the below steps:
-
To initialize the CRS, remove
.disabled
from the REQUEST-901-INITIALIZATION file. In other words, rename theREQUEST-901-INITIALIZATION.conf.disabled
file toREQUEST-901-INITIALIZATION.conf
. -
To remove the common false positives like local IP (127.0.0.1) ping, remove
.disabled
from the REQUEST-905-COMMON-EXCEPTIONS file. -
To add local exceptions like the AEM platform or your site-specific paths, rename the
REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example
toREQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
- Add AEM platform-specific path exceptions to the newly renamed file.
code language-none ######################################################## # AEM as a Cloud Service exclusions # ######################################################## # Ignoring AEM-CS Specific internal and reserved paths SecRule REQUEST_URI "@beginsWith /systemready" \ "id:1010,\ phase:1,\ pass,\ nolog,\ ctl:ruleEngine=Off" SecRule REQUEST_URI "@beginsWith /system/probes" \ "id:1011,\ phase:1,\ pass,\ nolog,\ ctl:ruleEngine=Off" SecRule REQUEST_URI "@beginsWith /gitinit-status" \ "id:1012,\ phase:1,\ pass,\ nolog,\ ctl:ruleEngine=Off" ######################################################## # ADD YOUR SITE related exclusions # ######################################################## ...
-
Also, remove the
.disabled
from REQUEST-910-IP-REPUTATION.conf.disabled for IP reputation block check andREQUEST-949-BLOCKING-EVALUATION.conf.disabled
for anomaly score check.
Add ModSecurity Apache configuration
To enable ModSecurity (aka mod_security
Apache module), follow the below steps:
-
Create
modsecurity.conf
atdispatcher/src/conf.d/modsec/modsecurity.conf
with the below key configurations.code language-none # Include the baseline crs setup Include conf.d/modsec/crs/crs-setup.conf # Include your customizations to crs setup if exist IncludeOptional conf.d/modsec/crs/crs-setup.custom.conf # Select all available CRS rules: #Include conf.d/modsec/crs/rules/*.conf # Or alternatively list only specific ones you want to enable e.g. Include conf.d/modsec/crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf Include conf.d/modsec/crs/rules/REQUEST-901-INITIALIZATION.conf Include conf.d/modsec/crs/rules/REQUEST-905-COMMON-EXCEPTIONS.conf Include conf.d/modsec/crs/rules/REQUEST-910-IP-REPUTATION.conf Include conf.d/modsec/crs/rules/REQUEST-912-DOS-PROTECTION.conf Include conf.d/modsec/crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf # Start initially with engine off, then switch to detection and observe, and when sure enable engine actions #SecRuleEngine Off #SecRuleEngine DetectionOnly SecRuleEngine On # Remember to use relative path for logs: SecDebugLog logs/httpd_mod_security_debug.log # Start with low debug level SecDebugLogLevel 0 #SecDebugLogLevel 1 # Start without auditing SecAuditEngine Off #SecAuditEngine RelevantOnly #SecAuditEngine On # Tune audit accordingly: SecAuditLogRelevantStatus "^(?:5|4(?!04))" SecAuditLogParts ABIJDEFHZ SecAuditLogType Serial # Remember to use relative path for logs: SecAuditLog logs/httpd_mod_security_audit.log # You might still use /tmp for temporary/work files: SecTmpDir /tmp SecDataDir /tmp
-
Select the desired
.vhost
from your AEM project’s Dispatcher moduledispatcher/src/conf.d/available_vhosts
, for example,wknd.vhost
, add the below entry outside the<VirtualHost>
block.code language-none # Enable the ModSecurity and OWASP CRS <IfModule mod_security2.c> Include conf.d/modsec/modsecurity.conf </IfModule> ... <VirtualHost *:80> ServerName "publish" ... </VirtualHost>
All the above ModSecurity CRS and DOS-PROTECTION configurations are available on the AEM WKND Sites Project’s branch for your review.
Validate Dispatcher configuration
When working with AEM as a Cloud Service, before deploying your Dispatcher configuration changes, it’s recommended to validate them locally using validate
script of the AEM SDK’s Dispatcher Tools.
# Go inside Dispatcher SDK 'bin' directory
$ cd <YOUR-AEM-SDK-DIR>/<DISPATCHER-SDK-DIR>/bin
# Validate the updated Dispatcher configurations
$ ./validate.sh <YOUR-AEM-PROJECT-CODE-DIR>/dispatcher/src
Deploy
Deploy the locally validated Dispatcher configurations using the Cloud Manager Web Tier or Full Stack pipeline. You can also use the Rapid Development Environment for faster turnaround time.
Verify
To verify the DoS protection, in this example, let’s send more than 50 requests (25 request threshold times two occurrences) within a span of 60 seconds. However, these requests should pass through the AEM as a Cloud Service built-in or any other CDN fronting your website.
One technique to achieve the CDN pass-through is to add a query parameter with a new random value on each site page request.
To trigger a larger number of requests (50 or more) within a short period (like 60 seconds), the Apache or can be used.
Simulate DoS attack using JMeter script
To simulate a DoS attack using JMeter, follow the below steps:
-
and it locally
-
it locally using the
jmeter
script from the<JMETER-INSTALL-DIR>/bin
directory. -
Open the sample WKND-DoS-Attack-Simulation-Test JMX script into JMeter using the Open tool menu.
-
Update the Server Name or IP field value in Home Page and Adventure Page HTTP Request sampler matching your test AEM environment URL. Review other details of the sample JMeter script.
-
Execute the script by pressing the Start button from the tool menu. The script sends 50 HTTP requests (5 users and 10 loop counts) against the WKND site’s Home Page and Adventure Page. Thus a total of 100 requests to non-static files, it qualifies the DoS attack per DOS-PROTECTION CRS rule custom configuration.
-
The View Results in Table JMeter listener shows Failed response status for request number ~ 53 and beyond.
-
The 503 HTTP Response code is returned for the failed requests, you can view the details using the View Results Tree JMeter listener.
Review logs
The ModSecurity logger configuration logs the details of the DoS attack incident. To view the details, follow the below steps:
-
Download and open the
httpderror
log file of the Publish Dispatcher. -
Search for word
burst
in the log file, to see the error linescode language-none Tue Aug 15 15:19:40.229262 2023 [security2:error] [pid 308:tid 140200050567992] [cm-p46652-e1167810-aem-publish-85df5d9954-bzvbs] [client 192.150.10.209] ModSecurity: Warning. Operator GE matched 2 at IP:dos_burst_counter. [file "/etc/httpd/conf.d/modsec/crs/rules/REQUEST-912-DOS-PROTECTION.conf"] [line "265"] [id "912170"] [msg "Potential Denial of Service (DoS) Attack from 192.150.10.209 - # of Request Bursts: 2"] [ver "OWASP_CRS/3.3.5"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "paranoia-level/1"] [tag "attack-dos"] [tag "OWASP_CRS"] [tag "capec/1000/210/227/469"] [hostname "publish-p46652-e1167810.adobeaemcloud.com"] [uri "/content/wknd/us/en/adventures.html"] [unique_id "ZNuXi9ft_9sa85dovgTN5gAAANI"] ... Tue Aug 15 15:19:40.515237 2023 [security2:error] [pid 309:tid 140200051428152] [cm-p46652-e1167810-aem-publish-85df5d9954-bzvbs] [client 192.150.10.209] ModSecurity: Access denied with connection close (phase 1). Operator EQ matched 0 at IP. [file "/etc/httpd/conf.d/modsec/crs/rules/REQUEST-912-DOS-PROTECTION.conf"] [line "120"] [id "912120"] [msg "Denial of Service (DoS) attack identified from 192.150.10.209 (1 hits since last alert)"] [ver "OWASP_CRS/3.3.5"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "paranoia-level/1"] [tag "attack-dos"] [tag "OWASP_CRS"] [tag "capec/1000/210/227/469"] [hostname "publish-p46652-e1167810.adobeaemcloud.com"] [uri "/us/en.html"] [unique_id "ZNuXjAN7ZtmIYHGpDEkmmwAAAQw"]
-
Review the details like client IP address, action, error message, and request details.
Performance impact of ModSecurity
Enabling the ModSecurity and associated rules has some performance implications, so be mindful of which rules are required, redundant, and skipped. Partner with your Web Security experts to enable, and customize the CRS rules.
Additional Rules
This tutorial only enables and customizes the DOS-PROTECTION CRS rule for demonstration purposes. It is recommended to partner with Web Security experts to understand, review, and configure appropriate rules.