Ldap failover

EXIM, sendmail, postfix, Dovecot и прочие. Решение проблем связанных с работой электронной почты

Модератор: xM

Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
CrazyPilot
ст. сержант
Сообщения: 321
Зарегистрирован: 2008-08-14 9:17:58
Откуда: Санкт-Петербург
Контактная информация:

Ldap failover

Непрочитанное сообщение CrazyPilot » 2008-11-17 11:17:54

Доброго времени суток!

Что есть:

Код: Выделить всё

[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 принимал бы все письма и копил их в очереди. Потом при возвращении контроллеров к жизни - начал роутить письма по сконфигуренным роутерам. Возможно такое? Если да, просветите, плз, как такое сделать...

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

Brain
проходил мимо
Сообщения: 5
Зарегистрирован: 2008-09-02 8:56:03

Re: Ldap failover

Непрочитанное сообщение Brain » 2008-11-22 16:57:46

Может имеет смысл установиться openldap и делать репликацию из AD?

pango
проходил мимо
Сообщения: 7
Зарегистрирован: 2008-09-23 20:29:14

Re: Ldap failover

Непрочитанное сообщение pango » 2008-11-22 20:14:52

Ага. Это слабое место использования 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

Код: Выделить всё

pupkin      IP принимающего сервера
...
и т.д.
Можно еще использовать 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 должно быть

Код: Выделить всё

pupkin@domain.tld
...
и т.д.
Оба варианта работают. Но какой правильнее и правильны ли они идеологически, сам не знаю. Только начинаю осваивать.
Может старшие товарищи меня поправят.

klin2
рядовой
Сообщения: 12
Зарегистрирован: 2007-02-09 20:12:25
Откуда: Germany

Re: Ldap failover

Непрочитанное сообщение klin2 » 2008-11-29 21:01:01

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;

CrazyPilot
ст. сержант
Сообщения: 321
Зарегистрирован: 2008-08-14 9:17:58
Откуда: Санкт-Петербург
Контактная информация:

Re: Ldap failover

Непрочитанное сообщение CrazyPilot » 2008-12-01 13:48:24

В общем все сводится к тому, чтобы роутить письма через локальный файлик, а файлик формировать скриптом по крону. Я же хочу сделать иначе, чтобы при недоступности ldap замораживать сообщения и пытаться их доставить через 1, 2, 3 и т.д.