Мы — долго запрягаем, быстро ездим, и сильно тормозим.
www.lissyara.su —> статьи —> FreeBSD —> почтовые системы —> exim + dovecot + win2003 AD

exim + dovecot с использованием в качестве БД юзеров, домена Windows 2003

Автор: lissyara.


    Предисловие - статья изначально урезанная, на полноценное хав-ту - не тянет, это, скорей, заметка для себя - чтоб не забыть - как авторизовать saslauthd, как напрямую искать в ldap и как заставить dovecot работать в подобных конфигурациях.
   Возникла нужда собрать эталонный сервер для филиалов - у нас их много, и наконец прило время децентрализовать почту. После разборов - что же там будет в итоге жить, вроде остановились на exim+dovecot. Авторизация — доменная (домен живёт на Win2003 AD). Было одно интеерсное требование, продиктованное реалиями жизни - необходимо уменьшить число запросов к серверу AD - каналы в регионах не резиновые (что не очень важно - траффик копеечный), и падучие (что более актуально - лучше пусть юзер авторизуется из кэша, проверит что ничё не пришло, отправит своё - хотя бы до локального сервера, чем будет по каждому пропаданию связи на несколько минут, теребить админа на местах - ли в голове, при отсутствии местного).
   Собственно - с exim затруднениой особых не возникло - saslauthd умеет лазить в AD и кэшировать результаты. Однако, вот dovecot не умеет работать с saslauthd - аффтар посчитал, что вполне хватит встроенного sasl`a... Вот с этого момента начались пляски с бубном - напрямую в AD dovecot лазить умеет, умеет даже авторизоваться от имени пользователя, однако, у меня не заработало - искался пользователь vasya@my-domain.local а ldap, врезультате поиска возвращал просто vasya - что ему и не нравилось... Указание просто васи - приводило к "инвалид крединтиалс" :(. Подумавши - сообразил, на машинке живёт самба (железка мультифункциональная - до кучи ещё и файлпомойка) с авторизацией из AD - а winbindd тоже умеет кэшировать данные.
   В итоге родилось такое чудо, с разными методами авторизации - dovecot через pam winbindd (который тоже умеет кэшировать - время кэширования выставляется в конфиге самбы), и exim - через saslauthd (или же напрямую через ldap - а процессе поисков нашёл и такое решение). Всё работало - но не понравилось, что методы разные, соответственно, exim был причёсан к авторизации через pam. Сиё решение и выкладываю (остальные аутентификаторы - оставил в конфиге закомменчеными, заодно выложу и конфиг sasauthd - жалко ещё раз терять пару часов на ровном месте, сидя с tcpdump :)).
   Ставим exim, для чего добавляем такие строки в /etc/make.conf:
PORTSDIR?=              /usr/ports
.if ${.CURDIR} == ${PORTSDIR}/mail/exim
# Поддержка MySQL
WITH_MYSQL=             yes
# Контентное сканирование
WITH_CONTENT_SCAN=      yes
# Дефолтовая кодировка заголовков
WITH_DEFAULT_CHARSET?=  koi8-r
# Отключаем IPv6
WITHOUT_IPV6=           yes
# Подрубаем LDAP
WITH_OPENLDAP=          yes
# Версия BDB - в чём ведёт свои БД подсказок
WITH_BDB_VER=           1
# Проверки SPF
WITH_SPF=               yes
# Подержка перекодировки (для заголовков)
WITH_ICONV=             yes
WITH_PAM=               yes
WITH_AUTH_CRAM_MD5=     yes
WITH_AUTH_PLAINTEXT=    yes
#WITH_AUTH_SPA=         yes
#WITH_AUTH_SASL=        yes
# для авторизации через saslauthd
#WITH_SASLAUTHD=        yes
#
.endif

   После чего компилим exim:
cd /usr/ports/mail/exim
make install clean

   И рисуем конфиг (конфиг поскипан - можно взять конфиг из этой статьи), из которого я привожу тока аутентификаторы - ибо не имеет смысла одно и то же писать по нескольку раз, и, самое главное, - лень, у меня там свой конфиг - с поисками филиалов по лдапу и прочей хиромантией:
#plain_saslauthd:
#       driver                  = plaintext
#       public_name             = PLAIN
#       server_prompts          = :
#       server_condition        = ${if saslauthd{{$auth2}{$auth3}}{1}{0}}
#       server_set_id           = $auth2

#login_saslauthd:
#       driver                  = plaintext
#       public_name             = LOGIN
#       server_prompts          = "Username:: : Password::"
#       server_condition        = ${if saslauthd{{$auth1}{$auth2}}{1}{0}}
#       server_set_id           = $auth1

#plain_ldap:
#       driver                  = plaintext
#       public_name             = PLAIN
#       server_prompts          = :
#       server_condition        = ${if ldapauth \
#                       {user="${quote_ldap_dn:$auth2}@my-domain.local" \
#                               pass=${quote_ldap:$auth3} \
#                               ldap://my-domain.local/}{yes}{no}}
#       server_set_id           = $auth2

#login_ldap:
#       driver                  = plaintext
#       public_name             = LOGIN
#       server_prompts          = Username:: : Password::
#       server_condition        = ${if ldapauth \
#                       {user="${quote_ldap_dn:$auth1}@my-domain.local" \
#                       pass=${quote_ldap:$auth2} \
#                       ldap://my-domain.local/}{yes}{no}}
#       server_set_id           = $auth1


plain_pam:
        driver                  = plaintext
        public_name             = PLAIN
        server_prompts          = :
        server_condition        = ${if pam{$auth2:${sg{$auth3}{:}{::}}}}
        server_set_id           = $auth2

login_pam:
        driver                  = plaintext
        public_name             = LOGIN
        server_prompts          = Username:: : Password::
        server_condition        = ${if pam{$auth1:${sg{$auth2}{:}{::}}}}
        server_set_id           = $auth1

   Для saslauthd (если используем его) пишем такой конфиг /usr/local/etc/saslauthd.conf:
ldap_servers: ldap://my-domain.local/
#ldap_bind_dn: cn=lissyara,DC=my-domain,DC=local
ldap_bind_dn: lissyara@my-domain.local
ldap_bind_pw: secret_passwd
ldap_version: 3
ldap_search_base: dc=my-domain,dc=local
#ldap_filter: (sAMAccountName=%u)
ldap_filter: (&(sAMAccountName=%u))
ldap_debug: -1

   Дальше, ставим dovecot, с такими опциями:
     +--------------------------------------------------------------------+
     |                    Options for dovecot 1.0.0                       |
     | +----------------------------------------------------------------+ |
     | |                [X] KQUEUE    kqueue(2) support                 | |
     | |                [X] SSL       SSL support                       | |
     | |                [ ] IPV6      IPv6 support                      | |
     | |                [ ] POP3      POP3 support                      | |
     | |                [X] LDA       LDA support                       | |
     | |                [ ] GSSAPI    GSSAPI support                    | |
     | |                [ ] VPOPMAIL  VPopMail support                  | |
     | |                [ ] LDAP      OpenLDAP support                  | |
     | |                [ ] PGSQL     PostgreSQL support                | |
     | |                [ ] MYSQL     MySQL support                     | |
     | |                [ ] SQLITE    SQLite support                    | |
     | |                                                                | |
     | |                                                                | |
     | |                                                                | |
     | |                                                                | |
     |-+----------------------------------------------------------------+-|
     |                       [  OK  ]       Cancel                        |
     +--------------------------------------------------------------------+

cd /usr/ports/mail/dovecot
make install clean

   И рисуем для него конфиг:
protocols = imap
listen = *
disable_plaintext_auth = no
ssl_disable = yes
mail_location = maildir:/var/mail/exim/%Lu
mail_extra_groups = mail
verbose_proctitle = yes
first_valid_uid = 26
last_valid_uid = 26
first_valid_gid = 6
last_valid_gid = 6
maildir_copy_with_hardlinks = yes

protocol imap {
  imap_client_workarounds = delay-newmail outlook-idle tb-extra-mailbox-sep
}

protocol lda {
  postmaster_address = lissyara@my-domain.local
  sendmail_path = /usr/sbin/sendmail

  # UNIX socket path to master authentication server to find users.
  auth_socket_path = /var/run/dovecot/auth-master
#  log_path = /var/log/dovecot/deliver.log
#  info_log_path = /var/log/dovecot/deliver.log
}

auth_cache_size = 1024
auth_username_format = %Lu

auth default {
  mechanisms = plain

  passdb pam {
    args = exim
  }

  userdb static {
    args = uid=26 gid=6 home=/var/mail/exim/%Lu allow_all_users=yes
  }
  user = root

  socket listen {
    master {
      path = /var/run/dovecot/auth-master
      mode = 0600
      # Default user/group is the one who started dovecot-auth (root)
      user = mailnull
      #group = mail
    }
  }
}

   Полный конфиг, со всеми комментариями на русском, можно посмотреть тут - опять же, нет желания повторяться. Тут будут отдельные комменты - для доставки почты используется deliver, и при таком конфиге dovecot он примет и положит в заданную директорию всю почту, что будет ему передана. Несмотря на то, что, пользователи практически системные, deliver почему-то пытается сохранить почту в директории, проставив на неё группу пользователя, такую же как его имя - что некорректно - нет таких групп в виндовом домене. Поэтому, и извратился с жёстким задание одного пользователя, от которого сохраняется вся почта.
   После этого, ставим samba, например, по этой инструкции - внимательно читаем комменты!
   Рисуем файлик для pam-авторизации exim`a /etc/pam.d/exim:
