ModSecurity is the leading open-source Web Application Firewall (WAF), capable of inspecting all HTTP requests and responses against a ruleset and blocking malicious traffic including SQL injection, cross-site scripting (XSS), remote file inclusion, and OWASP Top 10 attack patterns. Combined with the OWASP Core Rule Set (CRS), ModSecurity transforms Apache into a security gateway that sits in front of your application and filters requests before they reach your code. On RHEL 9, ModSecurity for Apache is installed from the AppStream repository as mod_security, and the OWASP CRS is available separately. This guide covers installing ModSecurity with Apache on RHEL 9, enabling the OWASP Core Rule Set in detection mode, tuning rules to eliminate false positives, and switching to enforcement mode.
Prerequisites
- Apache (httpd) installed and running on RHEL 9
- Root or sudo access
Step 1 — Install ModSecurity
dnf install -y mod_security mod_security_crs
# Verify the module loaded
httpd -M | grep security
# Check the version
rpm -q mod_security
Step 2 — Understand the Configuration Files
/etc/httpd/conf.d/mod_security.conf— main ModSecurity configuration loaded by Apache/etc/httpd/modsecurity.d/— additional rule files/usr/share/mod_security_crs/— OWASP Core Rule Set files/var/log/httpd/modsec_audit.log— ModSecurity audit log
Step 3 — Configure ModSecurity in Detection Mode
Always start in detection mode (DetectionOnly) so you can tune rules before blocking legitimate traffic:
vi /etc/httpd/conf.d/mod_security.conf
# Enable ModSecurity
SecRuleEngine DetectionOnly # Change to On for enforcement
# Log format
SecAuditEngine RelevantOnly # Only log relevant transactions
SecAuditLog /var/log/httpd/modsec_audit.log
SecAuditLogParts ABIJDEFHZ
SecAuditLogType Serial
# Request body handling
SecRequestBodyAccess On
SecRequestBodyLimit 13107200 # 12.5MB
SecRequestBodyNoFilesLimit 131072
# Response body handling
SecResponseBodyAccess Off # Enable to inspect responses too
# Temporary file storage for large request bodies
SecTmpDir /tmp/
SecDataDir /tmp/
# Include OWASP CRS
Include /etc/httpd/modsecurity.d/*.conf
Include /usr/share/mod_security_crs/crs-setup.conf
Include /usr/share/mod_security_crs/rules/*.conf
apachectl configtest && systemctl reload httpd
Step 4 — Test ModSecurity is Working
# Test with a known XSS payload
curl -s "http://localhost/?q=alert(1)" -o /dev/null -w "%{http_code}n"
# In DetectionOnly mode: returns 200 but logs the event
# In enforcement mode: returns 403
# Check the audit log
tail -50 /var/log/httpd/modsec_audit.log
Step 5 — Tune Rules to Eliminate False Positives
Before switching to enforcement mode, run in detection mode for at least 48 hours and review the audit log for false positives:
# Find the most frequently triggered rule IDs
grep 'id "[0-9]' /var/log/httpd/modsec_audit.log |
grep -oP 'id "[0-9]+"' | sort | uniq -c | sort -rn | head -20
# Create a custom exclusion file
vi /etc/httpd/modsecurity.d/exclusions.conf
# Disable a specific rule by ID
SecRuleRemoveById 920350
# Disable a rule for a specific URI
SecRule REQUEST_URI "@beginsWith /admin/upload"
"id:1000,phase:1,pass,nolog,ctl:ruleRemoveById=920420"
# Disable a rule for a specific parameter
SecRuleRemoveTargetById 942100 "ARGS:editor_content"
Step 6 — Switch to Enforcement Mode
Once false positives are resolved, switch from DetectionOnly to enforcement:
sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/'
/etc/httpd/conf.d/mod_security.conf
apachectl configtest && systemctl reload httpd
# Verify enforcement is active
grep SecRuleEngine /etc/httpd/conf.d/mod_security.conf
Verification Checklist
httpd -M | grep security2
grep SecRuleEngine /etc/httpd/conf.d/mod_security.conf
curl -si "http://localhost/?q=alert(1)" | head -1
tail -5 /var/log/httpd/modsec_audit.log
Conclusion
ModSecurity with the OWASP Core Rule Set on RHEL 9 Apache provides enterprise-grade WAF protection against OWASP Top 10 attacks. Always deploy in DetectionOnly first, tune false positives with rule exclusions, then switch to enforcement mode. Regular CRS updates (dnf update mod_security_crs) keep your WAF current with evolving threats.
Next steps: How to Configure Nginx with ModSecurity WAF on RHEL 9, How to Configure Nginx Rate Limiting on RHEL 9, and How to Harden Web Servers: Security Headers, CSP, HSTS on RHEL 9.