How to make an automated connection checker and IP blocker for your server

Mar 23rd, 2013 | By | Category: Internet, Linux / Freebsd

I like to think of it as a door man for my server, or my little centurion 🙂  What this little guy does is checked the last 5 hours of access logs to your server to see if there are any IP’s that are hitting your server an unusually high amount of times.  If it finds any that are over the set limit it blocks them with iptables.  So as a disclaimer you need to have the following things setup and know how to use them:

  • iptables
  • global access logs turned on
  • Default log format for nginx:

log_format main ‘$remote_addr – $remote_user [$time_local] “$request” ‘
‘”$status” $body_bytes_sent “$http_referer” ‘
‘”$http_user_agent” “$http_x_forwarded_for”‘;

My environment is a debian 6 server running apache 2.2 and nginx, so for me I’m accessing my nginx access logs as apache is just acting as a proxy.

#Declare the date

Just a quick variable for the date, to be used with the logging

now=$(date +”%m_%d_%Y”)

#badIPChecker

#What we need to do first is to go through our access logs and print out a list of the top 10 offending IPs, sorted by the most connections.  I’ve also put a make believe IP at the end with a grep -v command.. this means that the listings will exclude all ip’s from that range, it’s a way to white list certain IP’s such as internal IP’s running automated processes.  Everything is appended to a text file for the day

cat /var/log/nginx/access.log | awk ‘{print $1}’ | sort | uniq -c | sort -n | grep -v 55.555 > /home/ipChecker/ipcheck_$now.txt

#autoBanIP

#Using Perl we are going to check the above generated daily log for any IP’s that have logged more than 600 connections to the server.  You will have to adjust this limit depending on how you and others use your server.  I have some users that log 500 connections every 5 hours some busy days so that’s why I had to up this to where it is but I would think that anywhere between 400-600 would be appropriate.  After the scan is done we print just the IP’s to a file and insert the command to run a block script I made for that particular IP(usr/local/sbin/blockIP).  It runs the little script it just made, turns the txt file of the IP’s into a log file(which will get appended to every script run which I have set to every 5 ours via a cron).  After that it just does a little tidying up and then truncates the log files so we get to start fresh 🙂  This last action will erase your global access logs but if you are worth your salt as an admin you no doubt have domain specific logs running(assuming you are using this for a webserver) and the global one just takes up space.

/usr/bin/perl -ne ‘print if grep {$_>600} /(\d{3,})/g’ /home/ipChecker/ipcheck_$now.txt | awk ‘{print $2}’ > /home/ipChecker/badIPs_$now.sh
sed -i “s/^/\/usr\/local\/sbin\/blockIP /g” /home/ipChecker/badIPs_$now.sh
/bin/bash /home/ipChecker/badIPs_$now.sh
cat /home/ipChecker/ipcheck_$now.txt >> /home/ipChecker/ipcheck_$now.log
rm /home/ipChecker/ipcheck_$now.txt
rm /home/ipChecker/badIPs_$now.sh/usr/bin/truncate -s 0 /var/log/nginx/access.log

 

blockIP

#this little diddy is just to allow me to quickly block IP’s with a quick flick of my fingers 🙂  Obviously $1 is the IP address so the syntax would be #blockIP 55.555.555.555 or whatever you want to block

#!/bin/bash
sudo iptables -I INPUT -s $1 -j DROP
sudo bash -c “iptables-save > /etc/network/iptables.save”

 

So that’s it, just put the second script on your server and cron the first for whatever crono-frequency fits your scenario best.  I created this script because I was getting hammered by scrapers and spiders(even though my robots.txt clearly tells them to piss off.  I would log in after waking up to find my server usage at 22 and every site on the server down.  So not the fuckers have 5 hours to do their thing before they are automatically blocked and the server usage can go back to normal.  Obviously this isn’t idea as you would want a quicker response time than that but this is mainly so I can take a day or two off and not worry about the server being kurfucked for days on end.  A few hours I can handle 🙂  Hope it serves you well and if you have any ways to make it better just leave them in the comments below.

Tags: , , , , , , , , , , ,

Leave a Comment