ModSecurity is an open-source Web Application Firewall (WAF) that protects web applications from common attacks like SQL injection, XSS, and file inclusion. While it works with both Apache and Nginx, this guide covers the Apache implementation.
Installation
# Install Apache and ModSecurity
sudo apt install apache2 libapache2-mod-security2
# Enable the module
sudo a2enmod security2
sudo systemctl restart apache2Basic Configuration
# Copy the recommended config
sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
# Enable detection mode first (log only, do not block)
sudo nano /etc/modsecurity/modsecurity.conf
# Change: SecRuleEngine DetectionOnly
# Later change to: SecRuleEngine OnInstall OWASP Core Rule Set (CRS)
# The CRS provides pre-built rules for common attacks
sudo apt install modsecurity-crs
# Or install latest from GitHub
cd /etc/modsecurity
sudo git clone https://github.com/coreruleset/coreruleset.git
sudo cp coreruleset/crs-setup.conf.example coreruleset/crs-setup.conf
# Include CRS in Apache config
# /etc/apache2/mods-enabled/security2.conf
IncludeOptional /etc/modsecurity/coreruleset/crs-setup.conf
IncludeOptional /etc/modsecurity/coreruleset/rules/*.conf
sudo systemctl restart apache2What CRS Protects Against
- SQL Injection (SQLi)
- Cross-Site Scripting (XSS)
- Local File Inclusion (LFI)
- Remote File Inclusion (RFI)
- Remote Code Execution (RCE)
- PHP injection
- Session fixation
- Scanner/bot detection
Tuning for False Positives
# View ModSecurity logs
sudo tail -f /var/log/apache2/modsec_audit.log
# Common false positives and exclusions:
# /etc/modsecurity/coreruleset/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
# Exclude a specific rule for a URL
SecRule REQUEST_URI "@beginsWith /api/" "id:1000,phase:1,pass,nolog,ctl:ruleRemoveById=941100"
# Exclude a specific parameter from checking
SecRule ARGS:content "@rx .*" "id:1001,phase:2,pass,nolog,ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:content"Monitoring and Logging
# ModSecurity audit log
/var/log/apache2/modsec_audit.log
# Check blocked requests
grep "Access denied" /var/log/apache2/error.log
# View rule violations
grep "ModSecurity" /var/log/apache2/error.log | tail -20Going to Enforcement Mode
# After testing in DetectionOnly mode and resolving false positives:
sudo nano /etc/modsecurity/modsecurity.conf
# Change: SecRuleEngine On
sudo systemctl restart apache2
# Monitor closely for the first few days