2個小時拿下Perl語言:自動監控服務器內網站訪問ip次數並預警(附源碼)

[作者]
網名: 豬頭三
QQ: 643439947
編程生涯: 2001~至今[2014年]
職業生涯: 11年
開發語言: C/C++; x86asm; Object Pascal; Object-C; C#;
開發工具: VC++; Delphi;
研發領域: Windows應用軟件安全; Windows系統內核安全; Windows系統磁盤數據安全;
技能種類: 逆向 驅動 磁盤 文件
[序言]
一直都不是Linux服務器專業人員. 但恰恰自己又擁有2臺國外服務器, 上面有好多關於我國外軟件的產品網站. 這2臺服務器每天都遭受各種第3世界國家攻擊以及主流國家惡意爬蟲和wp_login.php攻擊. 每次維護一次訪問日記都需要1個多小時, 很麻煩. 再一個Linux命令苦澀難懂, 勉強會用幾個, 但還是不頂用. 就在前幾天心煩了, 乾脆自己寫腳本解析日記算了. 就這個念頭一閃, 就誕生了這個perl腳本出來.
[學習]
perl語言認真看2個小時, 然後再mac os x系統裝上eclips+perl插件就開工了(備註: 不會用vi, 因爲人笨), 斷斷續續用了2天時間終於完成了第一個版本, 大約700多行. 在開發過程中, 其實很簡單: 就是把C語言的邏輯思維轉換成perl代碼. 爲什麼要這樣做, 因爲腳本語言通病就是語法糖過多, 會讓你迷失在語法糖裏面而無法寫出正常的程序, 不是每個開發人員有擁有那種開發語言的天賦(備註:我個人認爲只有這樣的天賦才能接受各種奇怪的語法糖). 也就是一直堅持這個原則才讓這個perl腳本誕生.
[差異]
perl和python都很好上手, 只要你有C語言基礎, 玩這個很簡單. 比JS簡單多了. 那我爲什麼用perl呢?其實是我的服務器默認沒有安裝python, 倒反默認安裝了ruby, 比較神奇. 本來想用ruby的, 因爲我第一個腳本語言就是ruby, 但是後來想想linux服務器一般大頭都是perl語言, 因此選擇了perl而不是ruby.
[源碼]
#!usr/bin/perl
#access-log
#     ipemail
#     
# http://www.x86asm.com
#: v0.0.1 
#: 2014-07-15
#Linux,
#     .
#使linuxcrontab -e
#
BEGIN {
  push @INC,"/Users/PigHeadThree/perl5/lib/perl5" ;
}
#use 5.010;
use strict ;
use autodie;
use Try::Tiny;
use Tie::File;
use Fcntl 'O_RDONLY' ;
use File::Spec::Functions qw(rel2abs) ;
use File::Basename qw(dirname basename) ;
use File::Spec;
use File::Copy qw(copy);
use MIME::Lite ;
use MIME::Base64;
use Authen::SASL:email
#===================================
#===================================
#()()
my $g_str_App_Flag = 'pht_monitor' ;
#access-logsgooglebing()
#google bingipip
my $g_str_grep_Bot = 'googlebot|bingbot' ;
#ip()
my $g_int_Limit_VisitIp = 900 ;
#()
my $g_str_ServerName = "PHT Server" ;
#email()
my $g_str_email_From = '[email protected]' ;
my $g_str_email_Pass = 'xxxxxxx'         ;
my $g_str_eamil_Smtp = 'smtp.163.com'    ;
my $g_str_eamil_To   = '[email protected]'  ;
#===================================
try
{
    &fun_RunningLog("main() start...") ;
    &main() ;
    &fun_RunningLog("main() end.") ;
}
catch
{
    &fun_RunningLog("===========main() running error===========") ;     
};
sub main()
{
    # www.x86asm.com
    #
    #: x86asm
    #x86asm.com,
    #/home/x86asm/access-logs/x86asm.com
    #ip
    my $str_Site_URL         = "www.x86asm.com" ;
    my $str_Site_Name        = "x86asm_" ;
    my $str_Site_LogFilePath = "/home/x86asm/access-logs/x86asm.com" ;
    fun_CountTargetSite($str_Site_URL,
                        $str_Site_Name,
                        $str_Site_LogFilePath) ;
                              
}#End main()
               
