#!/usr/bin/perl -w

#------------------------------------------------------------------------------
# This is ipf-blacklist.pl
# It grabs the by you selected blacklists from http://www.wizcrafts.net and 
# parses them into your current ipf.rules file and then reloads ipf.
#
#   Copyright (C) 2009 loxley,
#   All Rights Reserved.
#
#    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 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/>.
#
# Author: Johan Svensson aka loxley <loxley at loxley dot se>
# Patches and problem reports are welcome.
#
# The latest version of this program is available at:
#   http://loxley.se/category/freebsd/
#------------------------------------------------------------------------------

# Usage:  Your ipf.rules file should load your rules with
#         /sbin/ipf -Fa -f - << EOF to work correctly.
#
#         Also you need to insert '# START BLACKLIST' and
#         '# END BLACKLIST' where it should be inserted.
#
#         Then fill out the proper block command below.
#
# Future: I'm planning on extending this to a all-in-one kind of deal. Meaning
#         that all options normally done by editing ipf.rules will be done
#         directly from here with various conf options. This was just a idea
#         I had that I wanted to implement.

use strict;
use File::Copy;
use LWP::Simple;

my $ipf_rules = "/etc/ipf.rules.tmp";
my $ipf_tmp = "/var/tmp/ipf.rules.tmp";

my $blacklists = [ 'chinese', 'russian', 'exploited-servers', 'nigerian' ];

sub blacklist
{
  my $blacklists = shift;
  my @black_ips;
  my $baseurl = "http://www.wizcrafts.net/";
  my $file_ext = "-iptables-blocklist.txt";

  foreach my $blacklist ( @{$blacklists} )
  {
    push(@black_ips, split( "\n", get($baseurl . $blacklist . $file_ext)) );
  }

  # remove duplicates
  my %saw;
  my @black_ips_uniq = grep(!$saw{$_}++, @black_ips);

  return \@black_ips_uniq;

}

my ($ipf_in, $ipf_out);
open ( $ipf_in, "<", $ipf_rules ) or die $!;
open ( $ipf_out, ">", $ipf_tmp ) or die $!;
my $inside;
while (my $line = <$ipf_in>)
{
  chomp ($line);
  if ( $line =~ /^# START BLACKLIST/)
  {
    $inside = 1;
  }

  next if ( $inside && $line !~ /# END BLACKLIST/ );

  if ( $line =~ /^# END BLACKLIST/ )
  {
    $inside = 0;
    print $ipf_out "# START BLACKLIST\n";
    my $blacklisted_ips = &blacklist($blacklists);
    foreach my $ip ( sort (@{$blacklisted_ips}) )
    {
      chomp $ip;
      next if $ip =~ m/^#/ or $ip !~ m/^\d/;
      print $ipf_out "block in quick on \$oif from ${ip} to any group 20\n";
    }
  }
  print $ipf_out "${line}\n";
}
close ($ipf_in);
close ($ipf_out);
move($ipf_tmp,$ipf_rules) or die "Could not move file.";
if (system("/bin/sh $ipf_rules" ))
{
  die "Failed to reload script!\n";
}

