Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3342776
  • 博文数量: 815
  • 博客积分: 12898
  • 博客等级: 上将
  • 技术积分: 7883
  • 用 户 组: 普通用户
  • 注册时间: 2006-12-25 09:57
文章分类

全部博文(815)

文章存档

2014年(1)

2011年(46)

2010年(192)

2009年(121)

2008年(70)

2007年(385)

分类: BSD

2007-11-22 02:00:27

Author: J.Vriesman, joenix@gmx.net

All new documentation (including new versions of this one) will be put .




Abstract:

This document describes the setup of an ldap based mailsystem, using openldap, postfix and courier-imap. It was tested on Linux, but it should work on any os if postfix, openldap and courier-imap are available.

  • All mail is owned by one virtual user, no Unix accounts needed.
  • Everything is configured from ldap, no need to restart server processes when adding domains
  • Shared folders can be configured from ldap
  • Mail is in maildir format and can be placed on nfs
  • Multiple smtp and imap servers are possible

The ldap server contains all information needed by the smtp and imap server and can also be used as an address book. Since there seemed to be no objectclass which is exactly fit for this purpose, some attributes are used in a setup-specific way, e.g. ''seeAlso'' for shared folders.

The following schema's are included in slapd.conf:

  • core.schema
  • cosine.schema
  • corba.schema
  • inetorgperson.schema
  • java.schema
  • kerberosobject.schema
  • nis.schema
  • openldap.schema
  • qmail.schema
Not all schema's are used.

Two leaves of the ldap tree are essential for the imap and smtp servers, the first one stores ''system'' information, the other one ''account'' information.

The base for the system leave can be:

  • [ou=System,o=company] 
Under this system leave there is a leave ''ou=postfix'', under which the accepted domains are stored. From here and further this is refered to as the ''system-leave''.

The base for the accounts can be:

  • [ou=Country,o=company] 
Under the account tree the user information is stored, including addresses, passwords, aliases and shared folders. From here and further this is refered to as the ''account-leave''.

Under ''ou=postfix,system leave'' there is an entry for every top-level domain needed by the smtp server, eg:

 

dc=nl,ou=postfix,system_leave

dc=com,ou=postfix,system_leave

dc=net,ou=postfix,system_leave

The attributes of these entry's define the accepted domains for the smtp server using attribute type ''associatedDomain''. Two objectclasses are needed:

  • dNSDomain
  • domainRelatedObject
An example ldif file to make the smtp server accept mail for testdomain.nu, anotherdomain.nu and mydomain.nl:

 

dn: ou=System, o=company
userPassword:: encrypted password
ou: system
objectClass: organizationalUnit

dn: ou=postfix, ou=system, o=company
ou: postfix
objectClass: organizationalUnit

dn: dc=nl,ou=postfix, ou=system, o=company
associatedDomain: mydomain.nl
dc: nl
objectClass: dNSDomain
objectClass: domainRelatedObject

dn: dc=nu,ou=postfix, ou=system, o=company
associatedDomain: testdomain.nu
associatedDomain: anotherdomain.nu
dc: nu
objectClass: dNSDomain
objectClass: domainRelatedObject

Note that the hostname of any of the smtpservers is not mentioned, neither is the name ''localhost'', these names will be accepted, but they are configured in the postfix configuration file.

The dn of the system leave has a ''userPassword'', system has read-only access to the ldap database and is used by the smtp and imap server to read from the ldap database.

Under the account-leave all user accounts are entry's with a dn like:

 

dn: cn=Test User,account-leave

A personal account entry uses the following object classes:

  • top
  • person
  • organizationalPerson
  • inetOrgPerson
  • qmailUser
There seem to be different versions of the qmail.schema file, make sure that in the qmail.schema file qmailUID and qmailGID have ''EQUALITY numericStringMatch'', mailMessageStore has ''EQUALITY caseExactIA5Match'', and all other EQUALITY's in qmail.schema are ''caseIgnoreIA5Match''.

The following subsubsections describe the attributes used by the imap and smtp server.

This attribute must exists, it contains the full name of the used, e.g. ''Abert Onestone''.

This attribute must exists, it can be any string and it's used as a login-id by the imap server.

