PHPIDS缺省支持的邮件报警存在一些不足之处:

1、对页面的访问速度有一定影响。

2、邮件发送以一条告警日志为单位,如果日志比较多的话,我们可能会收到上百封邮件。(可能有某个选项可以设置,但我没找到)

设计一个perl脚本来发送邮件,原理如下:
首先读取phpids的log文件(tmp/phpids_log.txt),然后利用正则对日志内容进行简单的格式话,最后把格式化的内容发送出去。

 
  
  1. #!/usr/bin/perl -w 
  2. use strict; 
  3. use warnings; 
  4. use MIME::Lite; 
  5. # set up email 
  6. my $mailto = "you\@example.com"
  7. my $mailfrom = "phpids\@example.com"
  8. my $Cc = ""
  9. my $subject = "PHPIDS detected an intrusion attempt!"
  10. my $message = "The following attack has been detected by PHPIDS"
  11. my $content = $message."\n\n"
  12. my $count
  13. get_content(); 
  14. if($content eq $message."\n\n") { 
  15.         print "No data to mail!\nByeBye!\n"
  16. }else
  17.         print "Sending mail now!\n"
  18.         email($mailto$mailfrom$Cc$subject$message$content); 
  19.  
  20. sub email 
  21.         # get incoming parameters 
  22.         my ($mailto$mailfrom$Cc$subject$message$content) = @_; 
  23.  
  24.         #create a new message 
  25.         my $msg = MIME::Lite->new
  26.                 From => $mailfrom
  27.                 To => $mailto
  28.                 Cc => $Cc
  29.                 Subject => $subject
  30.                 Data => "message"
  31.                 Type => 'multipart/mixed' 
  32.         ); 
  33.  
  34.         $msg->attach( 
  35.         Type => 'text/plain'
  36.         Data => $content
  37.         ); 
  38.         # send the mail 
  39.         MIME::Lite->send('smtp''example.com', Debug =>0, Timeout => 60);  
  40.         $msg->send();  
  41.  
  42. # get log content from log file  
  43. sub get_content{ 
  44.         read_count(); 
  45.         format_log(); 
  46.         read_result(); 
  47.         note_count(); 
  48.  
  49. # read count number from the count file. 
  50. sub read_count{ 
  51.         if (-e "count"){ 
  52.     open(FILE, "<count"or die "Can't open count\n"
  53.     while(<FILE>){ 
  54.     chomp; 
  55.     $count = int($_); 
  56.     } 
  57.     close FILE; 
  58. }else
  59.         $count = 1; 
  60.  
  61. # format log content.  
  62. sub format_log{ 
  63.     open(LOG, "<phpids_log.txt"or die "Can't open phpids_log.txt\n"
  64.         open(O,">result.log"or die "can't open result.log\n"
  65.         my $number = 1; 
  66.     while(<LOG>) { 
  67.         if($. >= $count){ 
  68.                         chomp; 
  69.                         if($_ =~ /"(.*?)",(.*?),(\d+)."(.*?)","(.*?)","(.*?)","(.*?)"/){ 
  70.                                         printf O ("NO.%s\nIP: %s\nDate: %s\nImpact: %s\nAffected tags: %s\nAffected parameters: %s\nRequest URI: %s\nOrigin: %s\n\n"$number$1$2$3$4$5$6$7); 
  71.                         }else
  72.                                         if($_ = ~/"(.*?)",(.*?),(\d+)."(.*?)","(.*?)","(.*?)"/) { 
  73.                                                         printf O ("NO.%s\nIP: %s\nDate: %s\nImpact: %s\nAffected tags: %s\nAffected parameters: %s\nRequest URI: %s\n\n"$number$1$2$3$4$5$6); 
  74.                                         }else
  75.                                                 print O "NO.".$number."\n"."$_"
  76.                                         } 
  77.                         } 
  78.                         $number++; 
  79.             $count++; 
  80.         }    
  81.     }    
  82.     close LOG; 
  83.         close O; 
  84. }    
  85.  
  86. # read formatted result from result.log 
  87. sub read_result { 
  88.         open(R,"<result.log"or die "Can't open result.log\n"
  89.         while(<R>){ 
  90.                 $content .= $_
  91.         unlink "result.log"
  92. close R; 
  93.  
  94. # note current count number to count
  95. sub note_count { 
  96.     open(OUT, ">count"or die "Can't open count\n"
  97.     print OUT $count
  98.     close OUT;