#!/usr/bin/perl -T -W

my $logfile = "/var/log/fail2ban.log";
my @logfile_data;
my $hosts_allow_file = "/etc/hosts.allow";
my @hosts_allow_data;
my $identifyer = "# auto-script begin/end #\n";
my @ignore_IPs = ("192.168.0.1", "192.168.1."); # never ban these
my %banlist;

&remove_previously_banned(); # loads the data from $hosts_allow_file and processes it a bit
&get_ban_list(); # gets the ban list from $logfile and removes duplicates
&add_bannable_ips(); # determine which IPs should be banned and insert into $hosts_allow_data
#&write_to_screen(); # prints the new $hosts_allow_file to screen for debugging only
&write_back_to_file(); # creates the new $hosts_allow_file


sub get_ban_list() {
  open(FILE,'<',$logfile) || die("cannot open file for reading >>$logfile<<: $!");
  @logfile_data = <FILE>;
  close(FILE);
  foreach my $line ( @logfile_data ) {
    if ( $line =~ m/^.*\ (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).*$/ ) {
      $banlist{$1} = 1; # add data to a hash: key = IP --> removes duplicates
    }
  }
}


sub add_bannable_ips() {
  push @hosts_allow_data,$identifyer;
  foreach my $key ( sort (keys ( %banlist )) ) {
    if ( &ban_this_IP($key) ) {
      push @hosts_allow_data,"ALL: ",$key," : DENY","\n";
    }
  }
  push @hosts_allow_data,$identifyer;
}


sub write_to_screen() { 
  for (0..$#hosts_allow_data) {
    print $hosts_allow_data[$_];
  }
}


sub write_back_to_file() {
  open(FILE,'>',$hosts_allow_file) || die("cannot open file for writing >>$hosts_allow_file<<: $!");
    foreach my $line ( @hosts_allow_data ) {
      print FILE $line;
    }
  close(FILE);
}


sub ban_this_IP() {
  my $IP = shift;
  foreach my $tmp_IP ( @ignore_IPs ) {
    if ( $IP =~ m/$tmp_IP/ ) {
      # IP found, ignore it, don't ban
      return 0;
    }
  }   
  return 1; # IP not found, ban it
}


sub remove_previously_banned() {
  open(FILE,'<',$hosts_allow_file) || die("cannot open file for reading >>$hosts_allow_file<<: $!");
    @hosts_allow_data = <FILE>;
  close(FILE);
  my $delete_line = 0;

  for (0..$#hosts_allow_data) {
    if ( $hosts_allow_data[$_] =~ m/$identifyer/ ) {
      $delete_line ^= 1;
      $hosts_allow_data[$_] = "";
    }
    if ( $delete_line == 1 ) {
      $hosts_allow_data[$_] = "";
    }
  }
}