This attribute is used by the imap server to authenticate, it's encrypted.

This is the ou part of the dn, for example, if you are using ou=Tokelau,o=company as your account-leave, the ou in every account is simply ''Tokelau''.

The given name, only used by the address book, not by the servers.

The surname, only used by the address book, not by the servers.

The main email address of the user, domain included, e.g. albert.onestone@anotherdomain.nu, make sure that the domain is listed in the system-leave, the mail attribute must exist

You can use the same email address in different accounts, it will deliver the mail to that address to multiple users.

IMPORTANT: Only use one mail attribute per account, use mailAlternateAddress for aliases!

This attribute is optional, and can be used multiple times, it contains the aliases, full email address aliases, just like the mail attribute, make sure that the domains you use are listed in the system-leave.

For every personal account the value of this attribute should be ''active'', if the value is ''inactive'' the smtp server will bounce all mail for this user with ''unknown user''.

This attribute is optional, it refers to another dn in the account-leave with accountStatus=shared, seeAlso can be used multiple times per account, when the script ''makeMailMessageStoreDirs'' is executed it creates the directories and links needed to access the shared folders.

This attribute must be present, it contains the full path to the maildir where all mail of the user is stored, make sure in ends with a ''/'', otherwise the smtp server doesn't deliver in maildir format, e.g. ''mailMessageStore: /vmail/harry.potter/Maildir/''.

Shared folders are exactly the same in the ldap server as the personal accounts, exept that it doesn't need a userPassword, and that accountStatus is ''shared''.

Since the entry fro the shared folder in the ldap database must have a uid, the uid entry is the name of the folder where mail for this account will be delivered to. A shared account has one extra attribute:

This attribute can be used multiple times, they contain the names of the subfolders in the shared folder. Not the main folder where mail gets delivered, that one is stored in ''uid''. The actual directories wil be created when the script ''makeMailMessageStoreDirs'' is executed.

The following ldif file represents two user accounts, ''Albert Onestone'' and ''Seven of Nine'', who are both using the shared folder ''Timetravel weekly''. The shared folder contains a folder incoming, past.editions and future.editions, and mail to timetravel@anotherdomain.nu is delivered to the incoming shared folder.

Example ldif:

 

dn: cn=Albert Onestone, ou=Tokelau, o=company
userPassword:: encrypted
givenName: Albert
sn: Onestone
mailMessageStore: /vmail/albert.onestone/Maildir/
mail: albert.onestone@anotherdomain.nu
mailAlternateAddress: a.onestone@anotherdomain.nu
mailAlternateAddress: ao@anotherdomain.nu
ou: Tokelau
uid: onestonea
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: qmailUser
accountStatus: active
cn: Albert Onestone
seeAlso: cn=Timetravel weekly,ou=Tokelau,o=company

dn: cn=Seven of Nine, ou=Tokelau, o=company
userPassword:: encrypted
givenName: Seven
sn: Nine
mailMessageStore: /vmail/seven.of.nine/Maildir/
mail: seven.of.nine@anotherdomain.nu
mailAlternateAddress: s.o.9@anotherdomain.nu
ou: Tokelau
uid: nines
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: qmailUser
accountStatus: active
cn: Seven of Nine
seeAlso: cn=Timetravel weekly,ou=Tokelau,o=company

dn: cn=Timetravel weekly, ou=Tokelau, o=company
givenName: Timetravel
sn: weekly
mailMessageStore: /vmail/shared/timetravel.weekly/incoming/
mail: timetravel@anotherdomain.nu
ou: Tokelau
uid: incoming
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: qmailUser
accountStatus: shared
postOfficeBox: past.editions
postOfficeBox: future.editions

The mail system assumes that all mail is stored under one directory, in this case ''/vmail'', whenever a shared account is created, it's mailMessageStore must be under /mailbasedirectory/shared. Under the mailbasedirectory, two directories must be created for shared folders, one is called ''shared'', the other one is ''shared.maildirs'', both directories must be writable by the mail owner. The shared.maildirs directory is used by the imap server to access the messages, the shared directory is used by the smtp server, it contains symbolic links to the incoming folders of the shared folders.

