Интеграция postfix с courier-imap, cyrus-sasl и openldap.


Этот документ является руководством по настройке и установке почтовой
системы для обслуживания нескольких почтовых доменов с возможностью
sasl авторизации и хранением информации об аккаунтах на сервере LDAP.
Информация справедлива для всех *nix системах , где возможна
компиляция и запуск приведенных пакетов.

* 1. Введение.
* 2. Необходимые пакеты.
* 3. Установка пакетов.

1. Введение.

Многие сталкивались с проблемой поддержки и обслуживания почтовых
служб. Многих устраивало стандартное решение MTA + MDA + simple
pop/imap daemon. Да и многие *nix системы при установке предлагают
установить такую простую и удобную (с первого взгляда) систему. Чем
многие и пользуются и вполне успешно. Но к сожалению данное решение не
лишено своих минусов. Назову несколько из них:

1. Повышенная уязвимость системы.

Если есть необходимость иметь открытые ssh и pop3/imap порты в
интернет. Возможна кража пароля, в результате злоумышленник получит
полноценный аккаунт на сервере. В принципе пресекается элементарной
заменой pop3/imap протоколов на их ssl аналоги. Благо почти все
почтовые клиенты умеют с ними работать (и в первую очередь незабвенный
outlook ).

2. Большое количество пользователей.

Создавать 50-200 полноценных аккаунтов только для почты, а потом
контролировать их это головная боль. Причем если вы решите дать эту
возможность другому человеку вам придется дать человеку права
суперпользователя (root).Это только увеличивает дыры в системе. Да и
если не предоставлять полноценные аккаунты можно не беспокоиться о
стойкости паролей к подбору. Максимум что сможет злоумышленник это
прочитать чужую почту и никаких деструктивных действий.

3. Сложность миграции пользователей.

При переходе с одной системы на другую. К примеру с Linux на FreeBSD
или с Slackware на ALT Master (в ALT Master используется отличная от
других Linux дистрибутивов система авторизации).

В целом есть несколько решений данных проблем:
1. MTA with backend -> [ MDA with backend -> ] pop/imap with backend
or sasl support + backend server + cyrus-sasl.
2. MTA with backend -> murder + cyrus-imap + acap server + cyrus-sasl
+ backend server.
3. Active Directory & MS Exchange.
4. Lotus Domino.

Рассмотрим их:
1. Наиболее простой и достаточно удобный если нет необходимости
распределять нагрузку на несколько серверов. Достаточно гибок в
администрировании. В документе рассматривается именно он.
2. Наиболее гибкий с возможностью распределения нагрузки по серверам.
Минус заключается в том что базы по авторизации (backend server
доступ через sasl) и собственно почтовым ящикам (ACAP server)
хранятся в разных местах. В целом это исправимо необходим ACAP
server с backend.
3. Не буду рассматривать в связи отсутствия *nix версии и собственно
толковой документации. Если у вас есть вышлите мне на e-mail буду
благодарен.
4. Коммерческий продукт не разу не видел по этому судить не берусь.

2. Необходимые пакеты.

Нам понадобятся :
* postfix 2.0.12 http://www.postfix.org
* courier-imap 1.7.0 http://www.courier-mta.org
* cyrus-sasl 2.1.13 http://asg.web.cmu.edu/sasl
* OpenLDAP 2.1.21 (или 2.0.x ) http://www.OpenLDAP.org
* Berkeley DB 4.1.25 (необходим только при установке OpenLDAP 2.1.x)
http://www.sleepycat.com

3. Установка пакетов.

Первым необходимо поставить OpenLDAP. Берем тарбол с
http://www.openldap.org/ Распаковываем. Далее запускаем configure с
опциями:

--prefix=/opt/openldap
--enable-syslog --enable-ldap
--enable-slapd --enable-slurpd
--with-tls --enable-wrappers
--enable-rewrite --enable-rlookups
--enable-dynamic --enable-modules

далее make depend all install.

Если все завершилось без ошибок мы получили установленный OpenLDAP
сервер.

note:

В gentoo linux в место этого в командной строке ввести emerge openldap
на выходе получите последний стабильный OpenLDAP сервер.Это касается
так же всех остальных пакетов. Я собирал и испытывал на
работоспособность данную связку именно в этом дистрибутиве.

Теперь привожу рабочие конфиги для OpenLDAP сервера.

note:

приведены только измененные параметры.

ldap.conf

--- start ---

BASE dc=example,dc=com
URI ldap://127.0.0.1

--- end ---

ldap.conf

--- start ---

