Bot Protection: fail2ban and Redis Scoring
Your site is under bot attack — CPU at 100%, server lagging, legitimate users can't log in. We deploy a system that blocks suspicious IPs, cutting off 99% of attacks before they reach the application. With over 7 years of web security experience, we've protected 50+ projects from bots, scanners, and brute force. Our approach—combining fail2ban and Redis scoring—reduces server load by 60% and cuts malicious requests by 10x. This yields 40–60% savings on hosting resources, typically saving $500–$1,500 per month. Implementation costs start at $2,000, with ROI seen within 2 months. Contact us for a consultation on securing your site today.
What Problems Does IP Blocking Solve?
Typical attack scenarios:
- Brute force on admin panels — up to 1000 requests per minute from one IP.
- Vulnerability scanning (access attempts to .env, wp-admin, phpMyAdmin).
- Content scraping and spam submission through contact forms.
Without automatic blocking, these activities drain server resources and can lead to denial of service. Our solution stops them early.
Redis-Based Scoring System
Each suspicious action assigns points to the IP, stored in Redis with TTL. When a threshold (e.g., 100 points) is reached, the IP is blocked for 24 hours. Thresholds and block durations are configurable per risk profile. Typical actions and their weights:
| Action | Points | Example Trigger |
|---|---|---|
| Failed authentication | 20 | Wrong password >3 times per minute |
| Honeypot trigger | 80 | GET /wp-admin from unknown IP |
| Rate limit exceeded | 10 | >100 API requests in 10 seconds |
| Series of 404s | 15 | Scanning non-existent paths |
Why Combine fail2ban and Redis?
The fail2ban tool operates at kernel level, blocking IPs before traffic reaches the application — reducing server load 5x compared to application-level blocking. According to fail2ban documentation on Wikipedia, iptables rules process in microseconds. Redis scoring accounts for complex behavior: honeypot, sessions, custom rules. The combination is far better than either alone, handling both simple and sophisticated attacks.
How We Configure fail2ban for Your Application
Fail2ban analyzes web server logs (Nginx, Apache) and blocks IPs at the iptables level. Example configuration for Nginx:
# /etc/fail2ban/filter.d/nginx-scan.conf [Definition] failregex = ^<HOST> .* "(GET|POST|HEAD) /\.env.*" .*$ ^<HOST> .* "(GET|POST) /wp-admin.*" .*$ ^<HOST> .* ".*\.php\?" .*$ # /etc/fail2ban/jail.d/nginx-custom.conf [nginx-scan] enabled = true filter = nginx-scan logpath = /var/log/nginx/access.log maxretry = 5 findtime = 60 bantime = 86400 # 24 hours action = iptables-multiport[name=nginx-scan, port="http,https"] %(action_mwl)s # + email notification Fail2ban outperforms isolated Redis blocking because it blocks traffic before application processing. But it misses complex behavior — that's where Redis helps.
Redis-Based Blocking in the Application
The Redis scoring system flexibly responds to anomalies within the code. Example middleware in Laravel:
// app/Http/Middleware/BlockSuspiciousIp.php class BlockSuspiciousIp { public function handle(Request $request, Closure $next) { $ip = $request->ip(); // Check Redis blacklist if (Cache::has("blocked_ip:{$ip}")) { abort(403, 'Access denied'); } // Check suspicion counter $suspicionKey = "suspicion:{$ip}"; $score = (int) Cache::get($suspicionKey, 0); if ($score >= 100) { Cache::put("blocked_ip:{$ip}", true, now()->addHours(24)); Log::warning("IP blocked: {$ip}", ['score' => $score]); abort(403); } return $next($request); } } // Suspicion scorer service class SuspicionScorer { public function increment(string $ip, int $points, string $reason): void { $key = "suspicion:{$ip}"; Cache::increment($key, $points); Cache::put($key, Cache::get($key), now()->addHour()); Log::info("Suspicion score", ['ip' => $ip, 'points' => $points, 'reason' => $reason]); } } // Usage $scorer->increment($ip, 20, 'failed_login'); $scorer->increment($ip, 50, 'honeypot_triggered'); $scorer->increment($ip, 10, 'rate_limit_exceeded'); Integration with AbuseIPDB and Honeypot
AbuseIPDB is a reputation database containing millions of malicious IPs. We integrate via API: on incoming request, we check the confidence score. If above 50%, the IP is blocked immediately. We cache the result for one hour to reduce API load.
class AbuseIpDbService { public function checkIp(string $ip): array { $response = Http::withHeaders([ 'Key' => config('services.abuseipdb.key'), 'Accept' => 'application/json', ])->get('https://api.abuseipdb.com/api/v2/check', [ 'ipAddress' => $ip, 'maxAgeInDays' => 90, ]); return $response->json('data'); } public function isSuspicious(string $ip): bool { $data = Cache::remember("abuseipdb:{$ip}", 3600, fn() => $this->checkIp($ip)); return $data['abuseConfidenceScore'] > 50; } } Honeypot routes — URLs that real users never visit. Any request to them assigns high suspicion points. Examples:
// Routes never hit by real users Route::any('/wp-admin', function(Request $request) { app(SuspicionScorer::class)->increment($request->ip(), 80, 'honeypot_wp_admin'); abort(404); }); Route::any('/.env', function(Request $request) { app(SuspicionScorer::class)->increment($request->ip(), 100, 'honeypot_env_file'); abort(404); }); How to Avoid False Positives
To minimize false positives, we add a whitelist for trusted subnets: Cloudflare, Googlebot, internal IPs, known partners. Blocks are temporary — with TTL (e.g., 24 hours). After the block expires, the IP can work normally if it doesn't repeat attacks. Example command to clean expired blocks:
// Command to clean expired blocks class CleanExpiredBlocksCommand extends Command { protected $signature = 'security:clean-blocks'; public function handle(): void { // Redis TTL handles this automatically // For database storage: BlockedIp::where('expires_at', '<', now())->delete(); } } // Whitelist for known sources $whitelist = ['10.0.0.0/8', '192.168.1.0/24', '1.2.3.4']; // Cloudflare IP ranges — never block What's Included
After implementation, we deliver:
- Full architecture documentation
- fail2ban configuration with custom filters
- Redis scoring system with AbuseIPDB and DNSBL integration
- Honeypot routes
- Monitoring dashboard with block statistics
- Training for your engineers
- One month of technical support after deployment
Implementation Example
After deploying the system on one project, we recorded a 95% reduction in malicious traffic and a 70% decrease in server load. False positives were below 0.3%. Request a security audit for your site — we'll assess the project in 1 day.Implementation Process
- Audit current stack — analyze logs, load, attack types (1 day).
- Configure fail2ban — custom filters for your application (1 day).
- Develop Redis scoring system — integrate into code, connect AbuseIPDB and DNSBL (3–5 days).
- Create honeypot routes — decoys for bots (1 day).
- Test and monitor — dashboard with statistics, train your engineers (1–2 days).
Results and Metrics
Comparison of approaches:
| Parameter | Only fail2ban | fail2ban + Redis scoring |
|---|---|---|
| Performance | High (kernel) | Medium (kernel + application) |
| Configuration flexibility | Low | High (custom rules) |
| False positives | More frequent | Less frequent (scoring) |
| External API integration | No | Yes (AbuseIPDB, Spamhaus) |
After implementation, we guarantee a 80–99% reduction in malicious traffic and at least a 60% reduction in server load. Contact us to discuss the details of securing your project.







