Block Malicious IPs on a Small Linux Site with iptables and Cron
This guide explains how to detect traffic attacks on a low‑traffic Linux website, split Nginx logs daily, identify IPs with excessive requests, and automatically block them using iptables rules scheduled via cron, complete with ready‑to‑run Bash scripts and common firewall commands.
Story Background
My small website running on a 4‑core 8 GB single server started receiving cloud‑monitor alerts; the logs revealed a traffic attack that woke me up at night.
Implementation Idea
Because the site has low traffic, any IP that accesses the site more than 10 times a day is considered suspicious.
To mitigate the attack I decided to write my own solution instead of buying expensive cloud security services.
Solution Overview
Monitor access.log and count requests per IP.
If an IP exceeds 100 requests in a day, block it with iptables. The threshold can be adjusted later.
Feature Breakdown
Write a script to split access.log by date.
Create a daily cron job at 00:00 to run the split script.
Write a script that parses the daily log and blocks IPs with >100 requests.
Schedule the blocking script to run every 10 minutes.
1. Log Splitting Script (log_cut.sh)
Replace LOG_PATH and PID with your own paths.
# Every day at 00:00 run this script to split Nginx logs
#!/bin/bash
# Path to Nginx logs (change to your own)
LOG_PATH=/data/logs/nginx/
YESTERDAY=$(date -d "yesterday" +%Y-%m-%d)
# Path to Nginx PID file (change to your own)
PID=/var/run/nginx.pid
# Move yesterday's log
mv ${LOG_PATH}access.log ${LOG_PATH}access-${YESTERDAY}.log
# Tell Nginx to reopen logs
kill -USR1 `cat ${PID}`2. Cron Job for Log Splitting
0 0 * * * cd /www/Home/ && ./log_cut.sh3. IP Blocking Script (blackip.sh)
Replace logdir with the path to your access log.
# Run every 10 minutes to block abusive IPs
#!/bin/bash
logdir=/data/logs/nginx/access.log
port=443
for drop_ip in $(cat $logdir | grep -v '127.0.0.1' | awk '{print $1}' | sort | uniq -c | sort -rn | awk '{if ($1>100) print $2}'); do
# Avoid duplicate entries
num=$(grep ${drop_ip} /tmp/nginx_deny.log | wc -l)
if [ $num -ge 1 ]; then
continue
fi
iptables -I INPUT -p tcp --dport ${port} -s ${drop_ip} -j DROP
echo ">>>>> $(date '+%Y-%m-%d %H%M%S') - Detected attack source -> ${drop_ip}" >> /tmp/nginx_deny.log
done4. Cron Job for IP Blocking
*/10 * * * * cd /www/Home/ && ./blackip.shBlocking Effect
After deploying the scripts, the server no longer suffers from the random attacks.
Unblocking Commands
If you accidentally block a legitimate IP, you can remove it:
# Remove a specific IP
iptables -t filter -D INPUT -s 1.2.3.4 -j DROP
# Flush all rules
iptables -FCommon iptables Commands
iptables -F– Flush all rules. iptables-save > iptables.txt – Backup current rules. iptables-restore < iptables.txt – Restore from backup. service iptables save – Make rules persistent across reboots. iptables -t filter -D INPUT -s 1.2.3.4 -j DROP – Delete a specific rule. iptables -I INPUT -s $ip -j DROP – Block a single IP. iptables -I INPUT -s $ip/$mask -j DROP – Block an IP range. iptables -A INPUT -p tcp --dport 80 -j DROP – Block all traffic to port 80. iptables -A INPUT -j DROP – Drop all incoming traffic.
Conclusion
Instead of configuring Nginx blacklists and restarting the server, using Linux's built‑in iptables firewall provides a simple, efficient way to block malicious IPs without exposing 403 pages to attackers.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Su San Talks Tech
Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
