Cyrus IMAP is an efficient IMAP server capable of handling a large number of accounts. Its biggest drawback is getting it installed and configured. This tutorial is a step-by-step guide on how to use Cyrus with the Postfix mail transfer agent (MTA). I tested these instructions with FreeBSD 5.4.
Postfix is a replacement for sendmail, the stock MTA that comes in FreeBSD. It is easier to configure and manage than sendmail. If you depend on sendmail, you can still look at the article for the Cyrus part, but you'll need to look elsewhere for the MTA configuration.
Unless otherwise instructed, perform all operations in this tutorial as root. You will need to use the port system. If you are new to it, check Chapter 4 of the FreeBSD Handbook.
Installing Cyrus and Postfix on FreeBSD requires three ports:
The SASL2 component acts as the authentication method. Any program that will connect to read email will go through SASL2 to authenticate. All users who have mailboxes need an account in the SASL2 database. In addition, any IDs you plan to use to manage Cyrus need IDs in SASL, but they don't need an ID in the Cyrus IMAP server.
Cyrus will manage the mailboxes. Users need to have an ID in Cyrus in order to receive mail.
Postfix will deliver the emails to Cyrus. Postfix needs to know about each user through a virtual alias map file. This file determines which emails to deliver to which internal mailbox. It is possible to point multiple email addresses to the same mailbox.
The ports I used for this article were Postfix 2.23, Cyrus 2.2.12, and SASL 2.1.21
All three ports rely on Berkeley DB as a database. For this article, I chose the most recent version, 4.3; however, if you already have a Berkeley DB port installed, you can configure the ports to use that instead.
Install this port:
# cd /usr/ports/security/cyrus-sasl2 # make WITHOUT_OTP=YES WITHOUT_NTLM=YES WITHOUT_GSSAPI=YES WITH_BDB_VER=43 # make install clean
OTP, NTLM, and GSSAPI are different authentication mechanisms and aren't relevant to this article. If you know about those other authentication mechanisms or plan to use them, you can omit the part that excludes them. However, leaving them while the rest of that authentication mechanism is not operational may cause your setup to not work or to produce additional warnings in your log files.
WITH_BDB_VER=43 specifies to use Berkeley database 4.3.
To test the SASL2 installation, do this:
# rehash # saslpasswd2 -c admin # sasldblistusers2 admin@domain1: userPassword
saslpasswd2 with the
-c parameter instructs SASL2 to create the user.
sasldblistusers2 shows the list of users. If the creation of the user
admin was successful, the output should match the display above.
After you run
make, a menu appears. Click on OK. This port needs no options besides Berkeley DB 4.3.
# cd /usr/ports/mail/cyrus-imapd22 # make USE_BDB_VER=43 # mail install clean
As with the SASL2 port, choose Berkeley DB 4.3 by using
Cyrus needs a directory to hold the IMAP files:
# mkdir /var/imap # mkdir /var/imap/spool # chown -R cyrus:mail /var/imap # chmod -R 750 /var/imap
The default directories for Cyrus are /var/imap and /var/spool, but I prefer /var/imap and /var/imap/spool to facilitate backups. You can point these directories somewhere else, as long as all configuration files point to the same place.
To start Cyrus at boot time, change /etc/rc.conf by adding:
Postfix and Cyrus will communicate with a socket. The /usr/local/etc/cyrus.conf contains the name and location of the socket. Comment the line with
lmtp and add:
lmtpunix cmd="lmtpd" listen="/var/imap/socket/lmtp" prefork=0
The primary configuration file for Cyrus is /usr/local/etc/imapd.conf. Replace your imapd.conf with the following. (The bracketed numbers refer to footnotes; remove those.)
partition-default: /var/imap/spool sievedir: /var/imap/sieve admins: user1@domain1 user2@domain2 admin
allowanonymouslogin: no autocreatequota: 10240 reject8bit: no quotawarn: 90 timeout: 30 poptimeout: 10 dracinterval: 0 drachost: localhost sasl_pwcheck_method: auxprop lmtp_overquota_perm_failure: no unixhierarchysep: no virtdomains: userid defaultdomain: domain1
 To use a different location for your email storage, change the
sievedir to point to your preferred location. The
partition-default doesn't have to be inside the same directory as the
configdirectory, but it makes it easier to back up if it is.
 If you want an ID to manage all domains, create it without a domain. IDs created with domains can manage only their own domain.
 This is the domain the system will add if you create a user without adding a domain.
 List all the domains for which you plan to host email. For an explanation of the options in imapd.conf, see /usr/local/etc/imapd.conf.original and
