Статьи‎ > ‎

Установка почтового сервера (postfix + dovecot) с авторизацией в Active Directory

*** НЕЗАВЕРШЁННАЯ СТАТЬЯ ***
Казалось бы, сколько уже написано заметок, статей и даже книг на тему настройки почтового сервера - всё уже разжёвано и ничего нового уже написать нельзя, а мне вот почему-то пришлось многие вещи додумывать самостоятельно - не удалось найти более-менее подробной инструкции для желаемой задачи.
Итак, что мы имеем:

  • почтовый сервер под управлением CentOS 6

  • домен Active Directory (в моём случае - SAMBA4 в режиме AD)

  • адреса email пользователей не совпадают с их именами авторизации (то есть у пользователя user@domain.lan может быть адрес office@firm.ru)

  • для доступа к почте предполагается использовать как почтовые клиенты, так и web-интерфейс

Исходя из вышеизложенного, мной были сформулированы задачи:

  • хранение почтовых баз и доступ к ящикам должен быть по протоколу imap (извне - с использованием шифрования)

  • авторизация пользователей почты по доменным учётным записям (внутри сети - без указания пароля, используя SSO/GSSAPI)

  • необходима реализация групп рассылок (когда письмо, отправленное на sales@firm.ru будет доставлено сразу нескольким получателям внутри домена)

  • наличие адресной книги предприятия

  • по возможности, не вносить никаких изменений в схему домена для обеспечения максимальной совместимости

  • естественно, почтовый сервер должен отвечать основным требованиям к почтовым серверам

Как была решена поставленная задача:

  • в качестве почтового сервера была выбрана связка из postfix (MTA) и dovecot (MDA/MRA)

  • авторизация была реализована по двум алгоритмам - авторизация ldap-пользователем в ldap AD при доступе извне и авторизация Kerberos/GSSAPI при доступе из локального домена

  • для сопоставления адресов электронной почты пользователям было использовано стандартное поле email (кроме того, можно использовать стандартное, но не отображаемое в оснастках AD поле otherMailbox - актуально для пользователей, имеющих адреса в двух почтовых доменах)

  • для организации групп рассылок использованы "Группы распространения" (Distribution Groups) Active Directory - их же было решено использовать как псевдонимы (aliases) для пользователей, нуждающихся в получении писем более чем с одного (двух) адреса

  • глобальная адресная книга реализована путём чтения списка пользователей домена с фильтрацией по типам записей

  • в качестве web-интерфейса использован Roundcube

Итак, что мы делаем
1. Устанавливаем необходимые пакеты - так как postfix уже установлен, ставим dovecot и openssl (потребуется для организации шифрования) командой yum install dovecot openssl
2. Генерируем сертификаты для dovecot и postfix (не буду повторяться - недавно уже описывал эту процедуру) - единственное, уточню, что сертификаты я поместил в /etc/pki/dovecot и /etc/pki/postfix, а ключи - в соответствующие вложенные каталоги private, чтобы обеспечить возможность ограничения доступа к ним.
3. Создаём служебную учётную запись пользователя для чтения атрибутов пользователей почты из AD - права минимальные, достаточно Domain Users - для определённости я его назвал ldapbind
4. Настраиваем dovecot:
Создаём файл параметров ldap в /etc/dovecot/dovecot-ldap.conf.ext следующего содержания:

# Два контроллера AD через пробел; к первому обращаемся по порту 3268 (как рекомендовано в wiki dovecot)
# ко второму - по стандартному порту (389) - тоже работает
hosts = dc1.test.lan:3268 dc2.test.lan
# Имя служебного пользователя для чтения параметров из AD - можно указывать как в нотации ldap, так и в
# любой нотации AD, учитывая, что символ "\" следует экранировать
dn = ldapbind@test.lan
# Пароль служебного пользователя для чтения параметров (***уточнить - можно ли помещать хэш)
dnpass = FidoNet-2-5020-2068
# Авторизацию будем пытаться провести с учётными данными пользователя почты
auth_bind = yes
# Формат имени пользователя - преобразуем всё в нижний регистр
auth_bind_userdn = %Lu
# Версия ldap
ldap_version = 3
# Базовый DN домена, начиная с которого будем искать пользователей - лучше максимально сузить
# base = ou=Users,ou=Office,dc=test,dc=lan
base = dc=test,dc=lan
# Не разбирался с этим параметром - оставил из шаблона
deref = finding
# Поиск вести по всем вложенным объектам, начиная с "base"
scope = subtree
# Искать только пользователей (805306368), у которых совпадает с переданным логином либо
# логин (userPrincipalName) - для входа по IMAP, либо mail - для локальной доставки
user_filter = (&(sAMAccountType=805306368)(|(userPrincipalName=%Lu)(mail=%Lu)))
# Крайне важный параметр - расположение домашнего каталога (home) - "%$" будет заменено
# на значение поля "userPrincipalName" найденного пользователя, содержащее в AD "логин@домен"
user_attrs = userPrincipalName=home=/var/vmail/%$
# Фильтр пользователей - отдавать только активных пользователей
pass_filter = (&(sAMAccountType=805306368)(userPrincipalName=%Lu))
pass_attrs = userPrincipalName=user

