Bash script to block brute force attacks with .htaccess

in #programming7 years ago

Your site is under attack. May be not right now, but several times a day. Password guessing, security vulnerabilities - that kind of stuff. In the error log it looks like this:


[Thu Jul 13 05:28:49 2017] [error] [client 196.64.59.18] ModSecurity: Access denied with code 401 (phase 2). Operator GT matched 0 at USER:bf_block. [file "/etc/apache2/mod_security/custom/wpbrute.conf"] [line "20"] [id "9999001"] [msg "ip address blocked for 5 minutes, more than 15 login attempts in 3 minutes."] [hostname "giraffesdoexist.com"] [uri "/wp-login.php"] [unique_id "WWdngc26uBEAAGIsOAEAAABG"]

The server, Apache in my case, handles these attacks routinely, but morons come back over and over again. Apart from performance implications there's a small chance of successful attack, so I made a simple script to block hackers via .htaccess.

This script runs by a cron job and has three parameters:

blockbruteforcers.sh ../logs/error_log ../domains/.htaccess 200

It searches error_log for ip-addresses that appear there more than 200 times and adds those to .htaccess with "deny from" prefix. Here's the script source code, don't forget to add "Execute" attribute when you create it on your server:


#!/bin/bash
if [ $# -ne 3 ]; then
echo "Incorrect number of arguments. Should be 3: apache error log path, .htaccess file path, number of entries."
exit
fi

filename=$2
num_entries=$3
error_log=$1

#If .htaccess file does not exist, create it and add 2 first lines
if [ ! -f "$filename" ]; then
echo order allow,deny >> "$filename"
echo allow from all >> "$filename"
fi

#Check if .htaccess file has new line at the end. If not - add it.
c=tail -c 1 "$filename"
if [ "$c" != "" ]; then
echo >> "$filename"
fi

msg=""
arr=($(grep -o 'client [0-9.]*' "$error_log"| sort -r | uniq -c | sort -nr | awk -v pNum=$num_entries '$1>pNum {print $3}'))
for i in "${arr[@]}"
do
if ! grep -q -P "$i$" "$filename"; then
if [ ! -z "$msg" ]; then
msg+="\n"
fi
msg+="deny from ${i}"
fi
done

if [ ! -z "$msg" ]; then
echo -e "$msg" >> "$filename"
echo "$msg"
else
echo "no matching records found"
fi

Sort:  

Congratulations @shuler! You have completed some achievement on Steemit and have been rewarded with new badge(s) :

Award for the number of upvotes

Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here

If you no longer want to receive notifications, reply to this comment with the word STOP

By upvoting this notification, you can help all Steemit users. Learn how here!

Thanks for first upvote :>

Thanks for the info. I recommend block brute force attacks with ConfigServer Security & Firewall (csf). https://configserver.com/cp/csf.html

I'm on shared hosting, it would not work for me.

Coin Marketplace

STEEM 0.18
TRX 0.16
JST 0.029
BTC 76214.38
ETH 3070.66
USDT 1.00
SBD 2.61