Register
It is currently Sun Dec 21, 2014 12:17 pm

Convert perl script to bash - block IP's from webserver with


All times are UTC - 6 hours


Post new topic Reply to topic  [ 1 post ] 
Author Message
 PostPosted: Tue May 17, 2005 8:20 pm   
Site Admin

Joined: Tue May 17, 2005 7:31 pm
Posts: 251
Location: Georgia
:: originally posted by crouse ::
Quote:
Convert this to bash..........

Just looking at an easy way to add firewall rules etc using bash........

Code:
#!/usr/bin/perl
# This is for extracting the Micro$oft boxes that have been compromised
# and blocking their access to the webserver for several weeks

######################################
#  Copyright Notice
#
#  This program, web-block.pl is
#  Copyright 2001
#  Local Net Solutions, LLC
#  4003 Allenwood Way
#  Tucker GA  30084
#
#  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 2 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, write to the Free Software
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#  The full text of the license can be found online at http://www.gnu.org/licenses/gpl.txt
######################################

######################################
#  Instructions for use
#
#  This program should be copied into a convenient location
#  such as /usr/local/sbin and the owner is root and the mode is 500.
#  As this sript will access an iptables firewall, it must have root priveledges.
#  Create a file /etc/hosts.web.deny. e.g. touch /etc/hosts.web.deny as root.
#  It can also be set to run on a cron job. e.g.
#  */20 * * * * /usr/local/sbin/web-block.pl
#  this will run every 20 minutes. It will only check the the most recent error_log
#
#  If it is run as <path>/web-block.pl all , it will check all the error_logs,
#  even the older, saved ones, up to error_log.4. This is for allowing aged IP's
#  to no longer be blocked.
#  It is a good idea to add this to the webserver log rotation process. On a RedHat 7.1
#  machine, edit /etc/logrotate.d/apache to look like:
#  /var/log/httpd/error_log {
#    missingok
#    postrotate
#        /bin/kill -HUP `cat /var/run/httpd.pid 2>/dev/null` 2> /dev/null || true
#        /root/web-block.pl all
#    endscript
#  }
#  Now it is pretty automatic.
#
#  To Do:
#  add a web-block.pl off argument flag
#  add an external file for exploit strings to search for.
#  be nicer on the firewall and only block the port 80 from the machines.
#  add an automailer to send complaints to the network mangers the offenders are on (yeah, right!).
#
######################################

use strict;

# the file with the data is
my $log = "/var/log/httpd/error_log";

# old log files add a .i i=1..4

# the place to store the output IP's to block
my $dropfile = "/etc/hosts.web.deny";

# strings to search for in the log file
my @strings = ("winnt", "cmd.exe", "root.exe");

# create a hash of the already blocked IP's

my ($key, %dropped, %filed, %block_these, %blocked, $in, @IN, $logfile, $j);

# Accept args to search all log files
my $log_depth = "0";
my $all = $ARGV[0];
#print "arg = $all\n";
if ($all =~ m/all/){$log_depth = "4"}

%filed = get_filed_hosts();

%block_these = get_hosts_to_block();

%dropped = iptables_firewall_check();

if ($log_depth == 4){
   foreach $key (keys %filed){ # removes old IP's from blacklist
      if ($block_these{$key} !~ "drop"){delete $filed{$key}}
   }
   write_drop_file();
}
else{ # Should handle a restart OK
   foreach $key (keys %filed){ # add all filed IP for blocking.
      if ($block_these{$key} !~ "drop"){$block_these{$key} = "drop"}
   }
   write_drop_file();
}

foreach $key (keys %dropped){
        delete $block_these{$key} #no duplicate filter rules
}

# Do the deed
foreach $key (keys %block_these){
   if ($key =~ m/\d+\.\d+\.\d+\.\d+/){
      `/sbin/iptables -I INPUT -s $key -j DROP`;
   }
}

#################################
##   Subroutines
#################################

sub get_filed_hosts{
   # create a hash of the already blocked IP's
   open (IN, "<$dropfile") || die "Failed to open $dropfile for read\n";
   @IN = <IN>;
   close IN;
   chomp(@IN);
   foreach $in (@IN) {
           $filed{$in}="filed";
   }
}

sub write_drop_file{
        my $key;
        open (OUT, ">$dropfile") || die "failed to open $dropfile for write\n";
        foreach $key ( keys %blocked ){
                if ($key =~ m/\d+\.\d+\.\d+\.\d+/){
                        print OUT "$key\n";
                }
        }
        close OUT;
}

sub get_hosts_to_block { # generate list of IP's to block from httpd log files
   # open logfile and stuff into an array for string searching
   my (@temp, $match, $i, %block_these);
   for ($j=0; $j<=$log_depth; $j++){
           if ($j == 0){$logfile=$log}
           else {$logfile = $log.".$j"}
      if ( -r $logfile){
         open (IN, "<$logfile") || die "failed to open $logfile for read\n";
         @IN=<IN>;
         chomp(@IN);
         close IN;
      }
      for ($i=0;$i<=$#strings;$i++){
         $match .= $strings[$i];
         if ($i != $#strings) {$match .= "|"}
      }   
      foreach $in (@IN){
         if ($in =~ m/$match/){
            @temp = split( /\s/, $in);
            # $temp[8] has ip address pluss and extra "]" on the end.
            chop($temp['8']);
            $block_these{$temp['8']} = "drop";
         }
      }
   }
   return %block_these;
} #end sub host_block     

sub iptables_firewall_check { #get list of IP's currently blocked
   my (@rules, %temp, @dropped, $IP);
   @rules = `/sbin/iptables -L INPUT -n | grep DROP | grep -v INPUT`;
   chomp(@rules);
   my (@temp);
   foreach my $rule (@rules){
      #print "$rule\n";
      @temp = split (/\s+/, $rule);
      #print "IP=$temp[3]\n";
      if ($temp[3] =~ m/\d+\.\d+\.\d+\.\d+/){
         push (@dropped, $temp[3]);
      }
   }
   foreach $IP (@dropped){
      #print "dropped IP -> $IP\n";
      $temp{$IP} = "FW";
   }
   return %temp;
}


Top
 Profile  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot] and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  


BashScripts | Promote Your Page Too
Powered by phpBB © 2011 phpBB Group
© 2003 - 2011 USA LINUX USERS GROUP