Jump to content

Script to check log file and add to .htaccess


garry

Recommended Posts

I need to make a script that is set up for cron and will work every hour. This is new to me so I need some help on where to go next..

 

Here's what I've got to start..

 

<?php

$logfile = file_get_contents("iplogfile2-".gmdate('Y-m-d').".html");

?>

 

In the log file, IP addresses are kept for each person that visits the site in the format "I.P - Time". So, "127.9.3.12 - 8:15". What I need to do with this is to check if an IP address occurs 30 times in one day, and if it does, I need it added to a .htaccess file to deny the permission. I also need to check the .htaccess file to make sure it is not already in there because this cron is run every 60 minutes. I realize I need to use preg_match but I'm not sure how to use it or how to find out if an IP is in there x amount of times.

 

Any help is greatly appreciated :)

I figured bash would be a better tool for this job so set out to create this script. Took me about 15 minutes but I got there.

 

#!/bin/bash

date=$(date '+%Y-%m-%d)
log="/full/path/to/your/log/iplogfile2-$date.html"  # full path to log file.
htaccess="/full/path/to/your/.htaccess"             # full path to your .htaccess file.

for ip in $(grep $(date '+%Y-%m-%d') $log | awk '{print $1}' | sort -u) ;  do  
    count=$(grep ${ip} $log | wc -l)
    if [ $count -gt 29 ] ; then
        grep -s ${ip} $htaccess || sed -i -e "1,/^deny/ {/^deny/i\
            deny from ${ip}
        }" $htaccess
    fi  
done

And a slight improvement....

 

#!/bin/bash

date=$(date '+%Y-%m-%d')
log="/full/path/to/your/log/iplogfile2-$date.html"  # full path to log file.
htaccess="/full/path/to/your/.htaccess"             # full path to your .htaccess file.

for ip in $(grep $date $log | awk '{print $1}' | sort -u) ; do
    if (( $(grep ${ip} $log | wc -l) > 29 )) ; then
grep ${ip} $htaccess >& /dev/null || sed -i -e "1,/^deny/ {
    /^deny/i\deny from ${ip}
}" $htaccess
    fi
done

Okay thank-you very much! Also, if you have time, I was just wondering how the stuff you did in bash works. Like, how it can distinguish from the IP's and the dates and how the statement you've written for >29 works. If you don't have time for a quick explanation that is fine, but I just like to try and learn new things so I can do it myself next time :) Also, can I put this file anywhere in the server or does it have to be in a special folder to execute it? (i think i've read about usr/bin or something)

No, It doesn't need to go in any special location as your telling cron exactly where it is. Normally, you would want scripts in your execution path, this would simply meen you could call logcheck.sh from the command line to run it. this kind of script really doesn't need to be within your path.

 

For an explination I'll add some comments (this could be quite verbose, hope it helps). The first line simply tells your shell what program should be used to execute the script.

 

#!/bin/bash

# assign the current data to the $date vairable for later use.
date=$(date '+%Y-%m-%d')
# store the path to your log file within a variable.
log="/full/path/to/your/log/iplogfile2-$date.html"  # full path to log file.
# store the path to your .htaccess file.
htaccess="/full/path/to/your/.htaccess"             # full path to your .htaccess file.

# Theres a bit to explain here. This part, $(grep $date $log | awk '{print $1}' | sort -u)
# basically pulls all lines from your log file that contain the current date: grep $date $log
# it then filters those lines to display only the ips addresses: awk '{print $1}'
# it then filters those ip addresses so as to only display each ip address once: sort -u
#
# we then use this list of ip addresses within a loop.
for ip in $(grep $date $log | awk '{print $1}' | sort -u) ; do
    # we use the current $ip iteration to check the log file once again to see how many times
    # that ip address appears within your log file.
    # if it appears more the 29 times, we need to write it to the .htaccess file. (thats next)
    if (( $(grep ${ip} $log | wc -l) > 29 )) ; then
        # here we use grep to see if the ip address is already within the .htaccess file
        # if the grep fails, it will go to the following sed command.
        # its basically like: if (grep = true) else sed
        #
        # the sed command itself is a little tricky. This part 1,/^deny/
        # says that we only want the following command (that within the {}) to operate on the first line starting with the word deny
grep ${ip} $htaccess >& /dev/null || sed -i -e "1,/^deny/ {
            # this part /^deny/i\deny from ${ip} within the {} tells sed we want to insert 'deny from ipaddress' on the line
            # prior to the line starting with the word deny.
    /^deny/i\deny from ${ip}
        # here we simply tell sed which file its operating on.
}" $htaccess
    fi
done

 

Hope that helps.

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.