На данный файл ссылается файл конфигурации /etc/dovecot/conf.d/auth-ldap.conf.ext - его оставляем без изменений:

passdb {
  driver = ldap
  args = /etc/dovecot/dovecot-ldap.conf.ext
}
userdb {
  driver = ldap
  args = /etc/dovecot/dovecot-ldap.conf.ext
}

А файл настройки параметров авторизации /etc/dovecot/conf.d/auth-ldap.conf.ext приводим к такому виду:

auth_username_format = %Lu
auth_gssapi_hostname = "$ALL"
auth_krb5_keytab = /etc/dovecot/dovecot.keytab
auth_use_winbind = no
auth_winbind_helper_path = /usr/bin/ntlm_auth
auth_failure_delay = 2 secs
auth_mechanisms = gssapi plain gss-spnego
!include auth-ldap.conf.ext

Следующим этапом правим /etc/dovecot/conf.d/10-mail.conf до такого состояния:

# Здесь указываем, что почта располагается в "домашнем" каталоге пользователя
# (устанавливается параметром user_attrs в dovecot-ldap.conf.ext)
mail_location = maildir:%h
# Имя и группа (системные, unix) владельца каталога почтовых баз
mail_uid = mail
mail_gid = mail
# Минимальные разрешённые UID и GID, которым разрешён доступ к почтовым базам -
# должны быть не более соответствующих значений предыдущих параметров
first_valid_uid = 5
first_valid_gid = 5
mbox_write_locks = fcntl

Теперь указываем расположение ключа шифрования и сертификата ssl для установления безопасных соединений, при необходимости - с паролем доступа к ключу:

ssl_cert = </etc/pki/dovecot/dovecot.pem
ssl_key = </etc/pki/dovecot/private/dovecot.pem
ssl_key_password = FidoNode-2-5020-116

Теперь надо настроить сокет авторизации для postfix - для этого в файле /etc/dovecot/conf.d/10-master.conf находим раздел service auth и приводим его к такому виду:

service auth {
  unix_listener auth-userdb {
  }

  unix_listener /var/spool/postfix/private/auth {
    mode = 0600
    user = postfix
    group = postfix
  }

}

И, наконец, запускаем dovecot. В моём случае /etc/dovecot/dovecot.conf имеет следующее содержимое, но на самом деле его можно вообще не модифицировать, т.к. все параметры имеют значения по умолчанию:

