Perl脚本黑名单检查高CPU使用率

时间:2014-05-31 01:17:06

标签: linux perl ubuntu dns centos

我在perl中编写了一个脚本,它从数据库中获取一组IP,并在20个主要黑名单服务器上查询它们。它非常简单,脚本似乎在Ubuntu 12.04安装上正常运行但是当我尝试将其迁移到具有相同版本的perl和安装库的CentOS 6.5时,我注意到该脚本将使用大量CPU。

它很奇怪,因为在其他ubuntu安装工作正常(0.0%使用)和dns服务器是相同的。我没有在这个版本上实现线程,因为它运行得很好(在ubuntu上)。 我尝试在本地dns上使用缓存,尝试升级perl,更新perl的模块,在检查期间添加睡眠暂停,但情况是相同的。

在代码

下面
#!/usr/bin/perl
use POSIX qw/ strftime /;

#use Encode qw/encode decode/;
#use Syslog;  # for later use to check everything's ding fine

use strict;
use warnings;

use Digest::MD5 qw(md5);
use Net::DNS;
use DBD::mysql;
use LWP::Simple;
use strict;
use warnings;
use Proc::Daemon;

#Proc::Daemon::Init;

print "Setting globals\n";
my $continue = 1;
my $debug   = 1;
my $timeout = 3;
my $id_start = 0;
#my $id_start = $ARGV[0];
#my $id_end = $ARGV[1];
my $id_end       = 320000;
my $enable_cache = 1;
my $count      = 0;
my $cache_path = "/cachedir/cache/";

#konfigu i db jarebi
my $host = "localhost";
my $db   = "db here";
my $user = "user and stuff";
my $pw   = "passwordz ";

$SIG{TERM} = sub { $continue = 0 };

while ($continue) {
    my $dbh = DBI->connect( "DBI:mysql:$db", $user, $pw ) || die "Snuk: $DBI::errstr";
    if ($debug) {
        print "Connecting to the databasse\n";
    }

    my @total_query;

    my $top_10 = "SELECT `ip` FROM main_data WHERE `id` >= ? and `id` <= ? ORDER BY `last_check` ASC limit 10";
    if ($debug) {
        print "Constructing query with $id_start and $id_end as parameters\n";
    }

    # zgjedhim 10 te parat qe nuk jane lock(te parat i thencin)
    my $sth = $dbh->prepare($top_10);

    if ( !$sth ) {
        die "Probleme me tabelen\n";
    } else {
        $sth->execute( $id_start, $id_end );
    }

    if ($debug) {
        print "Query Executed\n";
    }

    my @ips = ();

    while ( my @results = $sth->fetchrow() ) {
        if ($debug) {
            print "Inserting IP $results[0] on arrays\n";
        }
        push @ips, "$results[0]";
    }
    $dbh->disconnect;

    my @a     = ();
    my $count = 0;
    if ($debug) {
        print "Got " . scalar(@ips) . " from query\n";
    }

    foreach my $gje (@ips) {
        if ($debug) {
            print "Checking IP:$gje for spamming trace\n";
        }
        $a[0]  = $gje;
        $a[1]  = check( $gje, "b.barracudacentral.org" );
        $a[2]  = check( $gje, "zen.spamhaus.org" );
        $a[3]  = check( $gje, "sbl-xbl.spamhaus.org" );
        $a[4]  = check( $gje, "cidr.bl.mcafee.com" );
        $a[5]  = check( $gje, "bl.score.senderscore.com" );
        $a[6]  = check( $gje, "z.mailspike.net" );
        $a[7]  = check( $gje, "dnsbl.proxybl.org" );
        $a[8]  = check( $gje, "cbl.abuseat.org" );
        $a[9]  = check( $gje, "dnsbl.inps.de" );
        $a[10] = check( $gje, "dyna.spamrats.com" );
        $a[11] = check( $gje, "dnsbl-1.uceprotect.net" );
        $a[12] = check( $gje, "all.spamrats.com" );
        $a[13] = check( $gje, "spam.dnsbl.sorbs.net" );
        $a[14] = check( $gje, "dnsbl.sorbs.net" );
        $a[15] = check( $gje, "noptr.spamrats.com" );
        #   $a[16] = "-1";
        $a[16] = check( $gje, "db.wpbl.info" );
        $a[17] = check( $gje, "dnsbl.ahbl.org" );
        #   $a[17] = "-1";
        $a[18] = check( $gje, "ips.backscatterer.org" );
        $a[19] = check( $gje, "bl.spamcop.net" );
        $a[20] = check( $gje, "ip.v4bl.org" );
        print "@a" . "\n";

        if ( $enable_cache eq "1" ) {
            update_cache(@a);
        }

        push( @total_query, [@a] );
    }

    update_db(@total_query);

    print "Exiting \n";

}