This is a listing of a script , which creates maildirs and shared folders out of the ldap data, it also creates the right links to shared folders from the seeAlso attributes.

IMPORTANT: the script must be executed with the uid and gid of the mail owner, if it's executed as root, the mailfolders will be unaccessable!

Listing of makeMailMessageStoreDirs:


#!/bin/sh

systempass="your_system_password" # the userPassword of dn: system-leave
systemleave="system-leave" # e.g. ou=System,o=company
accountleave="account-leave" # e.g. ou=Tokelau,o=company


ldappersonaldirs=`ldapsearch -x -w $systempass -D "$systemleave" -b "$accountleave" "(accountStatus=active)" mailMessageStore | grep "^[^#]" | grep mailMessageStore | awk '{ print $2 }'`
ldapshareddirs=`ldapsearch -x -w $systempass -D "$systemleave" -b "$accountleave" "(accountStatus=shared)" mailMessageStore | grep "^[^#]" | grep mailMessageStore | awk '{ print $2 }'`

# create personal mailfolders

for ldappersonaldir in $ldappersonaldirs
do
if [ ! -d $ldappersonaldir ]
then
mkdir -p `dirname $ldappersonaldir`
maildirmake $ldappersonaldir
fi
done

for ldapshareddir in $ldapshareddirs
do
ldapsharedmaildir=`dirname $ldapshareddir | sed 's/\/shared\//\/shared\.maildirs\//g'`
shared_dn=`ldapsearch -x -w $systempass -D "$systemleave" -b "$accountleave" "(mailMessageStore=$ldapshareddir)" uid | grep "^[^#]" | grep "^dn:" | sed 's/^dn: //g'`
shared_uid=`ldapsearch -x -w $systempass -D "$systemleave" -b "$accountleave" "(mailMessageStore=$ldapshareddir)" uid | grep "^[^#]" | grep "^uid:" | sed 's/^uid: //g'`
shared_boxes=`ldapsearch -x -w $systempass -D "$systemleave" -b "$accountleave" "(mailMessageStore=$ldapshareddir)" postOfficeBox | grep "^[^#]" | grep "^postOfficeBox:" | sed 's/^postOfficeBox: //g'`
shared_cn=`ldapsearch -x -w $systempass -D "$systemleave" -b "$accountleave" "(mailMessageStore=$ldapshareddir)" cn | grep "^[^#]" | grep "^cn:" | sed 's/^cn: //g'`
subscribed_dirs=`ldapsearch -x -w $systempass -D "$systemleave" -b "$accountleave" "(&(accountStatus=active)(seeAlso=$shared_dn))" mailMessageStore | grep "^[^#]" | grep mailMessageStore | awk '{ print $2 }'`

# create shared mailfolder

if [ ! -d $ldapsharedmaildir ]
then
maildirmake -S $ldapsharedmaildir
fi

# create shared subfolders

if [ ! -d $ldapsharedmaildir/.$shared_uid ]
then
maildirmake -s write -f $shared_uid $ldapsharedmaildir
fi

# create other shared subfolders
for box in $shared_boxes
do
if [ ! -d $ldapsharedmaildir/.$box ]
then
maildirmake -s write -f $box $ldapsharedmaildir
fi
done

# mailstorage directory

if [ ! -d $ldapshareddir ]
then
mkdir -p `dirname $ldapshareddir`
fi

# link mailstorage to incoming shared folder

dirlink=`echo $ldapshareddir | sed 's/\/$//g'`

if [ ! -L $dirlink ]
then
ln -s $ldapsharedmaildir/.$shared_uid $dirlink
fi

# subscribe those who have a 'seeAlso' to the dn of the shared account

for subscribed_dir in $subscribed_dirs
do
groupname=`echo $shared_cn | sed 's/ /_/g'`
subscribed=$groupname

if [ -e $subscribed_dir/shared-maildirs ]
then
subscribed=`cat $subscribed_dir/shared-maildirs | grep ^$groupname[[:space:]] | awk '{ print $1 }'`
fi

if [ ! $subscribed ]
then
maildirmake --add $groupname=$ldapsharedmaildir $subscribed_dir
fi
done
done