include /opt/openldap/etc/openldap/schema/core.schema
include /opt/openldap/etc/openldap/schema/cosine.schema
include /opt/openldap/etc/openldap/schema/inetorgperson.schema
include /opt/openldap/etc/openldap/schema/misc.schema
include /opt/openldap/etc/openldap/schema/nis.schema
include /opt/openldap/etc/openldap/schema/openldap.schema
# моя схема в комплект OpenLDAP не входит. Приводится ниже.
include /opt/openldap/etc/openldap/schema/misc-mail.schema
include /opt/openldap/etc/openldap/schema/samba.schema

# разрешить доступ к серверу по протоколу LDAPv2 (только для OpenLDAP версии 2.0.x)
# надо для courier-imap
# и многих других приложений в которых поддержка LDAP протокола заморозилась на v2
allow bind_v2

# дать доступ на запись в ou=mail,dc=example,dc=com
# администраторам из ветки cn=admin,dc=example,dc=com
# и на чтение пользователям:
# ou=mail,ou=services,dc=example,dc=com
# ou=sasl,ou=services,dc=example,dc=com
access to dn=".*,ou=mail,dc=example,dc=com"
by dn=".*,cn=admin,dc=example,dc=com" write
by dn="ou=mail,ou=services,dc=example,dc=com" read
by dn="ou=sasl,ou=services,dc=example,dc=com" read
by self write
by anonymous auth

# дать возможность сменить пароль для пользователей и администраторов
access to attr=userPassword
by self write
by anonymous auth
by dn=".*,cn=admin,dc=example,dc=com" write
by * none

# дать доступ на запись администраторам из ветки
# cn=admin,dc=example,dc=com
access to *
by dn=".*,cn=admin,dc=example,dc=com" write
by self write
by anonymous auth

suffix "dc=example,dc=com"

rootdn "cn=admin,dc=example,dc=com"
rootpw secret

--- end ---



Далее идет схема. Перед использованием прочитайте комментарии в схеме.

misc-mail.schema
--- start ---

Created & modifed by Norguhtar (c) 2003.

############################
# attribute
############################

# old postfix mail address attribute from postfix-courier.schema
#attributetype ( 0.9.2342.19200300.100.5.3
# NAME ( 'postfix-alias' 'postfix-email' )
# DESC 'Postfix virtual mailbox'
# EQUALITY caseIgnoreIA5Match
# SUBSTR caseIgnoreIA5SubstringsMatch
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )


# standart mail address attribute from core.schema included at OpenLDAP 2.1.x version
#attributetype ( 0.9.2342.19200300.100.1.3
# NAME ( 'mail' 'rfc822Mailbox' )
# DESC 'RFC1274: RFC822 Mailbox'
# EQUALITY caseIgnoreIA5Match
# SUBSTR caseIgnoreIA5SubstringsMatch
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )

# standart (from) mail address (for routing forwarding ) attribute from
# misc.schema included at OpenLDAP 2.1.x version

#attributetype ( 2.16.840.1.113730.3.1.13
# NAME 'mailLocalAddress'
# DESC 'RFC822 email address of this recipient'
# EQUALITY caseIgnoreIA5Match
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )


# standart mail host attribute. see description.
# new unique attribute i'm not used this older howto.

#attributetype ( 2.16.840.1.113730.3.1.18
# NAME 'mailHost'
# DESC 'FQDN of the SMTP/MTA of this recipient'
# EQUALITY caseIgnoreIA5Match
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256}
# SINGLE-VALUE )


# old postfix mail forwarding attribute from postfix-courier.schema
#attributetype ( 0.9.2342.19200300.100.5.5
# NAME ( 'postfix-forward' 'postfix-remote-alias')
# DESC 'Postfix forwarding maps'
# EQUALITY caseIgnoreIA5Match
# SUBSTR caseIgnoreIA5SubstringsMatch
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )

# standart mail routing attribute. may be used for forwarding (to)
#attributetype ( 2.16.840.1.113730.3.1.47
# NAME 'mailRoutingAddress'
# DESC 'RFC822 routing address of this recipient'
# EQUALITY caseIgnoreIA5Match
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256}
# SINGLE-VALUE )


# very intresting attribute. This it can used in mail subscribe by members.
# You know any MTA support this ?

#attributetype ( 1.3.6.1.4.1.42.2.27.2.1.15
# NAME 'rfc822MailMember'
# DESC 'rfc822 mail address of group member(s)'
# EQUALITY caseIgnoreIA5Match
# SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

########## courier schema ###############
# Remember ! if you use this schema exclude authldap.schema.

attributetype ( 1.3.6.1.4.1.10018.1.1.2 NAME 'quota'
DESC 'A string that represents the quota on a mailbox'
EQUALITY caseExactIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )

