У нас в компании используется сервер Exchange для обмена почтовыми сообщениями. Но для отправки сообщений во "вне" используем Communigate Pro.
Communigate (CGP for Linux) используется только как прослойка и письма отправленные на известные домены пересылаются на Exchange.
схема
Internet
|
|
Communigate Pro
|
|
Exchange
|
|
Users
Но если просмотреть логи, то можно увидеть, что есть огромные очереди на адреса, которых не существует и соответственно куча DNR.
Значит нужно как-то отсеивать эти настырные подключения.
Пришел к выводу, что можно сделать External Authentication + скрипт на perl + запретить пересылку писем на exchange (это будет делать скрипт)
Что было сделано.1. На communigate включил External Authentication (В helpers) с параметрами:
Program Path: /var/CommuniGate/adrelay.pl
Time-out: 20s
Auto-Restart: 30sНе забыть поставить галку External Authentication
2. Так же на communigate в разделе Users - Domain Defaults - Unknown Names:Consult External for Unknown: Yes
Mail to Unknown: Rejected
Теперь напишем скрипт в /var/CommuniGate/adrelay.pl
#!/usr/bin/perl
use Net::LDAP;
my $searchBase = 'dc=DOMAIN,dc=local';
my @ldap_servers=(
{ address=>'XXX.XXX.XXX.XXX', # the address or IP of LDAP server
port=>389, # LDAP port, 389 by default
timeout=>5, # timeout in seconds, 20 by default
adminDN=>'LDAPUSER@DOMAIN.local', # the DN for admin bind
adminPassword=>'Password', # the DN PASSWORD for admin bind
},
{ address=>'XXX.XXX.XXX.XXX', # the address or IP of LDAP server2
port=>389, # LDAP port, 389 by default
timeout=>5, # timeout in seconds, 20 by default
adminDN=>'LDAPUSER@DOMAIN.local', # the DN for admin bind
adminPassword=>'Password', # the DN PASSWORD for admin bind
},
{ address=>'XXX.XXX.XXX.XXX', # the address or IP of LDAP server3
port=>389, # LDAP port, 389 by default
timeout=>5, # timeout in seconds, 20 by default
adminDN=>'LDAPUSER@DOMAIN.local', # the DN for admin bind
adminPassword=>'Password', # the DN PASSWORD for admin bind
},
);$| = 1;
print "* MegaScript started\n";
my ($ldapServerID,$ldapServerTried)=(0,0);
while(<STDIN>) {
chomp; # remove \n from the end of line
my ($prefix,$method,@eargs) = split(/ /);
if($method eq 'NEW') {
unless($prefix && $method && $eargs[0]) {
print "$prefix ERROR Expected: nnn NEW user\@domain\n";
} else {
my $errorMsg=new_command($prefix,$eargs[0]);
if(defined $errorMsg) {
print "$prefix ERROR $errorMsg\n";
}
}
}
elsif ($method eq 'INTF' ) {
if($eargs[0] < 3) {
print "* This script requires CGPro version 4.1b7 or newer\n";
exit;
}exit;
}
print "$prefix INTF 3\n";
}
elsif($method eq 'QUIT') {
print "$prefix OK\n";
last;
} else {
print "$prefix ERROR Only NEW, INTF and QUIT commands supported\n";
}
}
print "* Megascript done\n";
exit(0);
sub tryConnectServer {
my $theServer=$ldap_servers[$ldapServerID];
print "* trying to connect to $theServer->{address}\n";
my $ldap = Net::LDAP->new($theServer->{address},port=>($theServer->{port} || 389),timeout=>($theServer->{timeout} || 20) )
|| return undef;
return $ldap;
}
sub tryConnect {
my $nServers=scalar(@ldap_servers);
for(my $nTried=0;$nTried<$nServers;$nTried++) {
if($ldapServerID>=$nServers) { $ldapServerID=0;}
my $ldap=tryConnectServer();
return $ldap if($ldap);
++$ldapServerID;
}
return undef;
}sub new_command {
my ($prefix,$user)=@_;
my ($name,$domain)=("","");
if($user =~ /(.+)\@(.+)/) {
$name=$1;
$domain=$2;
} else {
return "Full account name with \@ and domain part expected";
}
my $ldap = tryConnect();
unless($ldap) {
return "Failed to connect to all LDAP servers";
}
my $adminDN=$ldap_servers[$ldapServerID]->{adminDN};
my $adminPassword=$ldap_servers[$ldapServerID]->{adminPassword};
my $result=$ldap->bind($adminDN,password=>$adminPassword)
|| return "Can't bind as admin: ".$result->error;
$result->code && return "Can't bind as admin: ".$result->error;
my $mesg = $ldap->search ( # perform a search
base => $searchBase,
scope => "subtree",
filter => "(&(proxyAddresses=smtp:$name\@$domain) (objectclass=*))"
);$ldap->unbind();
unless(defined $mesg) {
return "LDAP search failed";
}
if($mesg->all_entries() eq 0) {
return "address $name\@$domain NOT exists";
} else {
print "$prefix ROUTED $name\%$domain\@[IPEXCHANGE]\n";
# Pomenyai IPEXCHANGE!!!!!!!!!!!!
return undef;
}
};
Что делает скрипт.
При получении адреса e-mail в RCPT TO ищет его в AD в атрибутах пользователей. Если не находит, то сообщение игнорируется.Проверить работоспособность скрипта можно запустив его и набрать 1 NEW email@domain.ru
Если выдаст ROUTED email%domain.ru@IPEXCHANGE - то значит все ОК!!!
URL:
Обсуждается: http://www.opennet.me/tips/info/2218.shtml
Я у себя сделал немного по-другому: чтобы не делать тысячи обращений в час к AD на проверку существования пользователей, запускаю скрипт, который делает поиск всех адресов почты ао AD и пишет их в файл, а почтовый сервер(у меня postfix) смотрит адреса по локальному файлу.
Аналогично. По крону раз в 10 минут запускаю.
А нельзя разве сразу в AD postfix'ом смотреть адреса? У него же есть поддержка карт ldap
Я думал о файле, но у нас достаточно много человек и большая ротация персонала. Данный скрипт позволит следить за изменениями в режиме реального времени.Это уже V2. До этого была возможность подключения только к одному контроллеру домена. И если происходила ошибка, то почта переставала ходить. Здесь же можно увеличивать число контроллеров домена до бесконечности.
>Я думал о файле, но у нас достаточно много человек и большая
>ротация персонала.Что раз в 30 минут сотрудники увольняются/принимаются?
Я бы сделал вебмордочку для сотрудницы отдела кадров, чтобы она сама блокировала учетку. При блокировке, будет перегенерироваться файл для проверки почтовиком.
в exim это на уровне acl делается, без всяких скриптов
В postfix тоже, с помощью карт просмотра ldap :)
Ура велосипедистамиспользовать exchange только для писем это пипец
А для чего же ще ентот ексченж использовать?
нуда нуда
а патом еще говорят что венда отстой)
Все же непонятно, зачем гонять платный CGP, чтобы обеспечивать проксирование для платного же MS Exchange? При том, что первый конкурирует со вторым :)
>Все же непонятно, зачем гонять платный CGP, чтобы обеспечивать проксирование для платного
>же MS Exchange? При том, что первый конкурирует со вторым :)
>По воду первого не скажу - это к автору, но могу предположить - внешний фильтр и SMTP-прокси, а вот Exchange при всём вашем сарказме для многих организаций самое оно. Почтовик как таковой сейчас уж слишком "бедное" решение. Нужны и общие календари и папки, и планировщики, и интеграция с другими сервисами в сети, это в конце концов удобная работа с коммуникаторами и единый почтовый клиент.
Дело в том что всё что вы описали CommuniGate умеет сам по-себе :)
>Дело в том что всё что вы описали CommuniGate умеет сам по-себе
>:)Вопрос в формате и интегрированности. Exchange это интегрированный продукт, который чудесно встраивается и расширяет функционал других приложений MS, впрочем это тема не для этого форума. Опять таки возращаясь к почтовым клиентам и доступу с моб. устройств - комунигейту далековато в этом плане до MS - мое личное мнение.