Go to content Go to menu Go to search

Smtp фильтры для postfix

Задача 1

На сервере с postfix нужно сделать так, что бы отправлять письма через него можно было только из определенных стран.

Решение

Использовать функционал postfix tcp_table, perl и GeoIP. Нам понадобится пакет perl-Geo-IP из repoforge!

скрипт /etc/postfix/geo-reject.pl

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#!/usr/bin/perl
use strict;
use warnings;
use Sys::Syslog qw(:DEFAULT setlogsock);
use Geo::IP;

my $gi = Geo::IP->new(GEOIP_STANDARD);

# maps country code to reject (this is just example)
# add more country code you would like to reject
my @geo_map = (
    'US' ,
    'CA'
);

#
# Initalize and open syslog.
#
openlog('postfix/geoIP-reject','pid','mail');
#openlog('postfix/geoIP-reject','pid','local1');

#
# Autoflush standard output.
#
select STDOUT; $|++;

while (<>) {
    chomp;
    if (/^get\s(.+)$/i) {
        my $client_ip = $1;
        my $country_code = $gi->country_code_by_name($client_ip);

        if (defined $country_code)
        {
            if ( !(grep /$country_code/, @geo_map) )
            {
                print "200 REJECT you're from $country_code\n";
                syslog("info","Rejecting: %s", $country_code);
            } else {
                print "200 DUNNO\n";
            }
        } else {
            print "200 DUNNO\n";
        }
        next;
    }
    print "200 DUNNO\n";
}

Заставляем postfix запускать этот скрипт в фоне (master.cf):

127.0.0.1:2528 inet  n       n       n       -       0      spawn
    user=nobody argv=/etc/postfix/geo-reject.pl

Подключаем, для этого, в main.cf:

geoip = check_client_access tcp:[127.0.0.1]:2528

в master.cf в сервисах submission и 465 добавляем в smtpd_client_restrictions примерно так:

465    inet  n       -       n       -       -       smtpd
    -o smtpd_tls_wrappermode=yes 
    -o smtpd_sasl_auth_enable=yes
    -o smtpd_client_restrictions=$geoip
    -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
    -o syslog_name=postfix/smtps
    -o milter_macro_daemon_name=ORIGINATING
submission inet n      -       n       -       -       smtpd
    -o smtpd_etrn_restrictions=reject
    -o smtpd_sasl_auth_enable=no
    -o smtpd_tls_security_level=may
    -o smtpd_client_restrictions=$geoip
    -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
    -o syslog_name=postfix/submission
    -o milter_macro_daemon_name=ORIGINATING

Проверяем:

# telnet localhost 2528
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
get 217.112.35.75
200 REJECT you're from GB

Задача 2

Если нужно сделать то же самое, но для только для нескольких почтовых акаунтов

Решение

Будем использовать функционал postfix Policy Delegation.

Скрипт /etc/postfix/postfix-geo-policy.pl:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#!/usr/bin/perl
use strict;
use warnings;
use Switch;
use Sys::Syslog qw(:DEFAULT setlogsock);
use Geo::IP;

my $DEBUG = 0;
my $SENDERS_LIST='/etc/postfix/postfix-geo-policy-senders.txt';
# Add countries
my @geo_map = (
    'US' ,
#    'RU' ,
);

my $gi = Geo::IP->new(GEOIP_STANDARD);
my %attributes;

#
# Initalize and open syslog.
#
openlog('postfix/geoIP-reject','pid','mail');
#openlog('postfix/postfix-geo-policy','pid','local2');

#
# Autoflush standard output.
#
select STDOUT; $|++;
while (<>) {
    chomp;
    my $line = $_;
    $line =~ s/[\r\n]*$//; # this line remove \r\n from end of line if native perl chomp fails
    if ( $line eq '' ) { &policy; next; }
    (my $attr_name, my $attr_value) = split ( "=", $line );
    $attributes{$attr_name} = $attr_value if $attr_value;
}

sub policy {
    my $result;

    # Add load senders list
    my @senders;
    open (IN, "<$SENDERS_LIST");
    while (<IN>) { push @senders, $_; }
    close IN;

    # policy rules
    if ( $attributes{'sender'} && $attributes{'client_address'} ) {
        if ( grep /$attributes{'sender'}/, @senders ) {
        my $country_code = $gi->country_code_by_name($attributes{'client_address'});
            if ( $country_code ) {
        if ( !(grep /$country_code/, @geo_map) ) {
                    $result = "REJECT you're from $country_code";
                syslog("info","REJECT! sender: $attributes{'sender'} IP: $attributes{'client_address'} country: $country_code");
        }
        else {
            syslog("info","OK! sender: $attributes{'sender'} IP: $attributes{'client_address'} country: $country_code");
        }
            }
        }
        else {
            syslog("info","OK! (sender is not in restriction list) addr: $attributes{'sender'} IP: $attributes{'client_address'}");
       }
    }

    # cleanup %attributes
    foreach my $attr_name ( keys %attributes ) {
    syslog("info","$attr_name=$attributes{$attr_name}") if $DEBUG;
    delete($attributes{$attr_name});
    }

    # output result
    if ( $result ) {
    print "action=$result\n\n";
    syslog("info","Rejecting message with $result");
    }
    else {
    syslog("info","OK!!") if $DEBUG;
    print "action=DUNNO\n\n";
    }

}

Создаем файл со списком адресов отправителей, которые нужно проверять /etc/postfix/postfix-geo-policy-senders.txt.

Заставляем postfix запускать этот скрипт в фоне (master.cf):

127.0.0.1:9998 inet  n       n       n       -       0      spawn
     user=nobody argv=/etc/postfix/postfix-geo-policy.pl

Подключаем, для этого, в main.cf:

geoip_policy = check_policy_service  inet:127.0.0.1:9998

в master.cf в сервисах submission и 465 добавляем в smtpd_client_restrictions примерно так:

465    inet  n       -       n       -       -       smtpd
    -o smtpd_tls_wrappermode=yes 
    -o smtpd_sasl_auth_enable=yes
    -o smtpd_client_restrictions=$geoip_policy
    -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
    -o syslog_name=postfix/smtps
    -o milter_macro_daemon_name=ORIGINATING
submission inet n      -       n       -       -       smtpd
    -o smtpd_etrn_restrictions=reject
    -o smtpd_sasl_auth_enable=no
    -o smtpd_tls_security_level=may
    -o smtpd_client_restrictions=$geoip_policy
    -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
    -o syslog_name=postfix/submission
    -o milter_macro_daemon_name=ORIGINATING

Проверяем:

# telnet localhost 9998
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
sender=mari**@***prop.com
client_address=162.243.1.181

action=DUNNO

Список атрибутов, которые передаются в скрипт на этапе smtpd_client_restrictions:

protocol_state=RCPT
request=smtpd_access_policy
sasl_username=mari**@***prop.com
recipient=srab_alk**@****.com
sasl_method=LOGIN
instance=7df1.57739b39.6bf8f.0
protocol_name=ESMTP
encryption_keysize=256
helo_name=www.globalbotanical.com
sender=mari***@***prop.com
reverse_client_name=www.advanceqc.com
client_name=unknown
client_address=162.243.1.***
encryption_cipher=ECDHE-RSA-AES256-SHA
encryption_protocol=TLSv1

Enjoy!


при публикации материалов с данного сайта обратная ссылка на сайт обязательна.
valynkin.ru © no rights reserved