FreeBSD, Postfix, Dovecot, and Active Directory
A while back one of my clients had an unpatched qmail server configured with local system users, it was set up in a collocation long before I took over. After having to listen to a lot of complaints about slow internet connectivity I found out that 40-50MB attachments were very common. Another thing I didn’t like about this set-up is the fact I had to maintain 2 password databases; An Active Directory for local user login and a shadow file for mail. So a local set-up with Active Directory as a back end was needed.
Postfix comes to the rescue. Having used Postfix for the past 3 years I believe it is the best MTA out there. qmail has it’s merits, but I’m not a big fan. After a lot of arguing the client managed to budge and give me one of the old workstations to use as a server, which, a month later had a hard drive crash and I forgot everything about this. Yesterday I thought I should document this since I didn’t see an easy to follow HOWTO for doing such a set-up.
NOTE: Unless mentioned otherwise, all the samples provided here show the lines you need to change in your configuration files, not the whole contents of those files. Remember to restart each daemon after configuration file changes.
Update: After checking vgumus’s setup I need to mention this. You’ll notice the user part of the email address is the same as the Active Directory user name (mshami and [email protected] ). Dovecot expects to get the Active Directory username from Postfix. If you want to use some other address in the “mail” field you have to use the virtual alias maps feature from Postfix to return sAMAccountName.
Update 2: This tutorial isn’t a substitute for reading the manual pages and having the basic skills to perform these operations. Please consult the manuals to get an idea of the configuration options for each software.
Enough with the introduction, lets get down to business. Here is what we’re going to use in order of installation:
- FreeBSD 7.0. You can use Linux if you want, but you have to change a few steps. I’m using the ports version that came on the CD.
- Dovecot 1.0.10
- Postfix 2.4.6
Preparation:
- We will need to have an Active Directory environment set up. This is out of the scope of this document
- We need a non-privileged user in Active Directory to allow the other programs to authenticate, I’m calling it LDAP, and the password will be qwerty
- Test username will be mshami and password will be qazxsw
- Domain name is shami.local
- Base DN is DC=shami,DC=local
- IP addresses for our domain controllers are 192.168.192.210 and 192.168.192.211
FreeBSD: Start your FreeBSD installation, I like to go with minimal installations and then add the needed components. Just make sure to give /usr about 5GB of space and give /var a LOT of space to hold the logs and the mail files. Then install the ports collection.
Dovecot: The first time I did this I used Courier-IMAP. Its a good program but here it has a major issue. You have to create the home directories for all your users before they can log in. I wrote a patch for that but you have to apply it on both the IMAP and the POP3 daemons. You also have to patch Maildrop to do the same. So I decided to go ahead with Dovecot which after some research appears to have better performance than Courier-IMAP and more importantly has self-healing capabilities which solves this issue.
First, add a user called vmail (Assuming UID 1001 and GID 1001), this will be responsible for handling the virtual mailboxes. Then install Dovecot from ports
1cd /usr/ports/mail/dovecot/
2make
3make install
Choose LDAP, LDA, and any other options you want to use, answer yes when asked to create the group and the user dovecot. Asseming UID and GID of 143.
1mkdir /var/vmail
2chown vmail:vmail /var/vmail
Configuration:
1# rc.conf
2dovecot_enable="YES"
Configure Dovecot:
1# dovecot.conf
2#We'll be starting with IMAP only, add other protocols when you get your system to start
3protocols = imap
4#Set all usernames to lowercase before authenticating, because Dovecot will create folders with the mixed case characters.
5auth_username_format = %Lu
6#Enable non-secure logging for testing
7disable_plaintext_auth = no
8ssl_disable = yes
9#No matter how many domains we have, the usernames will be unique, so save the messages to /var/vmail/username
10#Same as default_mail_env
11mail_location = maildir:/var/vmail/%n
12#Since we have virtual delivery, only the vmail user should be able to deliver, in my case the UID of that user is 1001
13first_valid_uid = 1001
14last_valid_uid = 1001
15#Same thing for groups
16first_valid_gid = 1001
17last_valid_gid = 1001
18#Set this to were you want the messages to reside
19valid_chroot_dirs = /var/vmail
20#auth default section
21##Comment passdb pam
22##Commend userdb passwd
23##Add ldap passdb and userdb
24 passdb ldap {
25 # Path for LDAP configuration file, see doc/dovecot-ldap.conf for example
26 args = /usr/local/etc/dovecot-ldap.conf
27 }
28 userdb ldap {
29 # Path for LDAP configuration file, see doc/dovecot-ldap.conf for example
30 args = /usr/local/etc/dovecot-ldap.conf
31 }
Set up the LDAP backend:
1cp /usr/ports/mail/dovecot/work/dovecot-1.0.10/doc/dovecot-ldap-example.conf /usr/local/etc/dovecot-ldap.conf
2vi dovecot-ldap.conf
3
4hosts = 192.168.192.210 192.168.192.211
5dn = CN=LDAP User,OU=Special Users,DC=shami,DC=local
6dnpass = qwerty
7auth_bind = yes
8ldap_version = 3
9base = dc=shami, dc=local
10user_attrs = sAMAccountName=home
11user_filter = (&(ObjectClass=person)(sAMAccountName=%u))
12pass_filter = (&(ObjectClass=person)(sAMAccountName=%u))
13user_global_uid = 1001
14user_global_gid = 1001
auth_bind tells dovecot to try to bind to Active Directory with the username and password clients authenticate with. Since Active Directory won’t let us read the password field then we need to do this. we’re not using Kerberos here.
Testing:
1/usr/local/etc/rc.d/dovecot start
2telnet localhost 143
3Trying 127.0.0.1...
4Connected to 127.0.0.1.
5Escape character is '^]'.
6* OK Dovecot ready.
7a LOGIN mshami qazxsw
8a OK Logged in.
9a EXAMINE INBOX
10* FLAGS (Answered Flagged Deleted Seen Draft)
11* OK [PERMANENTFLAGS ()] Read-only mailbox.
12* 0 EXISTS
13* 0 RECENT
14* OK [UIDVALIDITY 1206022806] UIDs valid
15* OK [UIDNEXT 1] Predicted next UID
16a OK [READ-ONLY] Select completed.
17a LOGOUT
18* BYE Logging out
19a OK Logout completed.
20Connection closed by foreign host.
If you get that then you’re OK. Otherwise check your logs. You can turn on debugging in dovecot.conf. Also, you can use the Global Catalog port in your queries. The Global Catalog doesn’t use referrals, referrals cause some issues some times.
Now it’s time to get SMTP working
1cd /usr/ports/mail/postfix
2make
3make install
Make sure you choose DOVECOT and OPENLDAP. Also choose any other options you need. No need for any Kerberos options. You can use the default options during the make install operation.
Disable sendmail and enable Postfix:
1# /etc/rc.conf
2postfix_enable="YES"
3sendmail_enable="NO"
4sendmail_submit_enable="NO"
5sendmail_outbound_enable="NO"
6sendmail_msp_queue_enable="NO"
7
8# /etc/periodic.conf
9daily_clean_hoststat_enable="NO"
10daily_status_mail_rejects_enable="NO"
11daily_status_include_submit_mailq="NO"
12daily_submit_queuerun="NO"
Fix the Postfix maps
1postalias /etc/aliases```
2
3Reboot the system for all settings to take effect, then test:
4```plaintext
5telnet localhost 25
6Trying 127.0.0.1...
7Connected to localhost.
8Escape character is '^]'.
9220 server ESMTP Postfix
10quit
11221 2.0.0 Bye
Now that Postfix is running, lets hook it up to Active Directory (This is the complete file):
1myhostname=mailhost
2mydestination=localhost
3mynetworks=127.0.0.1
4myorigin=shami.net
5
6virtual_mailbox_base = /var/vmail
7
8virtual_uid_maps = static:1001
9virtual_gid_maps = static:1001
10
11smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination
12
13alias_maps = hash:/etc/aliases
14command_directory = /usr/local/sbin
15daemon_directory = /usr/local/libexec/postfix
16
17virtual_mailbox_domains =
18 shami.net
19
20#LDAP Stuff
21virtual_mailbox_maps = ldap:ldapvirtual
22ldapvirtual_server_host =
23 ldap://192.168.192.210
24 ldap://192.168.192.211
25ldapvirtual_search_base = DC=shami,DC=local
26ldapvirtual_bind = yes
27ldapvirtual_bind_dn = SHAMIldap
28ldapvirtual_bind_pw = qwerty
29ldapvirtual_query_filter = (sAMAccountName=%u)
30ldapvirtual_result_attribute = sAMAccountName
31ldapvirtual_version = 3
32ldapvirtual_chase_referrals = yes
33ldapvirtual_result_format=%s/
Lets test:
1telnet localhost 25
2Trying 127.0.0.1...
3Connected to localhost.
4Escape character is '^]'.
5220 mailhost ESMTP Postfix
6helo localhost
7250 mailhost
8mail from: [email protected]
9250 2.1.0 Ok
10rcpt to: [email protected]
11250 2.1.5 Ok
12data
13354 End data with .
14hi
15.
16250 2.0.0 Ok: queued as 92B5911460
17quit
18221 2.0.0 Bye
19Connection closed by foreign host.
If all goes well, Postfix will deliver the message to /var/vmail/mshami/
Using the Dovecot LDA: Normally the virtual delivery agent is enough, but if you want to apply quota or vacation auto reply you’re going to have to use the Dovecot LDA. Also, the Dovecot LDA updates the mailbox indexes which will give you better IMAP/POP3 performance
1
2# /usr/local/etc/postfix/master.cf
3dovecot unix - n n - - pipe
4 flags=DRhu user=vmail:vmail argv=/usr/local/libexec/dovecot/deliver -d ${user}
5
6# /usr/local/etc/postfix/main.cf
7virtual_transport=dovecot
8dovecot_destination_recipient_limit=1
9
10# /usr/local/etc/dovecot.conf and uncomment the following (client section removed):
11 socket listen {
12 master {
13 path = /var/run/dovecot/auth-master
14 mode = 0600
15 user = vmail
16 group = vmail
17 }
18 }
Test again:
1telnet localhost 25
2Trying 127.0.0.1...
3Connected to localhost.
4Escape character is '^]'.
5220 mailhost ESMTP Postfix
6helo localhost
7250 mailhost
8mail from: [email protected]
9250 2.1.0 Ok
10rcpt to: [email protected]
11250 2.1.5 Ok
12data
13354 End data with .
14hi
15.
16250 2.0.0 Ok: queued as 9DBBF1143B
17quit
18221 2.0.0 Bye
19Connection closed by foreign host.
Now check your logs, you should see something like this:
1postfix/pipe[904]: 9DBBF1143B: to=, relay=dovecot, delay=6.9, delays=6.4/0.01/0/0.56, dsn=2.0.0, status=sent (delivered via dovecot service)
Great, now we’re ready to enable SMTP authentication:
1vi /usr/local/etc/postfix/main.cf
2smtpd_sasl_auth_enable = yes
3broken_sasl_auth_clients = yes
4smtpd_sasl_type = dovecot
5smtpd_sasl_path = /var/run/dovecot/auth-client
6
7vi /usr/local/etc/dovecot.conf
8 client {
9 path = /var/run/dovecot/auth-client
10 mode = 0660
11 user = postfix
12 group = postfix
13 }
Testing:
1telnet localhost 25
2Trying 127.0.0.1...
3Connected to localhost.
4Escape character is '^]'.
5220 mailhost ESMTP Postfix
6ehlo localhost
7250-mailhost
8250-PIPELINING
9250-SIZE 10240000
10250-VRFY
11250-ETRN
12250-AUTH PLAIN
13250-AUTH=PLAIN
14250-ENHANCEDSTATUSCODES
15250-8BITMIME
16250 DSN
17AUTH PLAIN AG1zaGFtaQBxYXp4c3c=
18235 2.0.0 Authentication successful
19quit
20221 2.0.0 Bye
21Connection closed by foreign host.
Instead of AG1zaGFtaQBxYXp4c3c= you can generate your own username/password combination by using the command:
1printf 'usernamepassword' | mmencode```
2
3Where is the null byte.
4
5Enabling quota:
6There is no need to go through this here, as the Dovecot wiki explains it clearly.
7
8[http://wiki.dovecot.org/Quota](http://wiki.dovecot.org/Quota)
About Me
Dev gone Ops gone DevOps. Any views expressed on this blog are mine alone and do not necessarily reflect the views of my employer.
Recent Posts