ModSecurity is an open-source web application firewall (WAF) engine. Combined with the OWASP Core Rule Set (CRS) it inspects every request and blocks common attacks such as SQL injection, cross-site scripting, path traversal and scanner probes before they reach your app. This guide installs ModSecurity with the OWASP CRS on a server you manage yourself.
Before you start
- Root access to a Linux VPS running Apache or Nginx.
- On cPanel servers use WHM's built-in tools instead: WHM ModSecurity vendors.
- A staging copy of the site is ideal for tuning.
How the pieces fit
- Engine: mod_security2 for Apache, or libmodsecurity (v3) plus a connector for Nginx.
- Rules: the OWASP CRS, a generic rule set that scores suspicious requests (anomaly scoring) and blocks when the total passes a threshold.
- Paranoia level: 1 (default) has few false positives; 2–4 catch more attacks but need more tuning.
Install on Apache
- Install the module:
- Ubuntu/Debian:
sudo apt install -y libapache2-mod-security2 - AlmaLinux/Rocky (EPEL):
sudo dnf install -y mod_security
- Ubuntu/Debian:
- Copy the recommended config (Debian path shown):
sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf - Leave
SecRuleEngine DetectionOnlyfor now.
Install on Nginx
- Recent Debian/Ubuntu ship the connector as a package:
sudo apt install -y libnginx-mod-http-modsecurity. Otherwise buildModSecurity-nginxas a dynamic module matching your exact Nginx version. - Create
/etc/nginx/modsec/main.conf:Include /etc/nginx/modsec/modsecurity.conf Include /etc/nginx/modsec/crs/crs-setup.conf Include /etc/nginx/modsec/crs/rules/*.conf - Enable it in the
serverblock:modsecurity on; modsecurity_rules_file /etc/nginx/modsec/main.conf;
Install the OWASP Core Rule Set
- Download the latest CRS v4 release from the project's GitHub releases page and extract it (for Nginx, to
/etc/nginx/modsec/crs; for Apache, e.g./etc/modsecurity/crs). - Copy the example setup:
cp crs-setup.conf.example crs-setup.conf. - For Apache, include the files from your ModSecurity config:Remove any older distro CRS include so rules do not load twice.
IncludeOptional /etc/modsecurity/crs/crs-setup.conf IncludeOptional /etc/modsecurity/crs/rules/*.conf - Test and reload:
apachectl configtestornginx -t, then reload the service.
Run in detection mode first
With SecRuleEngine DetectionOnly, matches are logged but nothing is blocked. Browse the site, log in, submit forms, use the admin area and checkout for a few days. Then read the audit log (/var/log/modsec_audit.log or /var/log/apache2/modsec_audit.log) and look for rule IDs that fire on legitimate traffic.
Quick test that the WAF sees attacks:
curl -s -o /dev/null -w "%{http_code}\n" "https://example.com/?q=../../etc/passwd"Tune false positives
Never edit CRS files. Add exclusions in a file loaded after the CRS (e.g. RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf) or before it for runtime rules:
SecRule REQUEST_URI "@beginsWith /wp-admin/post.php" "id:1000001,phase:1,pass,nolog,ctl:ruleRemoveTargetById=942100;ARGS:content"This removes one rule for one parameter on one URL, the narrowest exclusion possible. CRS also ships plugins with ready exclusions for WordPress, Drupal and Nextcloud.
Switch to blocking
When the logs are clean, set SecRuleEngine On and reload. Keep watching the audit log for the first week.
Troubleshooting
- 403 on saving posts or uploading: a false positive. Find the rule ID in the audit log and add a targeted exclusion.
- Nginx: module is not binary compatible: the connector was built for a different Nginx version. Rebuild against the running version.
- Audit log grows fast: set
SecAuditEngine RelevantOnlyand rotate the log.
FAQ: ModSecurity and OWASP CRS
Does ModSecurity slow the site?
Slightly; a few milliseconds per request at paranoia level 1. Caching in front reduces the cost.
Is a WAF a replacement for updates?
No. It buys time against known attack patterns; patching fixes the cause.
Does LiteSpeed support these rules?
Yes, LiteSpeed Enterprise reads ModSecurity rule sets, including the CRS.
