2008-08-26 10:41:09 到處看看

啟用 Greylist

今天在 Mimedefang 裡的 filter_recipient 啟用了 Greylist,

因為有兩台 Spam Filter 主機, 所以 DB 就統一寫到 Mysql,

程式自己寫的, 短短的, 效果不錯, 約可擋掉 8 成 Spam.

sub filter_recipient ($$$$$$$$$)
    {
     use DBI;
     # 參數及變數設定
     my($recip, $sender, $rest_of_the_junk) = @_;
     
     # ByPass DMZ IP 不須要 RELAY 檢查
     if ( ($RelayAddr =~ "xxx.xxx.xxx"))
         { return ("CONTINUE", ""); }

     # 設定資料庫連線參數
     my $database = "xxxx";
     my $host = "xxx.xxx.xxx.xxx";
     my $user = "xxxxx";
     my $password = "xxxxxxxxxx";

     # 尋找 MySQL 裡 EmailUser Address 是否存在
     my $dbh = DBI->connect("DBI:mysql:$database;host=$host", $user, $password);
     my $sth = $dbh->prepare( "SELECT * FROM emailuser WHERE emailadd LIKE \'$recip\' ");
     $sth->execute;
  
     # 若 User 不存在, 則 Reject, 並記錄至資料庫
     if ( $sth->rows == 0 )
         {
          $sth = $dbh->prepare( "INSERT INTO rejectdata( recaddr, sender, hostip, datetime, messageid) VALUES (\"$recip\", \"$sender\", \"$RelayAddr\", now(), \"$MsgID\" )");
          $sth->execute;
          $dbh->disconnect();
          return("REJECT", "User unKnown.");
         }
     
     # 寄件者是否在白名單內, 則直接 Continue
     $sth = $dbh->prepare( "select sender from white_list where sender like \"$sender\" " );
     $sth->execute;
  
     if( $sth->rows > 0 )
           {
            action_add_header("White-List", "White List Check OK ");
         $dbh->disconnect();
                   
         # $Sender 在白名單裡, 做紀錄通過白名單並跳出, 回主程式繼續傳送信件
         $Features{'White_list'} = 1;
         return ("CONTINUE", "");
        }
       
     # 查詢灰名單, 是否在紀錄內, 若是, 又超過 300 秒, 則繼續傳送信件
     my $timestamp = time;
     
     # 啟動記錄的 DMZ 的主機的 IP
     my $ip = 'xxx.xxx.xxx.xxx';
     
     my $tripple = "$RelayAddr/$Sender/".$Recipients[0];
     $sth = $dbh->prepare( "select tripple, timestamp from grey_list where tripple like \"$tripple\" " );
     $sth->execute;
   
     if( $sth->rows > 0 )
           {
            my ( $trippledb, $timestampdb) = $sth->fetchrow;
            
            # 時間小於 300 秒, 回覆啟動灰名單
            if ( ( $timestamp - $timestampdb ) < 300 )
                {
                 $dbh->disconnect();
                 return ('TEMPFAIL', 'Greylisting active, please try again later');
                }
            # 通過灰名單, 砍掉紀錄, 然後 Continue
            else
                {
                 my $sth1 = $dbh->prepare( "delete from grey_list where tripple like '$tripple' " );
                 $sth1->execute;
                 $dbh->disconnect();
                 return ("CONTINUE", "");
                }
           }
     
     # 沒有灰名單紀錄, 塞入灰名單資料庫內
     $sth = $dbh->prepare( "INSERT INTO grey_list( tripple, timestamp, datetime, hostip ) VALUES (\"$tripple\", \"$timestamp\", now(), \"$ip\" )" );
     $sth->execute;
     $dbh->disconnect();
     
     # 回覆啟動灰名單
     return ('TEMPFAIL', 'Greylisting active, please try again later');
     }