Now you must create several directories and files to prepare Cyrus for operation. Become user
cyrus and run
# su cyrus >/usr/local/cyrus/bin/mkimap
As root, start Cyrus:
# /usr/local/etc/rc.d/imapd.sh start
To test whether Cyrus is running, use this:
#telnet localhost 143 Escape character is '^]'. * OK computer.domain.com Cyrus IMAP4 v2.2.12 server ready
To exit, type
For each mailbox you will host, you must create an ID in SASL2 and in Cyrus. For example, here's how to create the user
domain1 with a valid domain you plan to host. First, create the user in SASL2:
#saslpasswd2 -c test@domain1 Password: Again (for verification): # sasldblistusers2 email@example.com: userPassword
Then create it in Cyrus. You will need the password you used for user admin. If you don't recall the password, reset it using
#cyradm --user admin localhost Password: localhost.domain1> cm user.test@domain1 lm test@domain1 (\HasNoChildren) quit
A menu will appear when you
make this port. Select the options Cyrus SASL v2 and Berkeley DB4.3. The script will ask whether you want to add the
postfix user to the
# cd /usr/ports/mail/postfix # make install clean # rehash
Enable Postfix at startup by adding the following to your /etc/rc/conf:
sendmail_enable="NONE" sendmail_flags="-bd" sendmail_pidfile="/var/spool/postfix/pid/master.pid" sendmail_outbound_enable="NO" sendmail_submit_enable="NO" sendmail_msp_queue_enable="NO"
Also create a symbolic link in the startup folder so that Postfix will start when the system boots:
# cd /usr/local/etc/rc.d # ln -s /usr/local/sbin/postfix postfix.sh
Then disable some Sendmail-specific daily maintenance routines in your /etc/periodic.conf file:
daily_clean_hoststat_enable="NO" daily_status_mail_rejects_enable="NO" daily_status_include_submit_mailq="NO" daily_submit_queuerun="NO"
With Postfix configured, create a needed file called alias.db, and then start it.
# newaliases # ls -l /etc/aliases.db # postmap /usr/local/etc/postfix/virtual # postfix start
Although the setup described in this article does not use this file, Postfix looks for it anyway. You may need this file depending on your future needs.
To test whether Postfix is running:
telnet localhost 25 You should see a prompt Trying 127.0.0.1... Connected to < your host name > Escape character is '^]'. quit
There is one final file to edit, /usr/local/etc/postfix main.cf. Change the entire main.cf as follows. (Again, bracketed numbers refer to footnotes, so remove them.)
command_directory = /usr/local/sbin daemon_directory = /usr/local/libexec/postfix mailq_path = /usr/local/bin/mailq manpage_directory = /usr/local/man newaliases_path = /usr/local/bin/newaliases queue_directory = /var/spool/postfix sample_directory = /usr/local/etc/postfix sendmail_path = /usr/local/sbin/sendmail mail_owner = postfix soft_bounce = no myhostname = domain1
myorigin = $mydomain relay_domains = $mydestination local_recipient_maps = $virtual_mailbox_maps recipient_delimiter = + debug_peer_level = 2 unknown_local_recipient_reject_code = 550 setgid_group = maildrop html_directory = no readme_directory = no masquerade_domains = $mydomain smtpd_recipient_restrictions = reject_non_fqdn_recipient permit_mynetworks reject_unauth_destination reject_unknown_sender_domain permit smtpd_helo_restrictions = reject_invalid_hostname smtpd_require_helo = yes mailbox_transport = lmtp:unix:/var/imap/socket/lmtp virtual_transport = lmtp:unix:/var/imap/socket/lmtp virtual_mailbox_domains = domain1, domain2
virtual_alias_maps = hash:/usr/local/etc/postfix/virtual
 The primary domain for email purposes.
 A list of all domains you plan to manage, including your primary domain.
For details on the options listed above, see /usr/local/etc/postfix/dist/main.cf.
Now restart Postfix to make it read the new configuration files:
# postfix reload
In addition to having users listed in SASL and Cyrus, Postfix needs to know about them. Add each user to /usr/local/etc/postfix/virtual in the format:
You may also want to have a single address to receive all mail not designated to a valid address. Add the line:
Be aware that doing this will cause all the spam to that domain to go to that user. On the bright side, doing this will make your setup more compliant with the Internet standards that require the existence of addresses such as
postmap /usr/local/etc/postfix/virtual. Remember to run
postmap every time you change that file.
If you already have an IMAP client, you can connect to your newly configured Cyrus server using the test user. Remember to append the domain name when you log in.
If you don't have an IMAP client, you can use a text-based mail client, called Cone, in the ports system for your test. You can install Cone in the same server in which you have installed Cyrus, or on a different machine as long as it can connect to the Cyrus IMAP server.
# cd /usr/ports/mail/cone # make install clean
For the rest of the test, you do not need to be the root superuser.
coneat the command prompt.
Once you are able to connect to the IMAP server with your own client or with Cone, try sending an email. If the machine is the one responsible for handling email for the given domain (that is, if your DNS MX records point to it), you can send an email to your test user from any machine.
If the IMAP server doesn't yet have MX records pointing to it, you can still test your setup by setting the machine you configured as your Cyrus server as the SMTP server. If you're using Cone from the same machine, you don't need to do anything extra. Just write an email and send it to your test user. By default, Cone will use the current machine as the delivery SMTP server.
Francisco Reyes is an independent consultant in New York.
Return to the BSD DevCenter.
Copyright © 2009 O'Reilly Media, Inc.