The slapd.conf contains a ''index objectClass,uid,mail,mailAlternateAddress eq'' for performance reasons and a ''allow bind_v2'', which was needed for postfix at some moment.

The acl's of the ldap server don't allow anonymous reading of the ldap data, anonymous can only authenticate, that's why the smtp and imap server have to bind as ''system-leave'', and ''System'' has a password. If anonymous reads would be allowed, the servers could do without binding.

The smtp server is configured once in /etc/postfix/main.cf, after that all users and domains can be added and removed without changing the configuration file. On multiple smtp servers, with a central mail storage (e.g. nfs), all smtp servers can have exactly the same configuration file. Three parameters are ldap based, mydestination, virtual_maps and virtual_mailbox_maps.

All mail is owned by one user, in this case the user is ''vmail'', with unix uid 5000 and unix gid 5000, in main.cf this is configured as:


local_transport = virtual
virtual_mailbox_base = /
virtual_mailbox_maps = ldap:ldapvirtual
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_minimum_uid = 500
virtual_mailbox_limit = 0
ldapvirtual_server_host = ldapserverhostname
ldapvirtual_server_port = 389
ldapvirtual_bind = yes
ldapvirtual_bind_dn = system-leave
ldapvirtual_bind_pw = ldapSystemPassword
ldapvirtual_search_base = account-leave
ldapvirtual_query_filter = (&(|(mail=%s)(mailAlternateAddress=%s))(|(AccountStatus=active)(accountStatus=shared)))
ldapvirtual_result_attribute = mailMessageStore

The local domains are looked up in ldap, this is configured in main.cf:


mydestination = $myhostname, localhost.$mydomain, localhost.localdomain, ldap:acceptdomains
acceptdomains_server_host = ldapserverhostname
acceptdomains_server_port = 389
acceptdomains_bind = yes
acceptdomains_bind_dn = system-leave
acceptdomains_bind_pw = ldapSystemPassword
acceptdomains_search_base = ou=postfix,system-leave
acceptdomains_query_filter = (associatedDomain=*)
acceptdomains_result_attribute = associatedDomain

These lookups are responsible for seeing the mailAlternateAddress as an alias, this part is configured in main.cf as:


virtual_maps = ldap:ldapalias
ldapalias_server_host = ldapserverhostname
ldapalias_server_port = 389
ldapalias_bind = yes
ldapalias_bind_dn = system-leave
ldapalias_bind_pw = ldapSystemPassword
ldapalias_search_base = account-leave
ldapalias_query_filter = (&(|(mail=%s)(mailAlternateAddress=%s))(|(AccountStatus=active)(AccountStatus=shared)))
ldapalias_result_attribute = mail

The imap server is a standard courier-imap installation the ldap configuration is in ''authldaprc'', it uses the mailMessageStore attribute to find the users' maildir, and authenticated with the ldap password.

The authldaprc is configured as follows:


LDAP_SERVER		ldapservername
LDAP_PORT 389
LDAP_BASEDN account-leave
LDAP_BINDDN system-leave
LDAP_BINDPW ldapSystemPassword
LDAP_TIMEOUT 15
LDAP_AUTHBIND 1
LDAP_MAIL uid
LDAP_FILTER (AccountStatus=active)
LDAP_GLOB_UID vmail
LDAP_GLOB_GID vmail
LDAP_HOMEDIR mailMessageStore
LDAP_MAILDIR mailMessageStore
LDAP_FULLNAME cn
LDAP_CRYPTPW userPassword
LDAP_DEREF never
LDAP_TLS 0

All shared folders and the users who have access to it are created with maildirmake commands in the script makeMailMessageStoreDirs (see above).

About this document ...

ldap, postfix and courier-imap howto

This document was generated using the translator Version 2002-1 (1.68)

Copyright © 1993, 1994, 1995, 1996, , Computer Based Learning Unit, University of Leeds.
Copyright © 1997, 1998, 1999, , Mathematics Department, Macquarie University, Sydney.

The command line arguments were:
latex2html -no_subdir -split 0 -show_section_numbers /tmp/lyx_tmpdir3842mb3hRe/lyx_tmpbuf0/postfix-courier-ldap-howto.tex

The translation was initiated by Administrative Account on 2003-05-16

阅读(2468) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~