sub update_db {
    my @total_query = @_;
    my $dbh = DBI->connect( "DBI:mysql:$db", $user, $pw ) || die "Snuk: $DBI::errstr";
    my $top_10 = "UPDATE main_data SET `1`=?,`2`=?,`3`=?,`4`=?,`5`=?,`6`=?,`7`=?,`8`=?,`9`=?,`10`=?,`11`=?,`12`=?,`13`=?,`14`=?,`15`=?,`16`=?,`17`=?,`18`=?,`19`=?,`20`=?,`last_check`= NOW(),status=? where ip = ? LIMIT 1";
    my $sth = $dbh->prepare($top_10);
    foreach my $data (@total_query) {
        my $status = 0;

        foreach ( my $i = 1 ; $i <= 20 ; $i++ ) {
            if ( $$data[$i] > 0 ) {
                $status++;
            }
        }
        print "$$data[1],$$data[2],$$data[3],$$data[4],$$data[5],$$data[6],$$data[7],$$data[8],$$data[9],$$data[10],$$data[11],$$data[12],$$data[13],$$data[14],$$data[15],$$data[16],$$data[17],$$data[18],$$data[19],$$data[20],$status,$$data[0]\n";

        $sth->execute(
            $$data[1],  $$data[2],  $$data[3],  $$data[4],  $$data[5],  $$data[6],  $$data[7],  $$data[8],
            $$data[9],  $$data[10], $$data[11], $$data[12], $$data[13], $$data[14], $$data[15], $$data[16],
            $$data[17], $$data[18], $$data[19], $$data[20], $status,    $$data[0]
        );
    }
    $dbh->disconnect;
}

sub check {
    my $res = Net::DNS::Resolver->new;
    $res->tcp_timeout($timeout);
    $res->udp_timeout($timeout);
    my $nr    = 0;
    my $ip    = shift;
    my @copat = split( /\./, $ip );
    $ip = "$copat[3].$copat[2].$copat[1].$copat[0]";

    my $rbl_server = shift;
    if ($debug) {
        print "Checking IP:$ip for spamm records on server $rbl_server\n";
    }
    my $query = $res->search("$ip.$rbl_server");

    if ($query) {
        foreach my $rr ( $query->answer ) {
            if ( $rr->type eq "A" ) {
                $nr++;

                #print ".$rr->address." \n";
                my $returnC = $rr->address;
                my $rtc = substr( $returnC, 8 );
                return $rtc;
            } else {
                return "1";
            }
        }
    } else {
        if ( $res->errorstring eq "NXDOMAIN" ) {
            return "0";
        } else {
            return "-1";
        }
    }
}

sub get_date {
    my ($self) = @_;
    my @timeD = localtime();    # 3 4 5
    $timeD[4]++;
    $timeD[5] += 1900;
    $timeD[4] = ( ( $timeD[4] < 10 ) ? "0" . $timeD[4] : $timeD[4] );    # nena ternarit jam :D
    $timeD[3] = ( ( $timeD[3] < 10 ) ? "0" . $timeD[3] : $timeD[3] );
    $timeD[2] = ( ( $timeD[2] < 10 ) ? "0" . $timeD[2] : $timeD[2] );
    $timeD[1] = ( ( $timeD[1] < 10 ) ? "0" . $timeD[1] : $timeD[1] );
    return "$timeD[5]-$timeD[4]-$timeD[3] $timeD[2]:$timeD[1]:$timeD[0]";
}

sub update_cache {
    my (@data) = @_;

    #my $last_ch = get_date();
    $count++;
    my $status = 0;
    foreach ( my $i = 1 ; $i <= 14 ; $i++ ) {
        if ( $data[$i] > 0 ) {
            $status++;
        }
    }

    if ( -d "$cache_path" ) {
        # ok folder exits
    } elsif ( -e "$cache_path" ) {
        # bohh
    } else {
        # lets create teh folder
        system("touch $cache_path");
    }

    open( REALTIME_FILE, "< $cache_path" ) or die "Could not open file";
    my @rrjeshtat = <REALTIME_FILE>;
    close(REALTIME_FILE);

    if ( $count > 5 ) {
        pop(@rrjeshtat);
    }
    my $line;

    open( REALTIME_FILE, "> $cache_path" ) or die "Could not open file";
    if ( $status > 0 ) {
        # blacklisted
        $status = ( $status > 1 ) ? "$status SERVERA" : "$status SERVER";
        $line =
            '<li class="list-group-item"><span class="text-muted">'
          . get_date()
          . '</span> <strong>'
          . $data[0]
          . '</strong> <span class="label label-danger pull-right">LISTUAR NE '
          . $status
          . ' </span></li>' . " \n";
         #print '<li class="list-group-item"><span class="text-muted">'.get_date().'</span> <strong>'.$data[0].'</strong> <span class="label label-danger pull-right">LISTUAR NE '.$status.'</span></li>'." \n";
    } else {
        # clean
        $line =
            '<li class="list-group-item"><span class="text-muted">'
          . get_date()
          . '</span> <strong>'
          . $data[0]
          . '</strong> <span class="label label-success pull-right">E PASTER</span></li>' . " \n";
          #print '<li class="list-group-item"><span class="text-muted">'.get_date().'</span> <strong>'.$data[0].'</strong> <span class="label label-success pull-right">'." \n";
    }
    unshift( @rrjeshtat, $line );

    #print $line;
    print REALTIME_FILE join( "", @rrjeshtat );
    close(REALTIME_FILE);
    $count++;
}

0 个答案:

没有答案