Skip to content
Snippets Groups Projects
blocklist.pl 8.25 KiB
Newer Older
virus2500's avatar
virus2500 committed
#!/usr/bin/perl
Virus2500's avatar
Virus2500 committed
use strict; 
use warnings;
virus2500's avatar
virus2500 committed
################################################################
###### Script to check Blocklist.de list. Block new IP    ###### 
###### and unblock deleted entrys                         ###### 
virus2500's avatar
virus2500 committed
################################################################

## config ##
virus2500's avatar
virus2500 committed
my @listUrl = ("http://lists.blocklist.de/lists/all.txt", "http://www.infiltrated.net/blacklisted");
virus2500's avatar
virus2500 committed
my $tmpDir = "/tmp";
my $logFile = "/var/log/blocklist";
Virus2500's avatar
Virus2500 committed
my $whiteList = "whitelist.txt";
my $blackList = "blacklist.txt";
virus2500's avatar
virus2500 committed

## binarys ##
my $iptables = "/sbin/iptables";
my $ipset = "/usr/sbin/ipset";
my $grep = "/bin/grep";
my $rm = "/bin/rm";
my $wget = "/usr/bin/wget";

## plain variables ##
virus2500's avatar
virus2500 committed
my($row, $Blocklist, $line, $check, $checkLine, $result, $output, $url, $ipRegex, $message);
virus2500's avatar
virus2500 committed

my ($added, $removed, $skipped); 
$added = $removed = $skipped = 0;
virus2500's avatar
virus2500 committed
my $count = 0;
virus2500's avatar
virus2500 committed

## init arrays ##
my @fileArray = ();
my @ipsetArray = ();
Virus2500's avatar
Virus2500 committed
my @whiteListArray = ();
my @blackListArray = ();
virus2500's avatar
virus2500 committed
## init hashes for faster searching
Virus2500's avatar
Virus2500 committed
my %whiteListArray;
my $blackListArray;
virus2500's avatar
virus2500 committed
my %ipsetArray;
my %fileArray;

my $dateTime;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
my @months = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
my @days = qw(Sun Mon Tue Wed Thu Fri Sat Sun);

virus2500's avatar
virus2500 committed
#****************************#
#*********** MAIN ***********#
#****************************#
logging("Starting blocklist refresh");
virus2500's avatar
virus2500 committed
&iptablesCheck();
Virus2500's avatar
Virus2500 committed
&getWhiteListArray();
&getBlackListArray();
virus2500's avatar
virus2500 committed
&getFileArray();
&getIpsetArray();
Virus2500's avatar
Virus2500 committed
print 
virus2500's avatar
virus2500 committed
&addIpsToBlocklist();
&remIpsFromBlocklist();
&cleanup();

exit;
#***** END MAIN *****#


#****************************#
#******* Subroutines ********#
#****************************#



############# iptablesCheck ###############
## checks if all necessary               ##
## iptable/ipset Settings have been set  ##
###########################################

sub iptablesCheck {
    ## Do we have an BLOCKLIST/DROP Chain?
    if (`$iptables -L -n | $grep BLOCKLIST` =~ m/Chain BLOCKLIST/) {
    } else {
        $message = "Creating Chain BLOCKLIST";
        logging($message);
virus2500's avatar
virus2500 committed
        `$iptables -N BLOCKLIST`;
        `$iptables -A BLOCKLIST -m limit --limit 2/min -j LOG --log-prefix "Blocklist Dropped: " --log-level 4`;
        `$iptables -A BLOCKLIST -j DROP`;
    }
    
    ## Do we have an ipset list called blocklist?
    if(`$ipset list -n | $grep blocklist` =~ m/blocklist/) {
    } else {
        `$ipset create blocklist hash:ip hashsize 4096`;
        $message = "Created ipset list blocklist";
        logging($message);
virus2500's avatar
virus2500 committed
    }
    
    ## Is there an forwarded from INPUT to BLOCKLIST?
    if (`$iptables -L INPUT | $grep BLOCKLIST`=~ m/BLOCKLIST/) {
    } else {
        `$iptables -I INPUT -m set --match-set blocklist src -j BLOCKLIST`;
        $message = "Creating forward to BLOCKLIST chain";
        logging($message);
virus2500's avatar
virus2500 committed
    }
}

######## END iptablesCheck ########


########## getFileArray #############
## downloads the Blocklist.txt and ##
## pushes it into an array         ##
#####################################
sub getFileArray {
virus2500's avatar
virus2500 committed
    foreach $url (@listUrl) {
        $count++;
        `$wget -q -O $tmpDir/Blocklist_$count $url && echo "Downloaded temp file to $tmpDir/Blocklist_$count" || echo "Can not download file.... stopping"`;
    
        open(INFO, "$tmpDir/Blocklist_$count") or die("Could not open file.");
        foreach $line (<INFO>) {
            push(@fileArray, $line);
        }
virus2500's avatar
virus2500 committed

virus2500's avatar
virus2500 committed
        close(INFO);
virus2500's avatar
virus2500 committed
    }
    chomp(@fileArray);
    %fileArray = map {$_ => 1 } @fileArray;
}
####### END getFileArray ##########

######### getIpsetArray ##########
## runs ipset list blocklist    ##
## and pushes it into           ##
## array ipsetList              ##
##################################

