Why a Single Layer of Defense Isn't Enough Anymore#
Shared hosting is a magnet for automated attacks. Credential-stuffing bots, vulnerability scanners, and DDoS-for-hire scripts hammer servers around the clock. A firewall blocks network floods but sees nothing inside HTTP payloads. ModSecurity inspects payloads but can't throttle brute-force login storms that never trigger a CRS rule. Neither tool alone stops a botnet that already knows your IP ranges from a leaked customer list.
This tutorial walks you through building a multi-tier WAF stack using three free, production-proven tools:
- Nginx as the front-door reverse proxy with rate limiting and geo-blocking.
- ModSecurity v3 (with the OWASP CoreRuleSet) as the application-layer WAF.
- CrowdSec as a collaborative threat-intelligence engine that shares blocklists across your fleet.
The result is a layered defense where each tool handles what it does best, and CrowdSec automatically bans repeat offenders at the network level before they waste CPU cycles.
Prerequisites#
You need a Linux server (Ubuntu 22.04 or Debian 12 recommended) running Nginx 1.24+ and root or sudo access. If you're running a hosting control panel, make sure it uses Nginx as its web server rather than Apache — or front Apache with an Nginx reverse proxy.
sudo apt update && sudo apt install -y nginx libnginx-mod-http-modsecurity curl gnupg2Step 1: Enable and Configure ModSecurity v3#
1.1 — Activate the Module#
ModSecurity ships as an Nginx dynamic module on most distros. Create the engine config:
sudo mkdir -p /etc/nginx/modsec
sudo cp /etc/modsecurity/modsecurity.conf-recommended /etc/nginx/modsec/modsecurity.confEdit /etc/nginx/modsec/modsecurity.conf and change:
SecRuleEngine On
SecAuditLog /var/log/modsec_audit.log1.2 — Install the OWASP CoreRuleSet (CRS)#
cd /tmp
curl -sL https://github.com/coreruleset/coreruleset/archive/refs/tags/v4.0.tar.gz | tar xz
sudo mv coreruleset-4.0 /etc/nginx/modsec/crs
sudo cp /etc/nginx/modsec/crs/crs-setup.conf.example /etc/nginx/modsec/crs/crs-setup.confCreate /etc/nginx/modsec/main.conf to chain them together:
Include /etc/nginx/modsec/modsecurity.conf
Include /etc/nginx/modsec/crs/crs-setup.conf
Include /etc/nginx/modsec/crs/rules/*.conf1.3 — Wire It into Nginx#
Add these directives inside your http {} or server {} block:
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/main.conf;Reload Nginx:
sudo nginx -t && sudo systemctl reload nginxAt this point ModSecurity is inspecting every HTTP request against ~180 CRS rules covering SQL injection, XSS, remote code execution, and protocol violations.
Step 2: Add Nginx Rate Limiting and Bot Filtering#
ModSecurity excels at payload inspection, but it doesn't throttle floods. Add rate limiting directly in Nginx.
2.1 — Define Rate Zones#
In http {}:
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/s;
limit_req_zone $binary_remote_addr zone=general:10m rate=30r/s;
limit_conn_zone $binary_remote_addr zone=addr:10m;2.2 — Apply to Sensitive Endpoints#
location ~ ^/(cpanel|whm|webmail|admin) {
limit_req zone=login burst=10 nodelay;
limit_conn addr 10;
proxy_pass http://backend;
}
location / {
limit_req zone=general burst=50 nodelay;
proxy_pass http://backend;
}2.3 — Block Bad User-Agents#
Create /etc/nginx/snippets/block-bots.conf:
if ($http_user_agent ~* (semrush|ahrefs|mj12bot|dotbot|petalbot|Bytespider)) {
return 444;
}Include it in your server block:
include /etc/nginx/snippets/block-bots.conf;HTTP 444 drops the connection silently — no response body wasted on scrapers.
Step 3: Install CrowdSec for Collaborative Intelligence#
CrowdSec reads logs (Nginx, ModSecurity audit, SSH, etc.), detects attack patterns with its local agent, and bans IPs via a firewall bouncer. Its killer feature: you can opt into a community blocklist of millions of known malicious IPs.
3.1 — Install the Agent#
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
sudo apt install crowdsec3.2 — Install the Nginx and ModSecurity Collections#
sudo cscli collections install crowdsecurity/nginx
sudo cscli collections install crowdsecurity/modsecurity
sudo cscli hub update && sudo cscli hub upgradeThese collections include parsers for Nginx access logs and ModSecurity audit logs, plus scenarios for port scanning, credential brute-forcing, and web crawling.
3.3 — Install the Firewall Bouncer#
sudo apt install crowdsec-firewall-bouncer-iptables
sudo systemctl enable --now crowdsec-firewall-bouncerThe bouncer automatically inserts iptables (or nftables) rules to DROP traffic from banned IPs.
3.4 — Enable the Community Blocklist#
sudo cscli capi register
sudo cscli collections install crowdsecurity/blocklist-malicious
sudo systemctl restart crowdsecYou'll immediately start blocking tens of thousands of known-bad IPs with zero effort.
Step 4: Verify and Monitor#
Check CrowdSec Decisions#
sudo cscli decisions listYou should see bans accumulating within minutes.
Test ModSecurity#
curl -I "https://yourserver.com/?id=1' OR '1'='1"You should get a 403 Forbidden — that's CRS rule 942100 (SQL Injection Detection) doing its job.
Tail the Logs#
sudo tail -f /var/log/modsec_audit.log
sudo cscli metricsKeeping It Maintainable#
- Tune false positives. CRS ships in blocking mode. Run it in detection-only mode (
SecRuleEngine DetectionOnly) for a week on a busy server, review/var/log/modsec_audit.log, and add rule exclusions for legitimate traffic before switching to blocking. - Pin CrowdSec to your control panel logs. If you're running cPanel, DirectAdmin, or Salieno Core, add parsers for their access logs so brute-force login attempts get banned at the firewall level — not just by the panel's built-in rate limiter.
- Automate CRS updates. Add a cron job to pull the latest CRS release monthly:
0 3 1 * * cd /etc/nginx/modsec/crs && curl -sL https://github.com/coreruleset/coreruleset/archive/refs/tags/v4.0.tar.gz | tar xz --strip-components=1 && nginx -t && systemctl reload nginxThe Layered Payoff#
| Threat | Handled By |
|---|---|
| SQLi, XSS, RCE payloads | ModSecurity + CRS |
| Brute-force login floods | Nginx rate limiting |
| Known malicious IPs | CrowdSec community blocklist |
| Repeat offenders across your fleet | CrowdSec shared decisions |
| Scrapers and bad bots | Nginx User-Agent filter |
Each layer is free, open-source, and battle-tested in production. Together they give your shared hosting environment a defense posture that rivals commercial WAF appliances — without the per-domain licensing costs that eat into reseller margins. Start with ModSecurity and CRS today, add CrowdSec tomorrow, and you'll have a stack that scales with your fleet.
0 comments
Loading comments…