Luigi Rosa lists@luigirosa.com uttered: Hi, has anyone implemented a mail server with maildir, Postfix and Dovecot using Active Directory ad userbase and password authentication?
Do I need Samba to authenticate users?
Can I use credential caching just like mysql?
Ciao, luigi
-- / +--[Luigi Rosa]-- \
Hi Luigi, I am running a Postfix/Dovecot setup that is authenticating against a Windows 2000 domain. It is possible to authenticate several different ways, including Kerberos/Winbind and NTLM via Samba.
I used the following article as a guide. It is for FreeBSD, but the configuration instructions apply equally to any Postfix/Dovecot setup. I am running mine on Ubuntu 8.10.
http://blog.al-shami.net/index.php/freebsd-postfix-dovecot-and-active-direct...
The above article covers most of the setup, however I have changed a few things for my purposes.
In short, I am using LDAP to communicate with the Active Directory server. I am looking up email addresses and aliases from AD in Postfix and using Dovecot as LDA. Postfix uses Dovecot's SASL for authentication, and Dovecot in turn authenticates against AD.
My Setup: Postfix and Dovecot running on the same virtual machine on a Dell 2950 with 1x Xeon E5440 on ESXi 4. Maildirs served up by 10x146GB SCSI drives on RAID-10 via direct attached Dell MD-1000.
Serving 600+ users, mailbox sizes up to 14GiB with constant heavy searching (no fts yet) and filtering (sieve and IMAP clients). 80,000 messages delivered per week, 95,000 messages rejected, 17,000 spam. 15 minute Load average stays under .50 all day with 4 CPU cores.
IMAP clients include Outlook 2007, Thunderbird 2 and 3, in addition to webmail via Group Office (yuck).
dovecot-ldap.conf:
# Include multiple domain controllers for redundancy, first one is # at the same facility as the Dovecot server. hosts = 10.0.1.12:389 10.0.2.12:389 10.0.3.12:389
# Specify the full DN of a user to authenticate against dn = cn=Internal, ou=People, dc=example, dc=com dnpass = some_secure_password auth_bind = yes ldap_version = 3 base = ou=People, dc=example, dc=com
# Specify the base storage for email here user_attrs = sAMAccountName=home=/var/vmail/example.com/%$
# The following user_filter should all be on a single line. # The ugly userAccountControl param means "Exclude disabled users" user_filter = (&(sAMAccountName=%Ln)(!(userAccountControl:1.2.840.113556.1.4.803:=2))) pass_filter = (&(sAMAccountName=%Ln)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))
For the Postfix side of things, the article explains how to set Postfix to use Dovecot's SASL for authentication. It also specifies separate confs for Postfix to lookup users and aliases from.
For my purposes, I decided not to modify the AD schema, and to instead utilize an unused field to store aliases in. This field had to be able to store multiple values in a way that I could query easily via LDAP. I chose the "IP Phone" field for this purpose. In the AD GUI it is easily accessible, and allows for multiple values to be stored. Note its usage in the queries that follow.
/etc/postfix/ldap-users.cf:
# Same list of DCs as in dovecot-ldap.conf server_host = ldap://10.0.1.12:389 ldap://10.0.2.12:389 ldap://10.0.3.12:389
search_base = dc=example, dc=com bind = yes bind_dn = EXAMPLE\internal bind_pw = a_secure_password
# Use this lookup for email addresses matching the following domains # corresponds with virtal_mailbox_domains in main.cf domain = example.com, examplelegacy.com, exmple.com
# The following query has been modified a bit from the above article. # First, the userAccountControl param specifies the exclusion of # disabled users. # The other change is from objectClass to objectCategory. query_filter = (&(&(objectCategory=person)(sAMAccountName=%u))(!(userAccountControl:1.2.840.113556.1.4.803:=2))) result_attribute = sAMAccountName version = 3
# I was having trouble with referrals not resolving properly due to a # misconfigured domain controller. I turned this option off and have # not had a problem since. chase_referrals = no result_format=example.com/%s/ debuglevel = 0 timeout = 30
/etc/postfix/ldap-aliases.cf:
# Same list of DCs as in dovecot-ldap.conf server_host = ldap://10.0.1.12:389 ldap://10.0.2.12:389 ldap://10.0.3.12:389
search_base = dc=example, dc=com bind = yes bind_dn = EXAMPLE\internal bind_pw = a_secure_password domain = example.com, examplelegacy.com, exmple.com
# This query looks up aliases from the otherIPPhone field. query_filter = (&(&(objectCategory=person)(|(otherIPPhone=%u)(sAMAccountName=%u)))(!(userAccountControl:1.2.840.113556.1.4.803:=2))) result_attribute = sAMAccountName version = 3 chase_referrals = no result_format=%s@example.com debuglevel = 0 timeout = 30
The objectCategory replacement for objectClass is a *huge* performance increase. objectClass is not indexed in Active Directory, forcing a lot of CPU cycles to be wasted for every lookup. The way I have implemented things, this means two of these expensive lookups per incoming email (even if it was undeliverable!).
At first this was using around 50% CPU on a dual Xeon domain controller. This was acceptable at the time, but after my optimizations we were able to move authentication to a virtual machine with 640MB of RAM and a single CPU core where it now stays below 20% all day. Changing the lookup to an indexed field probably cut the initial load by 90%. Adding auth_cache settings to dovecot.conf then further reduced load by more than 50%.
Well, I suppose that screed should suffice for my first post. I've gained much from just lurking in this list, just trying to contribute where I can.
-- Wayne Thursby System Administrator Physicians Group, LLC