IP Blocker Script

A lightweight automatic DDoS protection script for Linux servers. Runs via cron every 10 minutes, scans Apache and Nginx access logs, detects IPs exceeding a configurable request threshold, and blocks them at the kernel level using iptables.

🛡

Kernel-Level Blocking

Blocks via iptables -I INPUT 1 — packets dropped before reaching the web server

Cloudflare Aware

Fetches Cloudflare IP ranges dynamically — never accidentally blocks proxy traffic

🔄

Weekly Auto-Reset

Clears all blocks every Sunday — persistent attackers get re-blocked within 10 minutes

🔍

Dual Log Format

Parses both combined and vhost_combined Apache/Nginx log formats

Installation

# Download and install
sudo cp ip-blocker.sh /usr/local/bin/ip-blocker.sh
sudo chmod +x /usr/local/bin/ip-blocker.sh

# Add to crontab (every 10 minutes)
(crontab -l 2>/dev/null; echo "*/10 * * * * /usr/local/bin/ip-blocker.sh >> /var/log/ip-blocker.log 2>&1") | crontab -

Usage

ip-blocker.sh

Detect and block (normal cron operation):

ip-blocker.sh

Preview without blocking:

ip-blocker.sh --dry-run

Show currently blocked IPs:

ip-blocker.sh --list

Manually unblock an IP:

ip-blocker.sh --unblock 1.2.3.4

Options

Option Default Description
--dry-run off Detect offenders but do not block them
--list Show all currently blocked IPs with timestamps
--unblock IP Remove a specific IP from the blocklist and iptables
--threshold N 250 Requests per window that triggers a block
--window N 10 Analysis window in minutes (should match cron interval)

How It Works

1. Scan Access Logs

Auto-discovers access log files from standard locations (/var/log/apache2/, /var/log/nginx/, /var/log/httpd/). Filters log entries to only the configured time window (default: last 10 minutes).

2. Count Requests Per IP

Parses both combined format (IP is first field) and vhost_combined format (IP is second field, after host:port). Counts total requests per unique IP address.

3. Whitelist Check

IPs are checked against a comprehensive whitelist before any blocking:

Range Description
127.0.0.0/8 Loopback
10.0.0.0/8 Private network (RFC 1918)
172.16.0.0/12 Private network (RFC 1918)
192.168.0.0/16 Private network (RFC 1918)
169.254.0.0/16 Link-local
Cloudflare ranges Fetched dynamically from cloudflare.com/ips-v4, cached 24h

4. Block via iptables

Offending IPs are blocked using iptables -I INPUT 1, which inserts the DROP rule at position 1 in the INPUT chain — before any ALLOW rules. This ensures packets are dropped at the kernel level before reaching the web server.

5. Weekly Reset

Every Sunday, all blocks are automatically cleared. This prevents false positives from persisting indefinitely. If an attacker is still active, they will be re-detected and re-blocked within 10 minutes by the next cron run.

Files

File Purpose
/etc/ip-blocker.list Persistent list of blocked IPs with timestamps
/var/log/ip-blocker.log Log file (when run via cron)
/tmp/ip-blocker-cloudflare.cache Cached Cloudflare IP ranges (refreshed every 24h)
/tmp/ip-blocker.lock Lockfile to prevent concurrent cron runs

Example: Attack Detected

[2026-02-16 01:30:01] Refreshed Cloudflare IP list (14 ranges)
[2026-02-16 01:30:01] BLOCKED 188.211.233.226 - 672 requests in 10min
[2026-02-16 01:40:01] No offenders detected (threshold: 250 req/10min)

Cloudflare & Direct Connections

This script blocks at the TCP/IP layer (iptables), which means it only catches attackers connecting directly to your origin server, bypassing Cloudflare. Traffic proxied through Cloudflare appears as Cloudflare IPs and is whitelisted. For Cloudflare-proxied attacks, use Cloudflare's built-in WAF and rate limiting rules.

Compatibility

Component Supported
Web Server Apache 2.x, Nginx
Log Formats combined, vhost_combined, common
Firewall iptables (works alongside UFW, firewalld)
OS Any Linux with iptables and bash
Dependencies iptables, curl, flock, awk (mawk or gawk)