How to Detect Web Scanners (Nikto, sqlmap, Nuclei) on Your Server
Your web server is being probed right now. Automated vulnerability scanners like Nikto, sqlmap, Nuclei, and dozens of others run 24/7, looking for SQL injection points, exposed admin panels, directory traversals, and known CVEs. Most of them announce themselves in the User-Agent header. The rest reveal themselves through their behavior.
This guide covers how web scanners work, how to detect them using both signature matching and behavioral analysis, and how to automatically block them at the firewall level.
What automated web scanners do
Web scanners send hundreds or thousands of HTTP requests to your server, each testing for a specific vulnerability. A single Nuclei scan with the default template set sends over 3,000 requests. sqlmap probes every parameter for SQL injection. Nikto checks for thousands of known misconfigurations.
These tools are freely available and widely used by both security researchers and attackers. The difference is intent, but your server cannot tell the difference. What it can see is the pattern.
Known scanner signatures
Many scanners identify themselves in the HTTP User-Agent header. Inner Warden's user_agent_scanner and web_scan detectors recognize over 20 known scanner signatures:
Any request with a matching User-Agent is immediately flagged. But smart attackers change their User-Agent. That is where behavioral detection takes over.
Behavioral detection: HTTP error floods
Even when a scanner hides its identity, its behavior is distinctive. Web scanners generate abnormally high rates of HTTP 4xx errors because they request paths that do not exist on your server. A real user might hit one 404 page. A scanner hits hundreds.
Inner Warden's search_abuse detector tracks the 4xx error rate per source IP. When an IP generates more than the configured threshold of errors in a time window, it is flagged as a scanner regardless of its User-Agent.
Real example from production
The IP 192.0.2.71 ran a Nuclei scan against our Nginx server. It sent 2,847 requests in 4 minutes, generating 2,619 errors (404s and 403s). Inner Warden caught it via both methods:
Set it up
Web scanner detection requires Nginx access logs. Install Inner Warden and point the sensor at your Nginx log directory:
curl -fsSL https://innerwarden.com/install | sudo bashinnerwarden enable search-protectionThe sensor automatically discovers Nginx logs at /var/log/nginx/access.log and begins scanning for both signatures and behavioral anomalies. Verify detection is active:
innerwarden statusWhat to do next
- Port scan detection - web scans often follow port scans. Detect both for complete reconnaissance coverage.
- Credential stuffing protection - scanners that find login pages often follow up with credential stuffing attacks.
- Threat intelligence sharing - report web scanners to AbuseIPDB and push blocks to Cloudflare WAF.