мини-howto по Postfix+LDAP

Обсуждение настройки и работы сервисов, резервирования, сетевых настроек и вопросов безопасности ОС.

Модераторы: SLEDopit, Модераторы разделов

Аватара пользователя
strah
Сообщения: 283
ОС: Freebsd, linux, Solaris.

мини-howto по Postfix+LDAP

Сообщение strah »

Вот, решил написать мини-howto по Postfix'у и openldap'у, может кому и пригодится...

Введение
Итак, имеем следующую схему: есть Postfix, который должен хранить всю информацию по виртуальным пользователям в LDAP. LDAP сервер в моем примере работает под управлением FreeBsd 7.0, с openldap-server-2.4.8 в качестве LDAP-сервера. Postfix (2.3.8-2) работает под управлением Debian Linux (4.0). Все вместе это крутится на Vmware-server 1.0.7 (так-как доступа к компам, акромя домашнего не имею).

Настройка openldap
Итак, нам надо настроить openldap так, чтобы он мог хранить информацию о ящиках пользавателей, алиасах, и тд. Для этого сначала надо написать соответствующую схему, в стандартных схемах не определены многие необходимые атрибуты. Например, я использую следующую схему, под названием mail.schema:

Код:

#mail.schema ######### # 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 organizationalPerson 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 ) )


Теперь нам надо настроить slapd.conf, и ldap.conf.

Код:

#/usr/local/etc/openldap/slapd.conf # # See slapd.conf(5) for details on configuration options. # This file should NOT be world readable. # include /usr/local/etc/openldap/schema/core.schema include /usr/local/etc/openldap/schema/misc.schema include /usr/local/etc/openldap/schema/mail.schema # Define global ACLs to disable default read access. # Do not enable referrals until AFTER you have a working directory # service AND an understanding of referrals. #referral ldap://root.openldap.org pidfile /var/run/openldap/slapd.pid argsfile /var/run/openldap/slapd.args # Load dynamic backend modules: modulepath /usr/local/libexec/openldap moduleload back_bdb # moduleload back_hdb # moduleload back_ldap # Sample security restrictions # Require integrity protection (prevent hijacking) # Require 112-bit (3DES or better) encryption for updates # Require 63-bit encryption for simple bind # security ssf=1 update_ssf=112 simple_bind=64 # Sample access control policy: # Root DSE: allow anyone to read it # Subschema (sub)entry DSE: allow anyone to read it # Other DSEs: # Allow self write access # Allow authenticated users read access # Allow anonymous users to authenticate # Directives needed to implement policy: # access to dn.base="" by * read # access to dn.base="cn=Subschema" by * read # access to * # by self write # by users read # by anonymous auth # # if no access controls are present, the default policy # allows anyone and everyone to read anything but restricts # updates to rootdn. (e.g., "access to * by * read") # # rootdn can always read and write EVERYTHING! ####################################################################### # BDB database definitions ####################################################################### database bdb directory /var/db/ldap/local.net suffix "dc=local,dc=net" rootdn "cn=ldapadmin,dc=local,dc=net" rootpw {SSHA}gtnZ2mIrPlSD5E9EsrT3xelxYxCfE1PA index objectClass eq index cn eq,sub index sn eq,sub access to attrs=userPassword by * auth ######################## #/usr/local/etc/openldap/ldap.conf # # LDAP Defaults # # See ldap.conf(5) for details # This file should be world readable but not world writable. BASE dc=local,dc=net URI ldap://127.0.0.1 #SIZELIMIT 12 #TIMELIMIT 15 #DEREF never


Запускаем slapd:

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

echo "spald_enable="YES" >> /etc/rc.conf
/usr/local/etc/rc.d/slapd start


После этого создаем ldif-файл следующего содержания:

Код:

#base.ldif dn: dc=local,dc=net objectClass: dcObject objectClass: organizationalUnit ou: Bell labs dc: local dn: ou=peoples,dc=local,dc=net objectClass: organizationalUnit ou: peoples dn: ou=it,ou=peoples,dc=local,dc=net objectClass: organizationalUnit ou: it description: IT workers dn: ou=managers,ou=peoples,dc=local,dc=net objectClass: organizationalUnit ou: managers description: All other workers dn: cn=Denis,ou=it,ou=peoples,dc=local,dc=net objectClass: mailAccount mail: denis@mail.local.net maildrop: denis/ cn: Denis sn: Vasiljev dn: cn=Peta,ou=managers,ou=peoples,dc=local,dc=net objectClass: mailAccount mail: peta@mail.local.net maildrop: peta/ cn: Peta sn: Pupkin


