It has been quite often that I need to do retroactive things on my machines. One such activity is banning all those users who use bad logins to attempt to get into my server through .htaccess. Now, I only block those who have tried bad logins, not bad passwords. I realize typos can be made, but there's really no excuse for a bad username typo, as you can see the username as you type it. Likewise, if I do get complaints that a user has been blocked because they typed their username in wrong, I white-list their IP so that it is no longer of concern. So here we go:
#!/bin/bash
clear
echo -n "Writing file /var/log/badusers.log for IPs with HTTP login attempts..."
grep "user" /var/www/logs/error_log |
grep "not found:" |
awk '{ print $8 }' |
cut -d "]" -f 1 |
sort |
uniq > /var/log/badusers.log
echo "...done."
echo ""
echo -n "Checking badusers.log vs white.list..."
for ip in `cat /web/default/white.list`; do
grep -v $ip /var/log/badusers.log > /var/log/badusers.tmp
done
mv /var/log/badusers.tmp /var/log/badusers.log
echo "...ok"
echo -n "Adding .htaccess rules to deny these bad IPs..."
echo ""
for ip in `cat /var/log/badusers.log`; do
echo "deny from $ip" >> /web/default/.htaccess
done
grep -v "deny from" /web/default/.htaccess > /web/default/.htaccess.tmp
grep "deny from" /web/default/.htaccess |
sort |
uniq > /web/default/.deny_from
cat /web/default/.deny_from >> /web/default/.htaccess.tmp
mv /web/default/.htaccess.tmp /web/default/.htaccess
for site in `ls /web/*/.htaccess`; do
echo ""
echo "Updating $site"
grep -v "deny from" $site > /web/default/.htaccess.tmp
cat /web/default/.deny_from >> /web/default/.htaccess.tmp
mv /web/default/.htaccess.tmp $site
done
rm -f /web/default/.deny_from
echo "...done."
echo ""
echo -n "Press enter to continue..."
read enter
Now, this script may need to be tweaked if you style error_log differently than I do; that said, if yours is the same, then what we just did was:
- We pulled out every line in our error_log that contains the phrase "not found" (e.g., username not found)
- From that, we took only the 8th column, where the users' IP is recorded
- We sorted these IP addresses
- We wrote all of these IPs to a file called badusers.log in directory /var/log/
- We check the file /web/default/white.list for each IP address to remove any friends/good-users (the white.list is simply in format of one IP per line, standard text-file)
- Once compared, for each IP in the badusers.log we add them to a global .htaccess file in /web/default/
- For every domain (all my domains are chrooted into /web/) we go in, take their .htaccess file, and copy everything out of it that is NOT a "deny from" line. Then, we add our "deny from" lines from the global /web/default/.htaccess file.

