amavisd plugin for the geolocation addresses and headers X-Anti-Abuse

Mark Martinec Mark.Martinec+amavis at ijs.si
Tue May 3 17:39:04 CEST 2011


fakessh,


> I wrote a plugin that minimum here but I get no result
> 
> package Amavis::Custom;
> use Geo::IP::PurePerl;
> 
> # invoked at child process creation time;
> # return an object, or just undef when custom checks are not needed
> sub new {
>  my($class,$conn,$msginfo) = @_;
>  my($self) = bless {}, $class;
> my($cl_ip) = $msginfo->client_addr;
>   if (!exists $self->{geoip}) {
>     my $geo_file = "/usr/share/GeoIP/GeoLiteCity.dat";
>     $self->{geoip} = undef;
>     if (!-e $geo_file) {
>       do_log(0, "geoip-plugin: GeoIP, unable to stat %s", $geo_file);
>     } else {
>       $self->{geoip} = Geo::IP::PurePerl->new($geo_file, GEOIP_STANDARD);
>       do_log(0, "geoip-plugin: GeoIP, failed to open %s",
>                  $geo_file)  if !$self->{geoip};
>     }
>   }
>   my($country_code, $country_code3, $country_name, $region,
>               $city,         $postal_code,   $latitude,     $longitude,
>               $metro_code,   $area_code) =
> $self->{geoip}->get_city_record($cl_ip);
>  my($hdr_edits) = $msginfo->header_edits;
>        $hdr_edits->add_header('X-Header-GeoIP-Client', " geo ip client
> $country_code $country_code3 $country_name $region   $city
> $postal_code   $latitude     $longitude  $metro_code   $area_code ");
> 
>  $self;  # returning an object activates further callbacks,
>            # returning undef disables them
> }
> 1;  # insure a defined return

Your custom hook looks fine on a first glance (didn't try it),
and it should be inserting the X-Header-GeoIP-Client header field.

Make sure the code is actually included or called from amavisd.conf,
e.g.:
  include_config_files('/etc/amavisd-custom.conf');

Here is a similar hook that I'm using here, it does add these header fields:


package Amavis::Custom;
use strict;
use re 'taint';
use warnings;
use warnings FATAL => qw(utf8 void);
no warnings qw(uninitialized redefine);

BEGIN {
  import Amavis::Conf qw(:platform :confvars c cr ca);
  import Amavis::Util qw(do_log untaint min max);
}

sub new {
  my($class,$conn,$msginfo) = @_;
  my($self) = bless {}, $class;
  checks_geo($self,$conn,$msginfo);
  $self;
}

use Geo::IP;
sub checks_geo {
  my($self,$conn,$msginfo) = @_;
  if (!exists $self->{geoip}) {  # first time only in a child process
    my $geo_file = "/usr/local/share/GeoIP/GeoLiteCity.dat";
    $self->{geoip} = Geo::IP->open($geo_file, GEOIP_STANDARD);
    if (!$self->{geoip}) {
      do_log(0, "GeoIP: failed to open %s", $geo_file);
    } else {
      $self->{geoip}->set_charset(GEOIP_CHARSET_UTF8);
    }
  }
  if ($self->{geoip}) {
    my $last_received_ip =
      Amavis::UnmangleSender::parse_ip_address_from_received($msginfo);
    if (defined $last_received_ip && $last_received_ip ne '') {
      my($country_name,$region_name,$city);
      my $record = $self->{geoip}->record_by_addr($last_received_ip);
      if (!$record) {
        do_log(2, "GeoIP: no record for %s", $last_received_ip);
      } else {
        $country_name = $record->country_name;
        $region_name = $record->region_name;
        $city = $record->city;
      }
      do_log(2, "GeoIP: %-15s %s %s, %s, %s", $last_received_ip,
                $msginfo->is_in_contents_category(CC_SPAM) ? 'SPAM' : '    ',
                map(defined $_ && $_ ne '' ? $_ : "-",
                    $country_name, $region_name, $city));
      my $hdr_edits = $msginfo->header_edits;
      $hdr_edits->add_header('X-Amavis-GeoIP', "$country_name $city");
    }
  }
}

1;



Add calls to do_log to your code to help with debugging.


> but when I've put my achievements in production
> the headers X-SenderID disappears
> so I wonder why after having added mimedefang header and X-SenderID disappears

I don't know about that. Amavisd is not removing an X-SenderID header field.

  Mark


More information about the amavis-users mailing list