#=======================================
#ip
#param_1 : 
#param_2 : 
#param_3 : access_log 
sub fun_CountTargetSite()
{
    
    #0
    if (@_ != 3)
    {
        return 0 ;
    }
    
    (my $str_param_Site_URL,
     my $str_param_Site_Name,
     my $str_param_Site_LogFilePath= @_ ;
    
    my %hash_VisitIp_Count ;
    
    &fun_RunningLog("[$str_param_Site_URL] : start...");
    
    &fun_GetVisitIp($str_param_Site_LogFilePath,
                    $g_int_Limit_VisitIp,
                    &fun_GetLocaltime("/"),
                    \%hash_VisitIp_Count) ;
    if (&fun_IsNeedUpdate($str_param_Site_Name.&fun_GetLocaltime("_").".txt",
                         \%hash_VisitIp_Counteq 1)
    {
        
        #
        &fun_VisitIpSaveToCurrentPathFile($str_param_Site_Name.&fun_GetLocaltime("_").".txt",
                                        \%hash_VisitIp_Count);
        #EMAIL
        my $str_SendEmail_Data = &fun_GetSendEmailToData($str_param_Site_Name.&fun_GetLocaltime("_").".txt") ;
        if ($str_SendEmail_Data ne 0)
        {
            &fun_AutoSendEmailToAlarm($g_str_ServerName."[$str_param_Site_URL]"."Alarm Ip Visit",
                                      $str_SendEmail_Data) ;
        }
        
    }
    else
    {
        
    }    
    &fun_RunningLog("[$str_param_Site_URL] : end.");
    
}# End fun_CountTargetSite() 
#
#param_1 : 
sub fun_GetLocaltime()
{
    
    #0
    if (@_ != 1)
    {
        return 0 ;
    }
    
    #
    my %hash_montoname = (
        "01" => "Jan",
        "02" => "Feb",
        "03" => "Mar",
        "04" => "Apr",
        "05" => "May",
        "06" => "Jun",
        "07" => "Jul",
        "08" => "Aug",
        "09" => "Sep",
        "10" => "Oct",
        "11" => "Nov",
        "12" => "Dec") ;
        
    #
    my ($sec,$min,$hour,$mday,$mon,$year_off,$wday,$yday,$isdat= localtime;
        ($mday, $mon, $year_off= (
        sprintf("%02d", $mday),
        sprintf("%02d", $mon+1),
        $year_off+1900);
    #
    $mon = $hash_montoname{$mon} ;
    return $mday.$_[0].$mon.$_[0].$year_off;
            
}# End fun_GetLocaltime()
#
sub fun_GetLocaltimeToLog()
{
    #
    if (@_)
    {
        return 0 ;
    }
    
    #
    my @array_montoname = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec) ;
        
    #
    my ($sec,$min,$hour,$mday,$mon,$year_off,$wday,$yday,$isdat= localtime;
        ($sec, $min, $hour, $mday, $year_off= (
        sprintf("%02d", $sec),
        sprintf("%02d", $min),
        sprintf("%02d", $hour),
        sprintf("%02d", $mday),
        $year_off+1900);
    #
    $mon = $array_montoname[$mon] ;
    return $mday.'/'.$mon.'/'.$year_off.'  '.$hour.':'.$min.':'.$sec ;  
    
}# End fun_GetLocaltimeToLog()
#
#param_1 : 
sub fun_RunningLog()
{
    #0
    if (@_ != 1)
    {
        return 0 ;
    }
    
    (my $str_param_Print= @_ ;
    
    #
    my $str_LogTime = '['.&fun_GetLocaltimeToLog().']' ;
    
    #
    my $str_Log_FileName = 'run_'.&fun_GetLocaltime('_').'.txt' ;
    $str_Log_FileName    = File::Spec->join(&fun_GetCurrentAppPath(),
                                            $str_Log_FileName) ;
                                            
    unless(-e $str_Log_FileName)
    {
        unless(open(HANDLE_OPEN, ">$str_Log_FileName"))
        {
            return 0 ;
        }
    }
    else
    {
        unless(open(HANDLE_OPEN, ">>$str_Log_FileName"))
        {
            return 0 ;
        }
    }
    
    #
    print HANDLE_OPEN $str_LogTime.' : '.$str_param_Print."\n" ;
    
    close(HANDLE_OPEN) ;
    
    return 1 ;
        
}#End fun_RunningLog()
#
sub fun_GetCurrentAppPath()
{
    #
    if (@_)
    {
        return 0 ;
    }
    
    return dirname(rel2abs(__FILE__)) ;
    
}# End fun_GetCurrentAppPath()
#
#param_1 : 
sub fun_CopyFileToCurrentAppPath()
{
    my $str_CopyFileToPath = "" ;
    my $str_CopyFileName   = "" ;
    my $str_CurrentAppPath = "" ;
    
    #0
    if (@_ != 1)
    {
        return 0 ;
    }
    else
    {
        my $str_param_CopyFilePath = $_[0] ;
        # -e   -d 
        if (-e $str_param_CopyFilePath)
        {
            #()
            $str_CurrentAppPath = &fun_GetCurrentAppPath() ;
            $str_CopyFileName   = basename($str_param_CopyFilePath) ;
            $str_CopyFileToPath = File::Spec->join($str_CurrentAppPath, $str_CopyFileName) ;
            if (-e $str_CopyFileToPath)
            {
                #
                if ($str_CopyFileToPath =~ /$g_str_App_Flag/i)
                {
                    &fun_RunningLog("fun_CopyFileToCurrentAppPath() deleteing $str_CopyFileToPath...") ;
                    unlink($str_CopyFileToPath);
                    &fun_RunningLog("fun_CopyFileToCurrentAppPath() deleted $str_CopyFileToPath.") ;    
                }
            }
            copy($str_param_CopyFilePath, $str_CopyFileToPath) ;
            
            return $str_CopyFileToPath ;
            
        }
    }
    
    return 0 ;
    
}# End fun_CopyFileToCurrentAppPath()
#ip
sub fun_GetIpByStr()
{
    #0
    if (@_ != 1)
    {
        return 0 ;
    }
    
    (my $str_param_Target= @_ ;
    
    if ($str_param_Target =~ /(\d+\.\d+\.\d+\.\d+)/)
    {
        return "$1" ; #IP
    }
    
    return 0 ;
    
}# End fun_GetIpByStr()
#ip
#param_1 : 
#param_2 : IP
#param_3 :  (02/jul/2014)
#param_4 :  
sub fun_GetVisitIp()
{
    #0
    if (@_ != 4)
    {
        return 0 ;
    }
    #
    (my $str_param_VisitIp_LogFilePath,
     my $int_param_VisitIp_Count,
     my $time_param_Get,
     my $hash_param_VisitIp= @_ ;
     
    #
    if ($time_param_Get eq "NO")
    {
        $time_param_Get = &fun_GetLocaltime("/") ;
    }
     
    #
    if (-e $str_param_VisitIp_LogFilePath)
    {
        my $str_VisitIp_CopyToPath = &fun_CopyFileToCurrentAppPath($str_param_VisitIp_LogFilePath) ;
        if ($str_VisitIp_CopyToPath eq 0)
        {
            #
            return 0 ;
        }
    
        #
        my @array_VisitIp_Load ;
        my $int_VisitIp_FileLineNums ;
        if (-e $str_VisitIp_CopyToPath)
        {
            tie @array_VisitIp_Load,
                'Tie::File',
                $str_VisitIp_CopyToPath,
                mode => O_RDONLY ;
                
            # 
            $int_VisitIp_FileLineNums = @array_VisitIp_Load - 1 ;
            
            #
            my $str_Temp_Line          = "" ;
            my $str_Temp_VisitIp       = "" ;
            my $str_Temp_VisitIp_Count = 0  ;
            my %hash_Temp_VisitIp      = () ;
            while ($int_VisitIp_FileLineNums >= 0)
            {
                $str_Temp_Line = $array_VisitIp_Load[$int_VisitIp_FileLineNums] ;
                if ($str_Temp_Line =~ /$time_param_Get/i)
                {
                    if ($str_Temp_Line =~ /$g_str_grep_Bot/i)
                    {
                        
                    }
                    else
                    {
            
                        #ip
                        $str_Temp_VisitIp = &fun_GetIpByStr($str_Temp_Line) ;
                        if ($str_Temp_VisitIp eq 0)
                        {
                        }
                        else
                        {
                            #ip()
                            if (exists $hash_Temp_VisitIp{$str_Temp_VisitIp})
                            {
                                $hash_Temp_VisitIp{$str_Temp_VisitIp+= 1 ;
                                
                                #,
                                if ($hash_Temp_VisitIp{$str_Temp_VisitIp>= $int_param_VisitIp_Count)
                                {
                                    
                                    if (exists $$hash_param_VisitIp{$str_Temp_VisitIp})
                                    {
                                        $$hash_param_VisitIp{$str_Temp_VisitIp+= 1 ;  
                                    }
                                    else
                                    {
                                        $$hash_param_VisitIp{$str_Temp_VisitIp= $int_param_VisitIp_Count ;                    
                                    }
                                    
                                }
                            }
                            else
                            {
                                $hash_Temp_VisitIp{$str_Temp_VisitIp= 1 ;
                            }
                            
                        }
                        
                    }
                }
                else
                {
                    last ;
                }
                
                $int_VisitIp_FileLineNums -= 1 ; 
            }
            
            #
            untie @array_VisitIp_Load ; 
            
            return 1 ;   
        }
    }
    else
    {
        &fun_RunningLog("fun_GetVisitIp() $str_param_VisitIp_LogFilePath no found.") ;
    }
    
    return 0 ;
    
}# End fun_GetVisitIp()
#
#param_1 : 
#param_2 : 
sub fun_VisitIpSaveToCurrentPathFile()
{
    #0
    if (@_ != 2)
    {
        return 0 ;
    }
    
    (my $str_param_SaveToFileName,
    my  $hash_param_Conent= @_ ;
    
    #
    if ((length($str_param_SaveToFileName== 0or
       ((keys %$hash_param_Conent== 0))
    {
        return 0 ;
    }
    
    #
    my $str_SaveToFilePath = File::Spec->join(&fun_GetCurrentAppPath(),
                             $str_param_SaveToFileName) ;
    if (-e $str_SaveToFilePath)
    {
        #
        if ($str_SaveToFilePath =~ /$g_str_App_Flag/i)
        {
            &fun_RunningLog("fun_VisitIpSaveToCurrentPathFile() deleteing $str_SaveToFilePath...") ;
            unlink($str_SaveToFilePath);
            &fun_RunningLog("fun_VisitIpSaveToCurrentPathFile() deleted $str_SaveToFilePath.") ;
        }
    }
    
    if (open(HANDLE_FILE, ">$str_SaveToFilePath"))
    {
        my $hash_Keys ;
        my $hash_Values ;
        
        foreach $hash_Keys (sort keys %$hash_param_Conent)
        {
            $hash_Values = $$hash_param_Conent{$hash_Keys} ;
            print HANDLE_FILE "$hash_Keys => $hash_Values \n" ;
        }
        
        close(HANDLE_FILE) ;
    }
    else
    {
        return 0 ;
    }
    
}# End fun_VisitIpSaveToCurrentPathFile()
#(.txt)
#param_1 : 
#param_2 : 
sub fun_IsNeedUpdate()
{
    #0
    if (@_ != 2)
    {
        return 0 ;
    }
    
    (my $str_param_FileName,
    my  $hash_param_Conent= @_ ;
    #
    if ((length($str_param_FileName== 0or
       (keys %$hash_param_Conent == 0))
    {
        return 0 ;
    }
    
    my $bool_IsNeedUpdate = 0 ; #
    my $str_Ip = "" ;
    my %hash_Load_Ip ;
    my $str_OpenFilePath = File::Spec->join(&fun_GetCurrentAppPath(),
                                            $str_param_FileName) ;
    #ip
    if (-e $str_OpenFilePath)
    {
        if (open (HANDLE_OPEN, $str_OpenFilePath))
        {
            while(my $str_Temp_Line = <HANDLE_OPEN>)
            {
                $str_Ip = &fun_GetIpByStr($str_Temp_Line) ;
                if ($str_Ip eq 0)
                {
                }
                else
                {
                    ip
                    $hash_Load_Ip{$str_Ip= 1 ;    
                }
            }
            
            close(HANDLE_OPEN);
            
            #
            my $str_Temp_Value ;
            while(($str_Ip, $str_Temp_Value= each %$hash_param_Conent)
            {
                #ip1
                if (exists $hash_Load_Ip{$str_Ip})
                {
                    
                }
                else
                {
                    $bool_IsNeedUpdate = 1 ;
                    last ;
                }   
            }
        }   
    }
    else
    {
        #
        $bool_IsNeedUpdate = 1 ;
    }
    return $bool_IsNeedUpdate ;
    
}# End fun_IsNeedUpdate()
#email
#param_1 : 
#param_2 : 
sub fun_AutoSendEmailToAlarm()
{
    #0
    if (@_ != 2)
    {
        return 0 ;
    }
    
    (my $str_param_Subject,
     my $str_param_Data= @_ ;
    
    if ((length($str_param_Subject== 0or
        (length($str_param_Data==  0)) 
     {
        return 0
     } 
     
     my $msg_Send = MIME::Lite->new(From    => $g_str_email_From,
                                    To      => $g_str_eamil_To,
                                    Subject => $str_param_Subject,
                                    Data    => $str_param_Data) ;
    #$msg_Send->attr("content-type" => "text/html") ;
    $msg_Send->send("smtp", $g_str_eamil_Smtp,
                    AuthUser=>$g_str_email_From,
                    AuthPass=>$g_str_email_Pass,
                    Timeout => 30) ; # Debug => 1 
                    
     return 1 ;
    
}# End fun_AutoSendEmailToAlarm()
#email
#param_1 :  ()
sub fun_GetSendEmailToData()
{
    #0
    if (@_ != 1)
    {
        return 0 ;
    }
    
    (my $str_param_FileName= @_ ;
    
    if (length($str_param_FileName== 0)
    {
        return 0 ;
    }
    
    #
    my $str_OpenFilePath = File::Spec->join(&fun_GetCurrentAppPath(),
                                            $str_param_FileName) ;
    if (-e $str_OpenFilePath)
    {
        my $str_Content = "" ;
        if (open (HANDLE_OPEN, $str_OpenFilePath))
        {
            while(my $str_Temp_Line = <HANDLE_OPEN>)
            {
                chomp($str_Temp_Line) ;
                $str_Content .= $str_Temp_Line .= "\n"  ;
            }
            
            close(HANDLE_OPEN);
            
            if (length($str_Content!= 0)
            {
                return $str_Content ;   
            }
        }   
    }
    
    return 0 ;
    
}# End fun_GetSendEmailToData()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章