protocols = imap pop3 lmtp
listen = *
base_dir = /var/run/dovecot/
login_greeting = Dovecot ready.
dict {
}
!include conf.d/*.conf

Если при запуске система ругается на неизвестный протокол или сервис семейства sieve, правим /etc/dovecot/conf.d/20-managesieve.conf - либо комментируем проблемные записи, либо настраиваем в соответствии со своими требованиями (в моём случае данные расширения не использовались и я закомментировал "лишние" разделы).
5. Настраиваем postfix:
В моём случае /etc/postfix/main.cf подвергся минимальной модификации и имеет следующее содержание:

queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
data_directory = /var/lib/postfix
mail_owner = postfix
# Здесь я указал FQDN сервера, которым он будет "представляться" при получении и отправке почты
# следует указать имя, соответствующее ptr-записи в rdns провайдера для внешнего IP
myhostname = mailserv.domain.tld
inet_interfaces = all
inet_protocols = all
# Следует учесть, что в данном параметре не должно быть доменов из virtual_mailbox_domains
mydestination = $myhostname, localhost.$mydomain, localhost
unknown_local_recipient_reject_code = 550
# Здесь перечислены домены, для которых postfix принимает почту
# так как схема AD не имеет расширений, список доменов прочесть не откуда
virtual_mailbox_domains =  bubnov.su  eahv.ru
# Здесь указываем дополнительные файлы настроек для пользователей почты и групп
virtual_mailbox_maps = ldap:/etc/postfix/ldap/local_recipients.cf
virtual_alias_maps = ldap:/etc/postfix/ldap/mailgroups.cf
# Указатель на сокет dovecot для локальной доставки писем
virtual_transport = lmtp:unix:/var/run/dovecot/lmtp
# Параметры шифрования
smtpd_tls_cert_file = /etc/pki/postfix/postfix.pem
smtpd_tls_key_file = /etc/pki/postfix/private/postfix.pem
smtpd_tls_loglevel = 0
smtpd_use_tls = yes
# По идее, эта опция запрещает авторизацию без TLS (у меня не запретила)
smtpd_tls_auth_only = yes
# Прописываем правила, ограничивающие отправителей
smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination, reject_non_fqdn_sender, reject_unknown_sender_domain, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, check_helo_access
submission_recipient_restrictions = reject_non_fqdn_sender, reject_non_fqdn_recipient, permit_sasl_authenticated, permit_mynetworks, reject
smtpd_restriction_classes = submission_recipient_restrictions
# Включаем авторизацию
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes
smtpd_sasl_type = dovecot
# Расположение сокета dovecot для авторизации
smtpd_sasl_path = private/auth
smtpd_sasl_local_domain =  $myorigin
# Запрещаем авторизованным пользователям отправлять письма с "чужого" адреса
smtpd_sender_restrictions=reject_authenticated_sender_login_mismatch
# Указываем файл параметров проверки принадлежности адреса пользователю
smtpd_sender_login_maps = ldap:/etc/postfix/ldap/senderlogin.cf
# Вместо указания параметров в отдельном файле, postfix позволяет указать все настройки
# в основном файле конфигурации, используя префикс
#smtpd_sender_login_maps = ldap:senderlogin
#senderlogin_server_host = dc1.test.lan:3268
#senderlogin_version = 3
#senderlogin_debuglevel = 3
#senderlogin_search_base = dc=test,dc=lan
#senderlogin_query_filter = (&(|(mail=%s)(userPrincipalName=%u@%d))(sAMAccountType=805306368))
# senderlogin_result_attribute = mail
#senderlogin_result_attribute = userPrincipalName
#senderlogin_bind = yes
#senderlogin_bind_dn = ldapbind@test.lan
#senderlogin_bind_pw = FidoNet-2-5020-2068

# Неиспользуемые параметры - остались от оригинального файла конфигурации
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
debugger_command =
         PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
         ddd $daemon_directory/$process_name $process_id & sleep 5
sendmail_path = /usr/sbin/sendmail.postfix
newaliases_path = /usr/bin/newaliases.postfix
mailq_path = /usr/bin/mailq.postfix
setgid_group = postdrop
html_directory = no
manpage_directory = /usr/share/man
sample_directory = /usr/share/doc/postfix-2.6.6/samples
readme_directory = /usr/share/doc/postfix-2.6.6/README_FILES

Далее разрешаем в /etc/postfix/master.cf протокол SMTPS, снимая комментарий со строчек:

smtps     inet  n       -       n       -       -       smtpd
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject

и приступаем к настройке взаимодействия с AD по протоколу LDAP. Как несложно понять из содержимого "main.cf", нам потребуется три файла - это /etc/postfix/ldap/local_recipients.cf следующего содержания:

debuglevel = 0
version = 3
server_host = ldap://dc1.test.lan:3268
bind_dn = ldapbind@test.lan
bind_pw = FidoNet-2-5020-2068
search_base = dc=test,dc=lan
search_scope = subtree
query_filter = (&(|(mail=%s)(otherMailbox=%u@%d))(sAMAccountType=805306368))
result_attribute = mail
cache = no

и /etc/postfix/ldap/mailgroups.cf такого содержания:

debuglevel = 0
version = 3
server_host = ldap://dc1.test.lan
bind = yes
bind_dn = ldapbind@test.lan
bind_pw = FidoNet-2-5020-2068
search_base = dc=test,dc=lan
timeout = 3
query_filter = (&(mail=%s)(sAMAccountType=268435457))
result_filter = %s
result_attribute = mail
special_result_attribute = member
scope = sub

а для проверки принадлежности предъявленного адреса отправителя авторизовавшемуся пользователю, будет использоваться файл /etc/postfix/ldap/senderlogin.cf такого содержания:

debuglevel = 0
version = 3
server_host = dc1.test.lan:3268
bind = yes
bind_dn = ldapbind@test.lan
bind_pw = FidoNet-2-5020-2068
search_base = dc=test,dc=lan
query_filter = (&(|(mail=%s)(otherMailbox=%s))(sAMAccountType=805306368))
result_attribute = userPrincipalName

В этих файлах настраиваются параметры авторизации в доменном ldap AD; параметр server_host может быть указан как с префиксом "ldap://", так и без него, равно как и порт ldap-сервера может быть указан в явном виде, а при отсутствии такого указания, соединение будет установлено по стандартному порту (389); параметр bind_dn также принимается сервером AD как в виде "ldapbind@test.lan", так и в виде "TEST\ldapbind" и в виде "cn=ldapbind,ou=Robots,dc=test,dc=lan" - в приведённом примере пользователь "ldapbind" помещён в "подразделение" (Organisation Unit) "Robots", располагающееся в корне домена "test.lan". Наиболее удобна нотация "ldapbind@test.lan", так как в ней отсутствует требующий "экранирования" символ обратной косой черты (\), и нет жёсткой привязки к расположению пользователя в структуре домена.
Всё. На данном этапе уже можно пользоваться почтовым сервером. Из поставленных задач не реализованы только web-интерфейс и беспарольная авторизация (через Kerberos GSSAPI).
*** НЕЗАВЕРШЁННАЯ СТАТЬЯ ***

Comments