sub getIpsetArray {
    $output = `$ipset list blocklist`;
    @ipsetArray = split("\n", $output);
    #remove the first 6 Elements of our Array using splice (ipset header info)
    splice @ipsetArray, 0, 6;
    %ipsetArray = map { $_ => 1} split("\n", $output);
}

##### END getIpsetArray #########

Virus2500's avatar
Virus2500 committed
######### getWhiteListArray ######
## puts all ips from our        ##
## $whitelist into              ##
## array whiteListArray         ##
##################################

sub getWhiteListArray {
    open(INFO, $whiteList) or die("Could not open Whitelist.");
    foreach $line (<INFO>) {
        push(@whiteListArray, $line);
    }

    close(INFO);
    chomp(@whiteListArray);
}
##### END getWhiteListArray #####

######### getBlackListArray ######
## puts all ips from our        ##
## $whitelist into              ##
## array blackListArray         ##
##################################

sub getBlackListArray {
    open(INFO, $blackList) or die("Could not open Blacklist.");
    foreach $line (<INFO>) {
        push(@blackListArray, $line);
    }

    close(INFO);
    chomp(@blackListArray);
}
##### END getBlackListArray #####

virus2500's avatar
virus2500 committed
######## addIpsToBlocklist ######
## adds IPs to our blocklist   ##
#################################

sub addIpsToBlocklist {
virus2500's avatar
virus2500 committed
    foreach $line (uniq(@blackListArray)) {
Virus2500's avatar
Virus2500 committed
        if ((exists $ipsetArray{"$line"}) ||  ($line ~~ @whiteListArray)) {
	    $skipped++;
        } else {
	    if ($line eq &isIpv4($line)) {
                $result = `$ipset add blocklist $line`;
                $added++;
                $message = "added $line";
                logging($message);
            } else {
                $skipped++;
            }
	}
    }
virus2500's avatar
virus2500 committed
    foreach $line (uniq(@fileArray)) { 
Virus2500's avatar
Virus2500 committed
        if ((exists $ipsetArray{"$line"}) || ($line ~~ @whiteListArray)) {
virus2500's avatar
virus2500 committed
            $skipped++;
        } else {
            if ($line eq &isIpv4($line)) { 
                $result = `$ipset add blocklist $line`;
                $added++;
                $message = "added $line";
                logging($message);
virus2500's avatar
virus2500 committed
            } else {
                $skipped++;
            }
        }
    }
}
######## END addIpsToBlocklist ######

########## remIpsFromBlocklist ########
## remove IPs from our blocklist   ##
#####################################
sub remIpsFromBlocklist {
Virus2500's avatar
Virus2500 committed
    # remove Ips that are in our whiteList
    foreach $line (@whiteListArray) {
        if ((exists $ipsetArray{"$line"}) && ($line ~~ @whiteListArray)) {
            if ($line eq &isIpv4($line)) {
                $result = `$ipset del blocklist $line`;
                $message = "removed $line";
                logging($message);
                $removed++;
            } else {
                $skipped++;
            }
        }
    }

virus2500's avatar
virus2500 committed
    foreach $line (@ipsetArray) {
Virus2500's avatar
Virus2500 committed
        if ((exists $fileArray{"$line"}) || ($line ~~ @blackListArray)) {
virus2500's avatar
virus2500 committed
            $skipped++;   
        } else {
            if ($line eq &isIpv4($line)) {
                $result = `$ipset del blocklist $line`;
                $message = "removed $line";
                logging($message);
virus2500's avatar
virus2500 committed
                $removed++;
            } else {
                $skipped++;
            }
        }
    }
}

######## END remIpsFromBlocklist ########


################## cleanup ###################
#### Cleanup: move tmp file to new place #####
##############################################
virus2500's avatar
virus2500 committed
sub cleanup {
virus2500's avatar
virus2500 committed
    for (1..$count) {
        $result = `$rm $tmpDir/Blocklist_$_ && echo "Deleted file $tmpDir/Blocklist_$_" || echo "Can\t delete file $tmpDir/Blocklist_$_"`;
    }
    $message = "We added $added, removed $removed, skipped $skipped Rules";
    logging($message);
virus2500's avatar
virus2500 committed
}
############### END cleanup ######################

############ isIpv4 #############
## check if given value looks  ##
## like an ipv4 ip address     ##
#################################
sub isIpv4 {
    my ($isIp) = @_;
    if ($isIp =~ m/^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/) {
        #print "It's an IPv4\n";
        return $isIp;
    } else {
        return 0;
    }
}
######### END isIpv4 ##########

###### log #######
## log $message ##
##################
sub logging {
    my ($message) = @_;

    ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();

    open my $fh, ">>", $logFile
        or die "Can't open logfile: $!";
    $dateTime = sprintf("$months[$mon]  %02d %02d:%02d:%02d ", $mday,$hour,$min,$sec);
    print $fh "$dateTime $message\n";
    print "$message\n";

    close($fh);
}
#### end log #####
virus2500's avatar
virus2500 committed

sub uniq { my %seen; grep !$seen{$_}++, @_ } # from http://stackoverflow.com/questions/13257095/remove-duplicate-values-for-a-key-in-hash

virus2500's avatar
virus2500 committed
######### EOF ###########