Страница 1 из 1
Ldap failover
Добавлено: 2008-11-17 11:17:54
CrazyPilot
Доброго времени суток!
Что есть:
Код: Выделить всё
[ArtemK@flanker ~]$ uname -a
FreeBSD flanker.example.ru 7.0-RELEASE-p5 FreeBSD 7.0-RELEASE-p5 #2: Fri Oct 24 12:04:07 MSD 2008 root@flanker.example.ru:/usr/obj/usr/src/sys/FLANKER-PAE-2008-10-24 i386
[ArtemK@flanker ~]$ exim -bV
Exim version 4.69 #0 (FreeBSD 7.0) built 11-Sep-2008 14:23:42
...
На данный момент, exim всех получателей у меня проверяет в MS AD.
В конфиге экзима прописаны два контроллера домена, а ля failover сделан:
Код: Выделить всё
hide ldap_default_servers = boss1.example.ru::3268 : boss2.example.ru::3268
Если убрать из конфига оба сервака - exim не принимает письма - типа невозможно проверить существование адреса. Lookup timeout...Хочется, чтобы почта не пропадала, если вдруг оба контроллера уйдут в даун, а ля питание выключат и сетка пропадет, или оба упадут...
Я вот думаю, как бы так сделать, что если оба контроллера недоступны - exim принимал бы все письма и копил их в очереди. Потом при возвращении контроллеров к жизни - начал роутить письма по сконфигуренным роутерам. Возможно такое? Если да, просветите, плз, как такое сделать...
Re: Ldap failover
Добавлено: 2008-11-22 16:57:46
Brain
Может имеет смысл установиться openldap и делать репликацию из AD?
Re: Ldap failover
Добавлено: 2008-11-22 20:14:52
pango
Ага. Это слабое место использования LDAP. Надо сделать локальный файл со списком получателей.
Скрипт для образца здесь
http://www-personal.umich.edu/~malth/ga ... tadsmtp.pl
Его надо обработать напильником для выделения $local_part. Или использовать ниже в поиске и $domain
И потом что-то вроде
Код: Выделить всё
smarthost:
driver = manualroute
domains = +local_domains
route_data = ${lookup{$local_part}lsearch{/usr/local/etc/exim/local_recipients.txt}}
transport = remote_smtp
В local_recipients.txt
Можно еще использовать route_list
Код: Выделить всё
smarthost:
driver = manualroute
domains = +local_domains
route_list = * IP принимающего сервера
transport = remote_smtp
Но тогда надо будет проверять получателя в acl_rcpt
Код: Выделить всё
drop message = Invalid recipient
domains = +local_domains
recipients = !/usr/local/etc/exim/local_recipients.txt
Тогда в local_recipients.txt должно быть
Оба варианта работают. Но какой правильнее и правильны ли они идеологически, сам не знаю. Только начинаю осваивать.
Может старшие товарищи меня поправят.
Re: Ldap failover
Добавлено: 2008-11-29 21:01:01
klin2
exim.conf:
Код: Выделить всё
# route to exchange server
exchange:
driver = manualroute
transport = remote_smtp
domains = yourdomain.org
condition = ${lookup{$local_part@$domain}lsearch{/etc/exim/virtual.txt}{yes}{no}}
getadsmtp.pl: (getadsmtp.pl запускать по "cron")
Код: Выделить всё
#!/usr/bin/perl -w
# This script will pull all users' SMTP addresses from your Active Directory
# (including primary and secondary email addresses) and list them in the
# format "user@example.com".
# Be sure to double-check the path to perl above.
# This requires Net::LDAP to be installed. To install Net::LDAP, at a shell
# type "perl -MCPAN -e shell" and then "install Net::LDAP"
use Net::LDAP;
use Net::LDAP::Control::Paged;
use Net::LDAP::Constant ( "LDAP_CONTROL_PAGED" );
# Enter the path/file for the output
$VALID = "/etc/exim/virtual.txt";
open VALID, ">$VALID" or die "CANNOT OPEN $VALID $!";
# Enter the FQDN of your Active Directory domain controllers below
$dc1="server1.w2k3-dom.local";
$dc2="server2.w2k3-dom.local";
$domain="yourdomain.org";
# Enter the LDAP container for your userbase.
# The syntax is CN=Users,dc=example,dc=com
# This can be found by installing the Windows 2000 Support Tools
# then running ADSI Edit.
# In ADSI Edit, expand the "Domain NC [domaincontroller1.example.com]" &
# you will see, for example, DC=example,DC=com (this is your base).
# The Users Container will be specified in the right pane as
# CN=Users depending on your schema (this is your container).
# You can double-check this by clicking "Properties" of your user
# folder in ADSI Edit and examining the "Path" value, such as:
# LDAP://domaincontroller1.example.com/CN=Users,DC=example,DC=com
# which would be $hqbase="cn=Users,dc=example,dc=com"
# Note: You can also use just $hqbase="dc=example,dc=com"
$hqbase="dc=w2k3-dom,dc=local";
# Enter the username & password for a valid user in your Active Directory
# with username in the form cn=username,cn=Users,dc=example,dc=com
# Make sure the user's password does not expire. Note that this user
# does not require any special privileges.
# You can double-check this by clicking "Properties" of your user in
# ADSI Edit and examining the "Path" value, such as:
# LDAP://domaincontroller1.example.com/CN=user,CN=Users,DC=example,DC=com
# which would be $user="cn=user,cn=Users,dc=example,dc=com"
# Note: You can also use the UPN login: "user\@example.com"
$user="cn=user,cn=Users,dc=w2k3-dom,dc=local";
$passwd="secret";
# Connecting to Active Directory domain controllers
$noldapserver=0;
$ldap = Net::LDAP->new($dc1) or
$noldapserver=1;
if ($noldapserver == 1) {
$ldap = Net::LDAP->new($dc2) or
die "Error connecting to specified domain controllers $@ \n";
}
$mesg = $ldap->bind ( dn => $user, password =>$passwd);
#$mesg = $ldap->bind ;
if ( $mesg->code()) {
die ("error:", $mesg->error_text((),"\n"));
}
# How many LDAP query results to grab for each paged round
# Set to under 1000 for Active Directory
$page = Net::LDAP::Control::Paged->new( size => 100 );
@args = ( base => $hqbase,
# Play around with this to grab objects such as Contacts, Public Folders, etc.
# A minimal filter for just users with email would be:
# filter => "(&(sAMAccountName=*)(mail=*))"
filter => " (| (&(objectClass=user) (proxyAddresses=smtp*)(!(name=SystemMailbox*)))
(&(objectClass=group)(proxyAddresses=smtp*)(!(name=SystemMailbox*)))
) ",
control => [ $page ],
attrs => "proxyAddresses",
);
my $cookie;
while(1) {
# Perform search
my $mesg = $ldap->search( @args );
# Filtering results for proxyAddresses attributes
foreach my $entry ( $mesg->entries ) {
my $name = $entry->get_value( "cn" );
# LDAP Attributes are multi-valued, so we have to print each one.
foreach my $mail ( $entry->get_value( "proxyAddresses" ) ) {
if ( $mail =~ s/^(smtp|SMTP)://gs && $mail =~ /$domain/ ) {
print VALID $mail."\n";
}
}
}
# Only continue on LDAP_SUCCESS
$mesg->code and last;
# Get cookie from paged control
my($resp) = $mesg->control( LDAP_CONTROL_PAGED ) or last;
$cookie = $resp->cookie or last;
# Set cookie in paged control
$page->cookie($cookie);
}
if ($cookie) {
# We had an abnormal exit, so let the server know we do not want any more
$page->cookie($cookie);
$page->size(0);
$ldap->search( @args );
# Also would be a good idea to die unhappily and inform OP at this point
die("LDAP query unsuccessful");
}
close VALID;
Re: Ldap failover
Добавлено: 2008-12-01 13:48:24
CrazyPilot
В общем все сводится к тому, чтобы роутить письма через локальный файлик, а файлик формировать скриптом по крону. Я же хочу сделать иначе, чтобы при недоступности ldap замораживать сообщения и пытаться их доставить через 1, 2, 3 и т.д.