Web Hosting Talk







View Full Version : Perl problem


jon-f
09-04-2009, 04:32 PM
I am no programmer so bear with me. Jpeterson on the forum made this new very useful script called BARF whcih works perfectly. The problem is there is an error that it constantly spits out while running, here is script while running:

deny failed: 217.164.251.225 is in already in the deny file /etc/csf/csf.deny
Use of uninitialized value in subtraction (-) at /usr/bin/barf line 119.
blocking 217.164.251.225
deny failed: 217.164.251.225 is in already in the deny file /etc/csf/csf.deny
Use of uninitialized value in subtraction (-) at /usr/bin/barf line 119.
blocking 217.164.251.225
deny failed: 217.164.251.225 is in already in the deny file /etc/csf/csf.deny
Use of uninitialized value in subtraction (-) at /usr/bin/barf line 119.
blocking 217.164.251.225
deny failed: 217.164.251.225 is in already in the deny file /etc/csf/csf.deny
Use of uninitialized value in subtraction (-) at /usr/bin/barf line 119.
blocking 217.164.251.225
deny failed: 217.164.251.225 is in already in the deny file /etc/csf/csf.deny
Use of uninitialized value in subtraction (-) at /usr/bin/barf line 119.
blocking 217.164.251.225
deny failed: 217.164.251.225 is in already in the deny file /etc/csf/csf.deny
Use of uninitialized value in subtraction (-) at /usr/bin/barf line 119.
blocking 217.164.251.225
deny failed: 217.164.251.225 is in already in the deny file /etc/csf/csf.deny
Use of uninitialized value in subtraction (-) at /usr/bin/barf line 119.
blocking 217.164.251.225
deny failed: 217.164.251.225 is in already in the deny file /etc/csf/csf.deny
Use of uninitialized value in subtraction (-) at /usr/bin/barf line 119.
blocking 217.164.251.225
deny failed: 217.164.251.225 is in already in the deny file /etc/csf/csf.deny
Use of uninitialized value in subtraction (-) at /usr/bin/barf line 119.
blocking 83.20.114.128
Adding 83.20.114.128 to csf.deny and iptables DROP...
DROP all opt -- in eth0 out * 83.20.114.128 -> 0.0.0.0/0
DROP all opt -- in * out eth0 0.0.0.0/0 -> 83.20.114.128
Use of uninitialized value in subtraction (-) at /usr/bin/barf line 119.
blocking 83.20.114.128
deny failed: 83.20.114.128 is in already in the deny file /etc/csf/csf.deny
Use of uninitialized value in subtraction (-) at /usr/bin/barf line 119.
Use of uninitialized value in subtraction (-) at /usr/bin/barf line 119.
blocking 83.20.114.128So the script is working just have this error -
Use of uninitialized value in subtraction (-) at /usr/bin/barf line 119.I would like to know how to fix this if necessary. Also Im pretty sure all functions such as the timing and such are working but would be great if someone with perl knowledge could review this and check it out. Also it seems it is not doing the stop tracking feature correctly as you can see from the ip already in deny errors.

#!/usr/bin/perl

##############################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Copyright 2009 jpetersen
#
##############################################################################

##############################################################################
# _ __
# | | / _| BLOCK
# | |__ __ _ _ __| |_ APACHE
# | '_ \ / _` | '__| _| REQUEST
# | |_) | (_| | | | | FLOODS
# |_.__/ \__,_|_| |_| LoL:D
#
##############################################################################

##############################################################################
#
# Block an IP address if it issues x number of y requests
# to apache within z seconds. This script takes 4 options:
#
# example.com this is the domain to monitor
# -n <num> if this many requests
# -t <num> are made within this many seconds
# -s <req> for this string
# then the IP address issuing the requests will be blocked.
#
# Examples:
#
# Look for 3 requests within 10 seconds that match GET /index.php
# ./script example.com -n 3 -t 10 -s "GET /index.php"
#
# Look for 10 requests within 30 seconds that match GET / HTTP/1.1
# ./script example.com -n 10 -t 30 -s "GET / HTTP/1.1"
#
# This is the expected Apache log format, which is the default on cPanel servers:
# 1.2.3.4 - - [28/Jun/2009:16:43:05 -0400] "GET / HTTP/1.1" 404 - "-" "-"
#
##############################################################################