attributetype ( 1.3.6.1.4.1.10018.1.1.3 NAME 'maildrop'
DESC 'The absolute path to the mailbox for a mail account in a non-default location'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )

# use mailHost ?
attributetype ( 1.3.6.1.4.1.10018.1.1.4 NAME 'mailDomain'
DESC 'A virtual mail domain'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

attributetype ( 1.3.6.1.4.1.10018.1.1.5
NAME 'mailTransport'
DESC 'transport for domain'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

attributetype ( 1.3.6.1.4.1.10018.1.1.6
NAME 'mailAccess'
DESC 'Access string'
EQUALITY caseIgnoreIA5Match
SUBSTR caseIgnoreIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

############################
# object class
############################

# old postfix object for mail forwarding.
#objectclass (0.9.2342.19200300.100.5.13
# NAME 'postfix-forward-map'
# DESC 'Postfix forward map'
# SUP top STRUCTURAL
# MUST ( postfix-alias $ postfix-forward ) )
#
# standart object for mail forward.

# object class for routing & forwarding.
# additional information mailHost.
# Can help routing in multi MTA & LDAP server configuration and saves timein search.
# objectclass ( 2.16.840.1.113730.3.2.147
# NAME 'inetLocalMailRecipient'
# DESC 'Internet local mail recipient'
# SUP top STRUCTURAL
# MAY ( mailLocalAddress $ mailHost $ mailRoutingAddress ) )
# warning !!! change AUXILIARY to STRUCTURAL !

#objectclass (0.9.2342.19200300.100.5.12
# NAME 'postfix-alias-map'
# DESC 'Postfix virtual account map'
# SUP top STRUCTURAL
# MUST ( postfix-alias $ postfix-uid $ postfix-gid $ postfix-maildir )
# MAY ( userPassword $ courier-clearPassword $ courier-home $ courier-quota ) )

# object class for full mail account
objectclass ( 1.3.6.1.4.1.10018.1.2.1 NAME 'fullMailAccount' SUP top STRUCTURAL
DESC 'Full mail account object as used by the mail for server recive &storage messages'
MUST ( mail $ maildrop $ uidNumber $ gidNumber )
MAY ( uid $ cn $ description $ quota $ userPassword ) )

# object class for mail account
# others attributes contains in additonal posixAccount.

objectclass ( 1.3.6.1.4.1.10018.1.2.2 NAME 'mailAccount' SUP top STRUCTURAL
DESC 'mail account object as used by the mail for server recive & storage messages'
MUST ( mail $ maildrop )
MAY ( quota ) )

#objectclass (0.9.2342.19200300.100.5.11
# NAME 'postfix-transport-map'
# DESC 'Postfix virtual domain-transport map'
# SUP top STRUCTURAL
# MUST ( postfix-domain $ postfix-transport ) )

# object class for virtual mail domain
# & additional transport table

objectclass ( 1.3.6.1.4.1.10018.1.2.3 NAME 'mailDomainTransport' SUP top STRUCTURAL
DESC 'Domain mail aliasing/transporting entry'
MUST ( mailDomain )
MAY ( mailTransport $ description ) )

# alternate object class
#objectclass ( 1.3.6.1.4.1.10018.1.2.3 NAME 'mailDomainTransport' SUP top STRUCTURAL
# DESC 'Domain mail aliasing/transporting entry'
# MUST ( mailHost )
# MAY ( mailTransport $ description ) )

# additional class object for access network & ip we can got in nis.schema
# ipHost & ipNetwork

# blacklist object class

objectclass ( 1.3.6.1.4.1.10018.1.2.4 NAME 'mailAccess' SUP top STRUCTURAL
DESC 'mail & domain access entry'
MUST ( mail )
MAY ( mailAccess $ description ) )

--- end ---



Теперь несколько ldif файлов для создания используемых веток.

init.ldif

--- start ---

dn: dc=example,dc=com
objectclass: dcObject
objectclass: organization
dc: example
o: LDAP Mail system Inc.
description: Experimental LDAP

dn: cn=admin,dc=example,dc=com
objectclass: organizationalRole
cn: admin

dn: cn=Mail Admin,cn=admin,dc=example,dc=com
objectclass: person
cn: Mail Admin
sn: LDAPmail
description: SysAdmin
userPassword: secret

dn: ou=services,dc=example,dc=com
objectclass: organizationalUnit
ou: services
description: Services entry

--- end ---

mail-misc.ldif

--- start ---

dn: ou=mail,ou=services,dc=example,dc=com
objectclass: organizationalUnit
ou: mail
description: mail service entry
userPassword: password

dn: ou=mail,dc=example,dc=com
objectclass: organizationalUnit
ou: mail
description: mail service tree

dn: ou=domains,ou=mail,dc=example,dc=com
objectclass: organizationalUnit
ou: domains
description: virtual mail domains

dn: ou=transports,ou=mail,dc=example,dc=com
objectclass: organizationalUnit
ou: transports
description: MTA routing table

dn: ou=networks,ou=mail,dc=example,dc=com
objectclass: organizationalUnit
ou: networks
description: MTA network access table

dn: ou=blacklist,ou=mail,dc=example,dc=com
objectclass: organizationalUnit
ou: blacklist
description: MTA blacklist table

dn: ou=spam,ou=mail,dc=example,dc=com
objectclass: organizationalUnit
ou: spam
description: MTA spam table

--- end ---

sasl.ldif

--- start ---

dn: ou=sasl,ou=services,dc=example,dc=com
objectclass: organizationalUnit
ou: sasl
description: sasl daemon service entry
userPassword: sasl password

--- end ---

network.ldif

--- start ---

dn: ipHostNumber=127.0.0.1,ou=networks,ou=mail,dc=example,dc=com
objectclass: ipHost
cn: localhost
ipHostNumber: 127.0.0.1

dn: ipHostNumber=192.168.1.1,ou=networks,ou=mail,dc=example,dc=com
objectclass: ipHost
cn: mail.com
ipHostNumber: 192.168.1.1

--- end ---

virtual.mail.domain.ldif

--- start ---

dn: mailDomain=example.com,ou=domains,ou=mail,dc=example,dc=com
objectclass: mailDomainTransport
mailDomain: example.com
description: example mail domain

dn: mail=example.com,mailDomain=example.com,ou=domains,ou=mail,dc=example,dc=com
objectclass: mailAccount
objectclass: posixAccount
cn: mail account
uid: domain
uidNumber: 2000
gidNumber: 2000
mail: example.com
homeDirectory: no dir for error denied
maildrop: no dir for error denied

dn: mail=postmaster@example.com,mailDomain=example.com,ou=domains,ou=mail,dc=example,dc=com
objectclass: mailAccount
objectclass: posixAccount
cn: standart mail account
uid: postmaster
uidNumber: 2001
gidNumber: 2000
mail: postmaster@example.com
homeDirectory: /var/spool/mail/domains
maildrop: example.com/postmaster/

dn: mail=abuse@example.com,mailDomain=example.com,ou=domains,ou=mail,dc=example,dc=com
objectclass: mailAccount
objectclass: posixAccount
cn: standart mail account
uid: abuse
uidNumber: 2002
gidNumber: 2000
mail: abuse@example.com
homeDirectory: /var/spool/mail/domains
maildrop: example.com/abuse/

dn: mailLocalAddress=root@example.com,mailDomain=example.com,ou=domains,ou=mail,dc=example,dc=com
objectclass: inetLocalMailRecipient
mailLocalAddress: root@example.com
mailRoutingAddress: abuse@example.com
mailHost: example.com

dn: mailLocalAddress=MAILER-DAEMON@example.com,mailDomain=example.com,ou=domains,ou=mail,dc=example,dc=com
objectclass: inetLocalMailRecipient
mailLocalAddress: MAILER-DAEMON@example.com
mailRoutingAddress: postmaster@dexample.com
mailHost: example.com

dn: mail=info@example.com,mailDomain=example.com,ou=domains,ou=mail,dc=example,dc=com
objectclass: mailAccount
objectclass: posixAccount
cn: info mail account
uid: info
uidNumber: 2005
gidNumber: 2000
mail: info@example.com
homeDirectory: /var/spool/mail/domains
maildrop: example.com/info/

--- end ---



В целом мы уже имеем рабочую структуру для домена example.com с
определенными стандартными почтовыми адресами и одним почтовым
аккаунтом info. Почта будет приниматься только с localhost и
192.168.1.1 другим адресам доступ будет запрещен. Далее при описании
конфига для postfix я дам более подробное описание. Не забудьте
запустить slapd! Обычно он лежит в /opt/ldap/sbin.

Следующим устанавливаем cyrus-sasl. Его необходимо собрать с
поддержкой LDAP сервера. Тарбол с исходниками можно взять сдесь
http://asg.web.cmu.edu/sasl. (http://asg.web.cmu.edu/sasl) Распаковываем.
Запускам configure со следующими опциями:

--with-ldap=/opt/ldap --enable-login

далее make all install. После этого делаем как советуют символический
линк

ln -s /usr/local/lib/sasl2 /usr/lib/sasl2

это необходимо для загрузки модулей cyrus-sasl и там же обычно лежат
конфигурационные файлы для приложений использующих cyrus-sasl.

Теперь настроим saslauthd. Это приложение используется cyrus-sasl
библиотекой для авторизации пользователей.

saslauthd.conf

--- start ---

# указываем LDAP сервер в данном случае localhost.

ldap_servers: ldap://127.0.0.1

# указываем пользователя и пароль для авторизации у LDAP сервера.
ldap_bind_dn: ou=sasl,ou=services,dc=example,dc=com
ldap_bind_pw: saslpw
# указываем верси LDAP протокола. OpenLDAP 2.1.x использует 3 версию протокола.
ldap_version: 3
# указываем ветку с пользователями которых требуется авторизовывать.
ldap_search_base: mailDomain=%d,ou=domains,ou=mail,dc=example,dc=com

# указываем метод авторизации custom является наиболее оптимальным,
# он ищет пользователя и проверяет в его аккаунте только его пароль.
# медленная операция bind только одна.
ldap_auth_method: custom
# указываем фильтр
ldap_filter: mail=%U
# можно указать uid=%u
# %U=info@example.com
# %d=example.com
# %u=info

--- end ---



Теперь необходимо запустить в режиме демона saslauthd.

saslauthd -a ldap -O/etc/sasl2/saslauthd.conf

у меня saslauthd.conf лежит /etc/sasl2, если вы положите его в другое
место измените путь.

Теперь мы имеем весь необходимый backend как для авторизации так и
собственно места расположения ящиков, а так же на какие собственно
адреса должен принимать почту MTA.

note:

Описанный backend может быть использован с любым другим MTA и
POP3/IMAP сервером.

Установим postfix. Я использовал postfix 2.0.12 хотя все написанное
справедливо для всех 2.0.x версий. Я брал тарбол с www.postfix.org
поищите наиболее близкое зеркало и скачайте его. Распаковываем. При
сборке postfix не используется configure а свой генератор make файла.
По сему привожу полную команду для получения необходимого результата.

make makefiles CCARGS=" -I/usr/local/include/sasl -DUSE_SASL_AUTH
-I/opt/ldap/include -DHAS_LDAP"
AUXLIBS="-L/opt/ldap/lib -lldap -L/opt/ldap/lib -llber -lsasl2"

После этого добавьте в систему группы postdrop, postfix и пользователя
postfix входящего в группу postfix. От имени их работает postfix.

Далее make all install. Если у вас уже стоит postfix make all upgrade.
После компиляции вам будут заданы вопросы о месторасположении postfix
его конфигурационных файлов и т.п. можно все оставить по умолчанию.
Просто жать enter на все вопросы.

Прежде чем запускать postfix необходимо его сконфигурировать. Ниже я
привожу параметры которые я изменил.

main.cf
--- start ---

# указываю название хоста и домена к которому он принадлежит.
# обычно postfix берет их с помощью gethostname.
# но почему-то в этом случае у меня не правильно отрабатывает
# Dr.web фильтр. Обычно обратный адрес может выглядеть как DRWEB-DAEMON@test.test.com
# Что не есть хорошо.
#
# Да если вы хотите использовать связку для всех доменов в том числе и дляlocal.
# Для него необходимо прописать транспорт virtual в таблицу transports. Поумолчанию для
# него используется local транспорт.

myhostname = test
mydomain = com

# с каких интерфейсов принимать почту
# по умолчанию со всех.
inet_interfaces = all

# допустимые по умолчанию назначения.
# т.е. если у вас нет виртуальных доменов почта принимается только для указанных в этой строке
# доменов.
mydestination = $myhostname.$mydomain, localhost.$mydomain

# проверка существования пользователя только для local.
# Если у вас все домены используют транспорт virtual.
# То она не используется.
local_recipient_maps = unix:passwd.byname $alias_maps

# номер ошибки неизвестный local получатель.
# лучше выставить 550 по умолчанию 450.
unknown_local_recipient_reject_code = 550

# указание стиля доверительной сети.
mynetworks_style = subnet

# указание доверительных сетей без использования LDAP.
# по сути обьявляет разрешает openrelay для mynetworks.
# минимум требуется 127.0.0.0/8 или запись для 127.0.0.1 в OpenLDAP.
#mynetworks = 192.168.0.0/16, 127.0.0.0/8

# тоже самое но с использованием LDAP.
# Обьявить сеть НЕЛЬЗЯ! Только ip адреса
# т.е. для сети 192.168.1.0/24 будет присутствовать
# 254 записи. Зато позволяет производить отключения по IP адресу.

## ldap enable network lookup ##
# так указывается что таблица хранится в LDAP
# ldapnetworks это идентификатор для настроек таблицы.
mynetworks = ldap:ldapnetworks

# настройки таблицы ldapnetworks
# LDAP сервер localhost
ldapnetworks_server_host = 127.0.0.1

# ветвь поиска.
ldapnetworks_search_base = ou=networks,ou=mail,dc=example,dc=com

# фильтр
ldapnetworks_query_filter = (ipHostNumber=%s)

# необходимый аттрибут.
ldapnetworks_result_attribute = ipHostNumber

# глубина поиска. В для ip адресов я использую flat модель т.е. все ip адреса лежат ниже
# ветви поиска на 1. Для экономии времени поиска указываю вложенность поиска один.
ldapnetworks_scope = one

# параметры авторизации пользователя.
# ВНИМАНИЕ ! Пароль хранится в открытом виде main.cf должен быть доступен на чтение для
# sendmail. Не храните в LDAP пароли пользователей в открытом виде. А так же не давайте
# права на запись пользователю от которого работает postfix.
ldapnetworks_bind_dn = ou=mail,ou=services,dc=example,dc=com
ldapnetworks_bind_pw = password

# определяет ограничения для пересылки.
# По умолчанию postfix является close relay что очень хорошо.
# К примеру sendmail является по умолчанию open relay.
# По крайней мере в RH 6.0 =).

relay_domains = $mydestination, $transport_maps

## ldap client access ##
# ограничение на вызов комманды ETRN
# ldap:ldapblacklist - таблица с ограничениями вида mail - что ограничивать см. pcre_table и
# regexp_table
# это относится к 2 следующим строкам.
# smtp_etrn_restrictions = permit_mynetworks,check_client_access ldap:ldapblacklist,reject
# smtpd_client_restrictions = permit_mynetworks,check_client_access ldap:ldapblacklist,reject

# собственно часть описывающая blacklist
#ldapblacklist_server_host = 127.0.0.1
#ldapblacklist_search_base = ou=blacklist,ou=mail,dc=example,dc=com
#ldapblacklist_query_filter = (mail=%s)
#ldapblacklist_result_attribute = mailAccess
#ldapblacklist_scope = one
#ldapblacklist_bind_dn = ou=mail,ou=services,dc=example,dc=com
#ldapblacklist_bind_pw = password

## ldap sender access ##
# описывает отсечение по from полю (по отправителю).
#smtpd_sender_restrictions = permit_mynetworks,check_sender_access ldap:ldapspam,reject_unknown_sender_domain
# note: приведенная строка не отвечает rfc, если необходимо соответствие то уберите последнюю строку.
# Далее будет приведена раскомментированная строка удовлетворяющая требованием rfc.
#ldapspam_server_host = 127.0.0.1
#ldapspam_search_base = ou=spam,ou=mail,dc=example,dc=com
#ldapspam_query_filter = (mail=%s)
#ldapspam_result_attribute = mailAccess
#ldapspam_scope = one
#ldapspam_bind_dn = ou=mail,ou=services,dc=example,dc=com
#ldapspam_bind_pw = password

# запрещение выполнение команды ETRN для внешнего мира.
smtp_etrn_restrictions = permit_mynetworks,reject

### sasl ###
# собственно описание snmp авторизации с использованием sasl.
# включаем sasl
smtpd_sasl_auth_enable = yes
# разрешаем принимать почту от нашей сети, от авторизованных и если получатель принадлежит нашему домену.
smtpd_recipient_restrictions =permit_mynetworks,permit_sasl_authenticated,permit_auth_destination, reject
# разрешаем нашу сеть и запрещаем получение почты с безымянных хостов (известен только ip).
smtpd_client_restrictions = permit_mynetworks, reject_unknown_client
# запрет с использованием rbl базы. Можно добавить в конец определения.
#reject_rbl_client relays.ordb.org
# разрешить HELO комманду для локальных сетей и авторизованных клиентов и замыкающий запрет.
smtpd_helo_restrictions = permit_mynetworks, permit_sasl_authenticated, reject
# запрет с помощью rbl базы.
#, reject_rbl_client relays.ordb.org

# Отключение анонимной авторизации.
smtpd_sasl_security_options = noanonymous

## non sasl ##
# тоже самое но без sasl авторизации но с rbl.
#smtpd_client_restrictions = permit_mynetworks, reject_rbl_client relays.ordb.org
#smtpd_recipient_restrictions =permit_mynetworks, permit_auth_destination,reject
#smtpd_helo_restrictions = permit_mynetworks, reject_rbl_client relays.ordb.org

# для работы с сервером требуется команда HELO
smtpd_helo_required = yes

# разрешить нашу сеть и запретить принимать почту не имеющих A или MX записи.
# внимание запрет приема с хостов не имеющих A или MX записи не соответствует rfc!
# подумайте стоит ли вам использовать ее.
smtpd_sender_restrictions = permit_mynetworks, reject_unknown_sender_domain

# задержка в приеме почты если очередь уже полна.
# например если очередь уже полна (50 сообщений к примеру)
# когда очередь уменьшится до 49 пройдет еще секунда когда
# сервер поставит в очередь новое сообщение.
in_flow_delay = 1s

# максимальное время жизни письма.
# если в течении 5 часов сервер не достучится сервера адресата.
# письмо вернется отправителю. По умолчанию стоит 5 дней.
maximal_queue_lifetime = 5h

# лимиты на размер сообщения и ящика.
message_size_limit = 5240000
mailbox_size_limit = 12000000
# На виртуальные ящики лимиты выставляются отдельно.

# указываем базовый путь где лежат ящики.
virtual_mailbox_base = /var/spool/mail/domains
# указываем список виртуальных доменов.
# сначала проверяется соответствие есть ли такой домен.
# для доменов в этом параметре используется транспорт virtual.
# если вы хотите сделать локальный домен виртуальным
# пропишите его в транспортную таблицу как виртуальный.
virtual_mailbox_domains = ldap:ldapdomains

# описание где взять в LDAP домены и с какого сервера взять.
ldapdomains_server_host = 127.0.0.1
ldapdomains_search_base = ou=domains,ou=mail,dc=example,dc=com
ldapdomains_query_filter = (mailDomain=%s)
ldapdomains_result_attribute = mailDomain
ldapdomains_scope = one
ldapdomains_bind_dn = ou=mail,ou=services,dc=example,dc=com
ldapdomains_bind_pw = password

# собственно указывает куда ложить почту в базовом пути.
virtual_mailbox_maps = ldap:ldapmaildrops

ldapmaildrops_server_host = 127.0.0.1
ldapmaildrops_search_base = ou=domains,ou=mail,dc=example,dc=com
ldapmaildrops_query_filter = (mail=%s)
ldapmaildrops_result_attribute = maildrop
ldapmaildrops_bind_dn = ou=mail,ou=services,dc=example,dc=com
ldapmaildrops_bind_pw = password

# виртуальные форвардинги
virtual_alias_maps = ldap:ldapmailforwards

ldapmailforwards_server_host = 127.0.0.1
ldapmailforwards_search_base = ou=domains,ou=mail,dc=example,dc=com
ldapmailforwards_query_filter = (mailLocalAddress=%s)
ldapmailforwards_result_attribute = mailRoutingAddress
ldapmailforwards_bind_dn = ou=mail,ou=services,dc=example,dc=com
ldapmailforwards_bind_pw = password

# uid используемый для выставления прав на ящик
virtual_uid_maps = ldap:ldapuids

ldapuids_server_host = 127.0.0.1
ldapuids_search_base = ou=domains,ou=mail,dc=example,dc=com
ldapuids_query_filter = (mail=%s)
ldapuids_result_attribute = uidNumber
ldapuids_bind_dn = ou=mail,ou=services,dc=example,dc=com
ldapuids_bind_pw = password

# gid используемый для выставления прав на ящик
virtual_gid_maps = ldap:ldapgids

ldapgids_server_host = 127.0.0.1
ldapgids_search_base = ou=domains,ou=mail,dc=example,dc=com
ldapgids_query_filter = (mail=%s)
ldapgids_result_attribute = gidNumber
ldapgids_bind_dn = ou=mail,ou=services,dc=example,dc=com
ldapgids_bind_pw = password

# лимит размера для виртуальных ящиков.
virtual_mailbox_limit = 12000000

# указываем что транспортная таблица лежит в LDAP.
transport_maps = ldap:ldaptransport

ldaptransport_server_host = 127.0.0.1
ldaptransport_search_base = ou=transports,ou=mail,dc=example,dc=com
ldaptransport_query_filter = (mailDomain=%s)
ldaptransport_result_attribute = mailTransport
ldaptransport_scope = one
ldaptransport_bind_dn = ou=mail,ou=services,dc=example,dc=com
ldaptransport_bind_pw = password

# локальные форвардинги.
alias_maps = hash:/etc/mail/aliases
alias_database = hash:/etc/mail/aliases
# указываем почтовый ящик в home папке для local транспорта.
home_mailbox = .maildir/

# баннер выводимый системой при подключении.
# mail_version и mail_name лучше выключить или фальсифицировать.
smtpd_banner = $myhostname ESMTP $mail_name ($mail_version)

# лимит на количество параллельных процессов отправления локальным получателям.
# рекомендовано ставить 2.
local_destination_concurrency_limit = 2
# лимит на количество параллельных процессов отправления по умолчанию.
default_destination_concurrency_limit = 10

--- end ---



Проверим все ли правильно и все ли есть. postfix check

Если после выполнения ничего не вывелось значит все указано и описано
правильно можно запускать.Запускаем postfix:

postfix start

Теперь мы получили систему готовую принимать почту. Теперь некоторые
нюансы по созданию каталогов виртуальных доменов. Допустим у нас
группа пользователей для домена example.com имеет gid 2000.

Права должны иметь вид:

rwxrwx-- mail.2000 example.com

т.е. данная группа должна иметь право доступа на запись в этот
каталог. Тогда почта будет приниматься, а заведенным пользователям при
получении 1 письма будет создаваться ящик.

Теперь осталось немного, настроить courier-imap. Взять последнюю
версию можно с http://www.courier-mta.org. (http://www.courier-mta.org/) Выкачиваем тарбол.
Распаковываем и запускаем configure со следующими аргументами:

--prefix=/opt/courier-imap --with-authldap --disable-root-check
--enable-workarounds-for-imap-client-bugs далее запускаем make all
install.

note:

если courier-imap не найдет у вас openldap наберите configure --help
там указано как выставить дополнительные пути для поиска заголовочных
файлов и библиотек.

После завершения процесса инсталляции необходимо сконфигурировать
демон авторизации courier-imap для работы с ldap. Ниже привожу те
параметры которые я изменил в конфиге демона. Конфиги лежат в
/opt/courier-imap/etc если вы собирали courier-imap с указанными выше
параметрами.

authdaemond.conf
--- start ---
# указываем что для авторизации будет использоваться демон с ldap
AUTHDAEMOND="authdaemond.ldap"

--- end ---

authdaemonrc
--- start ---

# перечисление какие модули необходимо проверять при попытки авторизации
# сейчас включены LDAP и PAM (PAM гибче но его тонкая настройка это отдельный документ).
authmodulelist="authldap authpam"

# используется только courier webmin модулем. Должен содержать только один модуль.
authmodulelistorig="authldap"

# количество запускаемых процессов обслуживающих авторизацию
# заявлено что этого количества достаточно. Если же их окажется мало
# рекомендуется проверить общую загрузку системы.
daemons=5

# какая версия демона используется.
version="authdaemon.ldap"

# не изменяйте этот параметр он используется различными конфигурационными и
# собирающими скриптами (цитата из примечания к параметру).
authdaemonvar=/var/lib/courier-imap/authdaemon

--- end ---

authldaprc
--- start ---
# указываем ip и порт сервера.
LDAP_SERVER 127.0.0.1
LDAP_PORT 389

# указываем базу поиска
LDAP_BASEDN ou=domains,ou=mail,dc=example,dc=com

# указываем пользователя и пароль с которыми подключаемся к LDAP.
LDAP_BINDDN ou=mail,ou=services,dc=example,dc=com
LDAP_BINDPW password

# включает биндинг в LDAP для авторизации пользователя.
# NOTE: должен быть включен! иначе не будет проходить авторизация.
LDAP_AUTHBIND 1

# собственно поле для поиска
LDAP_MAIL mail

# домен по умолчанию
# означает если вы подключаетесь с именем пользователя
# без указания домена то в качестве домена берется этот.
LDAP_DOMAIN exampe.com

# указываем домашнюю директорию пользователя
# (обычно это всегда одинаковая строка virtual_mailbox_base в
# postfix )
LDAP_HOMEDIR homeDirectory
# собствнно куда складываем почту
LDAP_MAILDIR maildrop
# uid и gid пользователя
LDAP_UID uidNumber
LDAP_GID gidNumber
# у меня tls отключен. И у меня на сервере не включен.
LDAP_TLS 0
--- end ---



Копируем pop3d.dest и imapd.dest в pop3d и imapd соответственно.
Остальные параметры я не изменял если вам что-то надо измените сами.
Теперь торжественный запуск последней части системы. ищем в каталоге
courier-imap скрипт pop3d.rc или еще что-то в этом духе и запускаем
его для запуска POP3 сервера. IMAP сервер запускается подобным же
скриптом. Из каждого из этих скриптов при не обнаружении auth демона
он запускается, но при выключении pop3 сервера при помощи скрипта он
не выключается.

В результате мы получили готовую к работе почтовую систему. С высокой
степени гибкости и динамичности. Если необходим web интерфейс к данной
почтовой системы я советую использовать sqwebmail как наиболее простое
в интеграции в систему средство.

Любые замечания и дополнения и пожелания приветствуются.

© Анатолий Шипицын aka Norguhtar (mail: sauron at infocentr dot ru).

Обновлено: 13.03.2015