PHPIDS缺省支持的邮件报警存在一些不足之处:
1、对页面的访问速度有一定影响。
2、邮件发送以一条告警日志为单位,如果日志比较多的话,我们可能会收到上百封邮件。(可能有某个选项可以设置,但我没找到)
设计一个perl脚本来发送邮件,原理如下:
首先读取phpids的log文件(tmp/phpids_log.txt),然后利用正则对日志内容进行简单的格式话,最后把格式化的内容发送出去。
- #!/usr/bin/perl -w
- use strict;
- use warnings;
- use MIME::Lite;
- # set up email
- my $mailto = "you\@example.com";
- my $mailfrom = "phpids\@example.com";
- my $Cc = "";
- my $subject = "PHPIDS detected an intrusion attempt!";
- my $message = "The following attack has been detected by PHPIDS";
- my $content = $message."\n\n";
- my $count;
- get_content();
- if($content eq $message."\n\n") {
- print "No data to mail!\nByeBye!\n";
- }else{
- print "Sending mail now!\n";
- email($mailto, $mailfrom, $Cc, $subject, $message, $content);
- }
-
- sub email
- {
- # get incoming parameters
- my ($mailto, $mailfrom, $Cc, $subject, $message, $content) = @_;
-
- #create a new message
- my $msg = MIME::Lite->new(
- From => $mailfrom,
- To => $mailto,
- Cc => $Cc,
- Subject => $subject,
- Data => "message",
- Type => 'multipart/mixed'
- );
-
- $msg->attach(
- Type => 'text/plain',
- Data => $content,
- );
- # send the mail
- MIME::Lite->send('smtp', 'example.com', Debug =>0, Timeout => 60);
- $msg->send();
- }
-
- # get log content from log file
- sub get_content{
- read_count();
- format_log();
- read_result();
- note_count();
- }
-
- # read count number from the count file.
- sub read_count{
- if (-e "count"){
- open(FILE, "<count") or die "Can't open count\n";
- while(<FILE>){
- chomp;
- $count = int($_);
- }
- close FILE;
- }else{
- $count = 1;
- }
- }
-
- # format log content.
- sub format_log{
- open(LOG, "<phpids_log.txt") or die "Can't open phpids_log.txt\n";
- open(O,">result.log") or die "can't open result.log\n";
- my $number = 1;
- while(<LOG>) {
- if($. >= $count){
- chomp;
- if($_ =~ /"(.*?)",(.*?),(\d+)."(.*?)","(.*?)","(.*?)","(.*?)"/){
- 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);
- }else{
- if($_ = ~/"(.*?)",(.*?),(\d+)."(.*?)","(.*?)","(.*?)"/) {
- 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);
- }else{
- print O "NO.".$number."\n"."$_";
- }
- }
- $number++;
- $count++;
- }
- }
- close LOG;
- close O;
- }
-
- # read formatted result from result.log
- sub read_result {
- open(R,"<result.log") or die "Can't open result.log\n";
- while(<R>){
- $content .= $_;
- }
- unlink "result.log";
- close R;
- }
-
- # note current count number to count.
- sub note_count {
- open(OUT, ">count") or die "Can't open count\n";
- print OUT $count;
- close OUT;
- }