use strict;
use warnings;
use File::Tail;
use Getopt::Long;

if ( @ARGV ne 7 )
{
die "\nUsage:\n\t$0 example.com -n 3 -t 10 -s \"GET / HTTP/1.1\"\n\n";
}

my $site = shift; # domain name
my $domlog = '/usr/local/apache/domlogs/' . $site;
my %visitors = (); # 1.2.3.4 => 1246231315
my %hits = (); # 1.2.3.4 => 3
my $log_line;

-e $domlog or die "Unable to locate $domlog\n";

my ( $max_number_of_requests, $time_to_track, $request_string );

GetOptions (
"n=i" => \$max_number_of_requests,
"t=i" => \$time_to_track,
"s=s" => \$request_string,
);

my $file = File::Tail->new(
name => $domlog,
interval => 1,
maxinterval => 1,
resetafter => 1,
reset_tail => 0,
);

################################################################
#
# tail the domlog
#
################################################################
while ( defined ( $log_line = $file->read ) )
{
if ( $log_line =~ m{\A((\d{1,3}\.){3}\d{1,3})(\s-){2}(\s\S+){2}\s"$request_string} )
{
my $ipaddr = $1;

clean_hashes( $ipaddr );
check_visitors( $ipaddr );
check_for_block( $ipaddr );
}
}

################################################################
#
# Remove any IP addresses that have been seen longer than
# $time_to_track seconds ago.
#
################################################################
sub clean_hashes
{
my $ipaddr = shift;

if ( %visitors )
{
if ( ( time - $visitors{$ipaddr} ) > $time_to_track )
{
delete $visitors{$ipaddr};
delete $hits{$ipaddr};
}
}
}

################################################################
#
# Check to see if we're tracking the IP address already.
# If we aren't, update the %visitors hash.
#
################################################################
sub check_visitors
{
my $ipaddr = shift;

my $already_tracked = 0;

for my $key ( keys %visitors )
{
if ( $key eq $ipaddr )
{
$already_tracked = 1;
}
}

if ( $already_tracked == 0 )
{
$visitors{$ipaddr} = time;
}
}

################################################################
#
# Update the %hits hash. Check to see if the user specified
# number of hits has exceeded the user specified time period.
# If the threshold has been exceeded, then block the host and
# stop tracking it.
#
################################################################
sub check_for_block
{
my $ipaddr = shift;

$hits{$ipaddr}++;

if ( $hits{$ipaddr} >= $max_number_of_requests )
{
if ( ( time - $visitors{$ipaddr} ) <= $time_to_track )
{
print "blocking $ipaddr\n";
system '/usr/local/bin/csf', '-d', $ipaddr;

delete $visitors{$ipaddr};
delete $hits{$ipaddr};
}
}
}

DigitalLinx
09-04-2009, 04:39 PM
Try this

#!/usr/bin/perl

##############################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Copyright 2009 jpetersen
#
##############################################################################

##############################################################################
# _ __
# | | / _| BLOCK
# | |__ __ _ _ __| |_ APACHE
# | '_ \ / _` | '__| _| REQUEST
# | |_) | (_| | | | | FLOODS
# |_.__/ \__,_|_| |_| LoL:D
#
##############################################################################

##############################################################################
#
# Block an IP address if it issues x number of y requests
# to apache within z seconds. This script takes 4 options:
#
# example.com this is the domain to monitor
# -n <num> if this many requests
# -t <num> are made within this many seconds
# -s <req> for this string
# then the IP address issuing the requests will be blocked.
#
# Examples:
#
# Look for 3 requests within 10 seconds that match GET /index.php
# ./script example.com -n 3 -t 10 -s "GET /index.php"
#
# Look for 10 requests within 30 seconds that match GET / HTTP/1.1
# ./script example.com -n 10 -t 30 -s "GET / HTTP/1.1"
#
# This is the expected Apache log format, which is the default on cPanel servers:
# 1.2.3.4 - - [28/Jun/2009:16:43:05 -0400] "GET / HTTP/1.1" 404 - "-" "-"
#
##############################################################################

use strict;
use warnings;
use File::Tail;
use Getopt::Long;

if ( @ARGV ne 7 )
{
die "\nUsage:\n\t$0 example.com -n 3 -t 10 -s \"GET / HTTP/1.1\"\n\n";
}

my $site = shift; # domain name
my $domlog = '/usr/local/apache/domlogs/' . $site;
my %visitors = (); # 1.2.3.4 => 1246231315
my %hits = (); # 1.2.3.4 => 3
my $log_line;

-e $domlog or die "Unable to locate $domlog\n";

my ( $max_number_of_requests, $time_to_track, $request_string );

GetOptions (
"n=i" => \$max_number_of_requests,
"t=i" => \$time_to_track,
"s=s" => \$request_string,
);

my $file = File::Tail->new(
name => $domlog,
interval => 1,
maxinterval => 1,
resetafter => 1,
reset_tail => 0,
);

################################################################
#
# tail the domlog
#
################################################################
while ( defined ( $log_line = $file->read ) )
{
if ( $log_line =~ m{\A((\d{1,3}\.){3}\d{1,3})(\s-){2}(\s\S+){2}\s"$request_string} )
{
my $ipaddr = $1;

clean_hashes( $ipaddr );
check_visitors( $ipaddr );
check_for_block( $ipaddr );
}
}

################################################################
#
# Remove any IP addresses that have been seen longer than
# $time_to_track seconds ago.
#
################################################################
sub clean_hashes
{
my $ipaddr = shift;

if ( %visitors )
{
if($visitors{$ipaddr}) {
if ( ( time - $visitors{$ipaddr} ) > $time_to_track )
{
delete $visitors{$ipaddr};
delete $hits{$ipaddr};
}
}
}
}

################################################################
#
# Check to see if we're tracking the IP address already.
# If we aren't, update the %visitors hash.
#
################################################################
sub check_visitors
{
my $ipaddr = shift;

my $already_tracked = 0;

for my $key ( keys %visitors )
{
if ( $key eq $ipaddr )
{
$already_tracked = 1;
}
}

if ( $already_tracked == 0 )
{
$visitors{$ipaddr} = time;
}
}

################################################################
#
# Update the %hits hash. Check to see if the user specified
# number of hits has exceeded the user specified time period.
# If the threshold has been exceeded, then block the host and
# stop tracking it.
#
################################################################
sub check_for_block
{
my $ipaddr = shift;

$hits{$ipaddr}++;

if ( $hits{$ipaddr} >= $max_number_of_requests )
{
if ( ( time - $visitors{$ipaddr} ) <= $time_to_track )
{
print "blocking $ipaddr\n";
system '/usr/local/bin/csf', '-d', $ipaddr;

delete $visitors{$ipaddr};
delete $hits{$ipaddr};
}
}
}

Added extra checking if $visitors{$ipaddr} holds anything, should get rid of that warning.

jon-f
09-04-2009, 05:05 PM
Yes, this seems to have fixed problem with unitialized value problem but still seems its not stopping tracking once an ip is blocked which isnt too big of a problem cause it will only try to block it maybe once or twice after that while rules are being added to firewall, I guess it takes a few seconds.

Thanks!

jpetersen
09-12-2009, 09:46 AM
Did the updated version I posted 2 months ago in the same thread not work out?