И добавляем данные записи в базу.

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

ldapadd -x -W -D "cn=ldapamin,dc=local,dc=net" -f base.ldif

Если все прошло без ошибок, тогда пробуем прочитать данные из базы

Код:

%ldapsearch -x -W -D "cn=ldapadmin,dc=local,dc=net" "(objectClass=mailAccount)" Enter LDAP Password: # extended LDIF # # LDAPv3 # base <dc=local,dc=net> (default) with scope subtree # filter: (objectClass=mailAccount) # requesting: ALL # # Denis, it, peoples, local.net dn: cn=Denis,ou=it,ou=peoples,dc=local,dc=net objectClass: mailAccount mail: denis@mail.local.net maildrop: denis/ cn: Denis sn: Repkov # Peta, managers, peoples, local.net dn: cn=Peta,ou=managers,ou=peoples,dc=local,dc=net objectClass: mailAccount mail: peta@mail.local.net maildrop: peta/ cn: Peta sn: Pupkin # search result search: 2 result: 0 Success # numResponses: 3 # numEntries: 2


Настройка Postfix
Создаем следующий /etc/postfix/main.cf

Код:

myorigin = $myhostname myhostname = mail.local.net smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU) biff = no # appending .domain is the MUA's job. append_dot_mydomain = no # Uncomment the next line to generate "delayed mail" warnings #delay_warning_time = 4h # TLS parameters smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key smtpd_use_tls=yes smtpd_tls_session_cache_database = btree:${queue_directory}/smtpd_scache smtp_tls_session_cache_database = btree:${queue_directory}/smtp_scache # See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for # information on enabling SSL in the smtp client. #максимальный размер сообщения - 3мб message_size_limit = 3145728 alias_maps = hash:/etc/aliases alias_database = hash:/etc/aliases mynetworks = 127.0.0.0/8 192.168.100.0/25 inet_interfaces = all #почта для пользователей из /etc/passwd mydestination = localhost mailbox_command = procmail -a "$EXTENSION" #максимальный размер ящика - 20мб mailbox_size_limit = 20971520 recipient_delimiter = + #почта для виртуальных пользователей virtual_mailbox_domains = $myhostname virtual_mailbox_maps = ldap:/etc/postfix/virtual-mbox.cf virtual_mailbox_base = /var/mail/virtual virtual_uid_maps = static:1999 virtual_gid_maps = static:1999 #максимальный размер ящика - 20мб virtual_mailbox_limit = 20971520


Теперь создаем /etc/postfix/virtual/mbox.cf, в котором описывается подключение к LDAP-серверу, ключи поиска, поле результата и тд (подробнее можно узнать по [i]man ldap_table[i]

Код:

#по умолчанию используется вторая версия version = 3 server_host = ldap://192.168.100.69 search_base = dc=local,dc=net query_filter = (&(mail=%s)(objectClass=mailAccount)) result_attribute = maildrop bind_dn = cn=ldapadmin,dc=local,dc=net bind_pw = gmzyyfz


Теперь проверяем правильность вышеописанного файла при помощи postmap:

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

/usr/sbin/postmap -q denis@mail.local.net ldap:/etc/postfix/virtual-mbox.cf
denis/


Теперь создаем системного пользователя, кому будут принадлежать все ящики виртуальных пользователей:

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

sudo /usr/sbin/addgroup --system --gid 1999 vmailgroup
sudo /usr/sbin/adduser --system --no-create-home --uid 1999 --ingroup vmailgroup vmailuser

sudo mkdir /var/mail/virtual
sudo chown vmailuser:vmailgroup /var/mail/virtual


И запускаем Postfix:

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

/etc/init.d/postfix start


Вот, собственно, и всё. Отдельное спасибо хочется сказать Ork'у Paladin'у за книжный архив и зеркало портов на www.simlada.ru, а так-же разработчикам Vmware-server, так-как без них пришлось-бы реализовывать схему на одном компе, что было-бы не очень познавательно.
/earth: file system full
Спасибо сказали: