จุดประสงค์:
เพิ่มความสามารถให้กับ SpamAssassin ในการตรวจสอบต้นทางของอีเมล โดยอ้างอิงจากหมายเลข IP Address และใช้ Module Geo::IP ของ perl ในการแปลงหมายเลข IP Address ให้เป็นชื่อประเทศ
*** ต้องติดตั้ง Module Geo::IP ก่อน
package Mail::SpamAssassin::Plugin::OriginatingCountry;
use Mail::SpamAssassin::Plugin;
use Mail::SpamAssassin::Constants qw(:ip);
use strict;
use warnings;
use bytes;
use vars qw(@ISA);
@ISA = qw(Mail::SpamAssassin::Plugin);
sub new {
my $class = shift;
my $mailsaobject = shift;
# some boilerplate...
$class = ref($class) || $class;
my $self = $class->SUPER::new($mailsaobject);
bless ($self, $class);
$self->register_eval_rule ("check_any_ip_header");
return $self;
}
sub check_any_ip_header {
my ($self, $permsgstatus, $rulename) = @_;
return 0;
}
sub parsed_metadata {
my ($self, $opts) = @_;
my $scanner = $opts->{permsgstatus};
my $gi;
eval {
require Geo::IP;
$gi = Geo::IP->new();
};
if ($@) {
dbg ("failed to load 'Geo::IP', skipping");
return 1;
}
my %iplist = ();
my $IP_ADDRESS = IP_ADDRESS;
my $ip;
# check_x_ip_header
for my $header ('X-X-Originating-IP', 'X-ORIGINATOR-IP', 'X-Apparently-From', 'X-Originating-IP', 'X-OriginatingIP', 'X-AOL-IP', 'X-SenderIP', 'X-Sender-IP', 'X-MDRemoteIP', 'X-Origin', 'X-MAIL-SOURCE-IP', 'X-IPADDR') {
$ip = $scanner->get($header);
next unless $ip;
$ip =~ m/($IP_ADDRESS)/g;
dbg("Found x-ip: $ip");
$iplist{$ip} = 1;
}
# check_yahoo_ip_header
if ($scanner->get("Received") =~ /\s?from\s+(\S+)\s+by\s+web[a-z0-9\.]+\.yahoo\.[a-z0-9\.]+\s+via\s+HTTP\;/) {
$ip = $1;
if ($ip =~ /$IP_ADDRESS/) {
dbg("Found yahoo-ip: $ip");
$iplist{$ip} = 1;
}
}
if ($scanner->get("Received") =~ /\s?from\s+unknown\s+\(HELO\s+[\w.-]+\)\s+\([\w.-]+\@(\S+)\s+with\s+login\)/) {
$ip = $1;
if ($ip =~ /$IP_ADDRESS/) {
dbg("Found yahoo-ip2: $ip");
$iplist{$ip} = 1;
}
}
if ($scanner->get("Received") =~ /\s?from\s+\[192\.168\.1\.1\]\s+\([\w._-]+\@(\S+)\s+with\s+plain\)/) {
$ip = $1;
if ($ip =~ /$IP_ADDRESS/) {
dbg("Found yahoo-ip3: $ip");
$iplist{$ip} = 1;
}
}
if ($scanner->get("X-Received") =~ /\s?from\s+\[192\.168\.1\.1\]\s+\([\w._-]+\@(\S+)\s+with\s+plain\)/) {
$ip = $1;
if ($ip =~ /$IP_ADDRESS/) {
dbg("Found yahoo-ip4: $ip");
$iplist{$ip} = 1;
}
}
# check_authen_ip_header
if ($scanner->get("Received") =~ /\s?from\s+\w+\s+(\S+)/) {
$ip = $1;
if ($ip =~ /$IP_ADDRESS/) {
dbg("Found authen-ip: $ip");
$iplist{$ip} = 1;
}
}
if ($scanner->get("Received") =~ /\s?from\s[\w.-]+\s+\(unknown\s+(\S+)\)/) {
$ip = $1;
if ($ip =~ /$IP_ADDRESS/) {
dbg("Found authen-ip2: $ip");
$iplist{$ip} = 1;
}
}
if ($scanner->get("Received") =~ /\s?from\s[\w.-]+\s+\(unknown\s+(\S+)\)[\s
\r]+\(/) {
$ip = $1;
if ($ip =~ /$IP_ADDRESS/) {
dbg("Found authen-ip3: $ip");
$iplist{$ip} = 1;
}
}
# check_squirrelmail_ip_header
if ($scanner->get("Received") =~ /\s?from\s+(\S+)[\s
\r]+\(SquirrelMail authenticated/) {
$ip = $1;
if ($ip =~ /$IP_ADDRESS/) {
dbg("Found SquirrelMail-ip: $ip");
$iplist{$ip} = 1;
}
}
if ($scanner->get("Received") =~ /\s?from\s[\w.-]+\s+\(proxying for\s+(\S+)\)[\s
\r]+\(SquirrelMail authenticated/) {
$ip = $1;
if ($ip =~ /$IP_ADDRESS/) {
dbg("Found proxying: $ip");
$iplist{$ip} = 1;
}
}
# check_qmail_ip_header
if ($scanner->get("Received") =~ /\s?from\s+[\w.-]+\s+\(\S+\s+\S+\)\s+(\S+)\s+\(envelope\-sender/) {
$ip = $1;
if ($ip =~ /$IP_ADDRESS/) {
dbg("Found qmail-ip: $ip");
$iplist{$ip} = 1;
}
}
# check_phpscript_ip_header
if ($scanner->get("X-PHP-Script") =~ /\sfor\s(\S+)/) {
$ip = $1;
if ($ip =~ /$IP_ADDRESS/) {
dbg("Found phpscript-ip: $ip");
$iplist{$ip} = 1;
}
}
# check_webmail_ip1
if ($scanner->get("Received") =~ /\s?from\s+[\w.-]+\s+\(\S+\s+\S+\)\s+\([\.\-\_a-z0-9A-Z]+\@[\.\-\_a-z0-9A-Z]+\@(\S+)\)/) {
$ip = $1;
if ($ip =~ /$IP_ADDRESS/) {
dbg("Found webmail-ip1: $ip");
$iplist{$ip} = 1;
}
}
if ($scanner->get("Received") =~ /\s?from\s[\w.-]+\s+(\S+)\s+by\s+[\w.-]+\s+with\s+SMTP\;/) {
$ip = $1;
if ($ip =~ /$IP_ADDRESS/) {
dbg("Found SMTP-ip: $ip");
$iplist{$ip} = 1;
}
}
if ($scanner->get("Received") =~ /\s?from\s(\S+)\s+(?:\S+)[\s
\r]+by\s+[\w.-]+\s+with\s+esmtpa/) {
$ip = $1;
if ($ip =~ /$IP_ADDRESS/) {
dbg("Found Exim-ip1: $ip");
$iplist{$ip} = 1;
}
}
# rediffmail
if ($scanner->get("Received") =~ /(\S+)\sby\srediffmail\.com\svia\sHTTP\;/) {
$ip = $1;
if ($ip =~ /$IP_ADDRESS/) {
dbg("Found rediffmail-ip: $ip");
$iplist{$ip} = 1;
}
}
if ($scanner->get("Received") =~ /\s?from\s+(\S+)\s+by\s+[\w.-]+\s+with\s+HTTP$/) {
$ip = $1;
if ($ip =~ /$IP_ADDRESS/) {
dbg("Found freewebmail: $ip");
$iplist{$ip} = 1;
}
}
# postfix
if ($scanner->get("Received") =~ /\s?from\s+unknown\s+\(HELO\s+[\w.-]+\)\s+\(\[(\S+)\]\)\s*by\s+[\w.-]+\s+with\s+ESMTP\;/) {
$ip = $1;
if ($ip =~ /$IP_ADDRESS/) {
dbg("Found postfix-ip: $ip");
$iplist{$ip} = 1;
}
}
if ($scanner->get("Received") =~ /\s?from\s+(?:\S+)\s+(?:\S+)\s+\[(\S+)\]\)[\s
\r]+\(authenticated\s+user\s+\S+\)/) {
$ip = $1;
if ($ip =~ /$IP_ADDRESS/) {
dbg("Found Postfix-ip1: $ip");
$iplist{$ip} = 1;
}
}
my %countries = ();
my $ipadd;
foreach my $ipaddr (keys(%iplist)) {
$ipadd = $ipaddr;
#if ($ipaddr =~ /(${IP_ADDRESS})/) { $ipadd = $1; }
$ipaddr =~ s/[\x28\x29\x22\x5B\x5D]//gs;
dbg("Test country on $ipadd");
if ($ipaddr =~ /(${IP_ADDRESS})/) {
$ipadd = $1;
dbg("Check country on $ipadd");
}
my $cc = $gi->country_code_by_addr($ipadd);
if ($cc) {
dbg("$ipadd in $cc");
$countries{uc($cc)} = 1;
}
}
foreach my $rule (keys(%{$scanner->{conf}->{xipcountry}})) {
my $country = uc($scanner->{conf}->{xipcountry}->{$rule});
if($countries{$country}) {
dbg ("hit rule: $country");
$scanner->got_hit($rule, "");
}
}
return 1;
}
sub parse_config {
my ($self, $opts) = @_;
my $key = $opts->{key};
if ($key eq 'xipcountry') {
if ($opts->{value} =~ /^(\S+)\s+(\S+)\s*$/) {
my $rulename = $1;
my $country = $2;
dbg("registering $rulename");
$opts->{conf}->{xipcountry}->{$rulename} = $country;
$self->inhibit_further_callbacks(); return 1;
}
}
return 0;
}
sub dbg { Mail::SpamAssassin::Plugin::dbg ("XIPCountry: @_"); }
1;
ifplugin Mail::SpamAssassin::Plugin::OriginatingCountry
xipcountry XIPCOUNTRY_NG NG
header XIPCOUNTRY_NG eval:check_any_ip_header('NG')
describe XIPCOUNTRY_NG Message was sending from Nigeria
score XIPCOUNTRY_NG 20.00
endif
เพิ่มบรรทัดในไฟล์ init.pre
loadplugin Mail::SpamAssassin::Plugin::OriginatingCountry OriginatingCountry.pm