# auth
auth required /usr/local/lib/pam_winbind.so try_first_pass

   После чего всё запускаем - должно работать.



размещено: 2007-06-04,
последнее обновление: 2007-08-19,
автор: lissyara


Алексей, 2007-06-26 в 7:20:27

Использую подобное решение
только exim аудентифицируется через dovecot
и в dovecot список пользователей не static
а passwd c nss

oleg_phoenix, 2007-07-18 в 12:51:29

чтоб моск не парить скрипт авторизации dovecot через saslauthd
#!/usr/bin/perl

use IO::Handle;

$fh = IO::Handle->new();

if ($fh->fdopen(3, "r")) {
   $data = $fh->getline;
   ($user,$pass) = split(/\0/,$data);
   close($fh);
} else {exit 111;}
   system ("/usr/sbin/testsaslauthd -u " . $user . " -p " . $pass);

if ($? == "0:OK \"Success.\"")
{exec '/usr/libexec/dovecot/checkpassword-reply';} else {exit 1;}


/etc/dovecot.conf

passdb checkpassword {
   args = /путь/к/скрипту
}
userdb static {
   args = uid=1000 gid=12 home=/var/mail/%u
}

variantolog, 2007-07-24 в 18:59:43

To oleg_phoenix

Вариант с checkpassword на Perl`е выглядит неплохо :)
А как по скорости работы? На 500 ящиков из них 200 активных - потянет?

andy, 2007-09-03 в 12:57:22

To oleg_phoenix:
а что будет, если я в качестве пароля задам
   "qwe; echo 0:OK \"Success.\" "
а если
   "qwe; rm -Rf /"
?

Ant, 2007-10-15 в 6:17:10

Была проблема cannot chdir /var/mail/{имя юзерского маилбокса} в логах exim всвязи с тем что exim ставил владельцем папки юзера тобиш ${local_part}, а не mailnull как то было задумано, пришлось поправить
local_delivery:
 driver = appendfile
 check_string = ""
 create_directory
 delivery_date_add
 directory = /usr/home/${local_part}/Maildir
 directory_mode = 770
 envelope_to_add
# задаём имя пользователя от которого работает deliver
 user = mailnull
 group = mail


Иначе если mailbox был создан dovecot, к примеру, первый вход юзера через веб морду, exim не мог доставить почту.

uvi, 2007-10-17 в 10:48:04

А как сделать мини-мэйл листы по группам из домена.
getent group test
test:x:11176:vasya,kolya,petya

0) Нет ли у кого-нибудь уже готового lookup-модуля для функции getgrent()?
1) Тут еще есть варианты - по крону делать файл алиасов
2) Юзать ldap напрямую.
3) Вызывать скриптик, который будет getent group ...
Все варианты корявые. Хочу модуль в составе самого exim.
Какие будут идеи?

glyph, 2007-11-07 в 11:10:14

Скажите, зачем добавлять параметры сборки конкретного порта в общесистемный файл конфигурации make? Думаю, что в православии принято указывать параметры в командной строке ключом -D, например -DWITH_MYSQL=yes.
Проблема в том, что строки после сборки обязательно надо поудалять, иначе остальные порты тоже получат эти параметры.

Потёмкин, 2008-08-02 в 15:06:16

Ну вообще-то для /etc/make.conf сделано всё кошерно ибо есть строчка:
.if ${.CURDIR} == ${PORTSDIR}/mail/exim
;) Поэтому остальные порты задевать не должно.

Kolesya, 2008-08-04 в 11:27:30

to glyph
Посмотри внимательно на то что привел Лис :)

PORTSDIR?=              /usr/ports
.if ${.CURDIR} == ${PORTSDIR}/mail/exim
...
.endif

Alexey, 2016-10-27 в 15:21:23

Столкнулся с проблемой, не заводился saslauthd
версия: cyrus-sasl-saslauthd-2.1.26_3

в доках (разные версии) строки подключения такие:
ldap_bind_dn: cn=operator,ou=Profile,o=foo.com
ldap_bind_dn: CN=operator,DC=foo,DC=com

Заработала только строчка
ldap_bind_dn: operator@foo.com



 

  Этот информационный блок появился по той простой причине, что многие считают нормальным, брать чужую информацию не уведомляя автора (что не так страшно), и не оставляя линк на оригинал и автора — что более существенно. Я не против распространения информации — только за. Только условие простое — извольте подписывать автора, и оставлять линк на оригинальную страницу в виде прямой, активной, нескриптовой, незакрытой от индексирования, и не запрещенной для следования роботов ссылки.
  Если соизволите поставить автора в известность — то вообще почёт вам и уважение.

© lissyara 2006-10-24 08:47 MSK

Время генерации страницы 0.0524 секунд
Из них PHP: 42%; SQL: 58%; Число SQL-запросов: 77 шт.
У Вас отключено GZIP-сжатие в браузере. Размер страницы 36800