Thursday, June 18, 2009

Virtual Mail Hosting with Postfix, Cyrus and Roundcube

My sister makes delicious fudge and sells it online through her website Being the computer geek in the family I help get it set up and deal with a little of the day to day requirements of the website. One of those requirements is that order notification emails are routed properly. As a knowledgeable Linux geek I’m undaunted by the idea of running my own mail system and would rather do that than have it hosted.

My platform of choice is Debian because of its stability and ease of management for the command-line adept. I’m providing my setup notes below with some commentary so that they might help someone else get their mail system online. These instructions should hopefully translate decently well to other distributions although the package names, config file locations, and default configuration choices are likely to be different.

I chose Postfix because it’s simple and works very well. I have experience with Sendmail and would like to keep it in the past. I chose Cyrus IMAP based on recommendations from peers. It’s my understanding that if my setup were to become more complex Cyrus would make those complex scenarios easier to implement. I chose Roundcube because it’s clean, easy to use, and has given me very few problems in the years I’ve been using it for my own mail.

These instructions are not a step-by-step guide. If you’re familiar with Linux and Debian they can probably get you through it. If not you may find some difficulty on systems other than Debian Lenny.

What’s Missing

  • SSL - I don’t explain how to set up SSL for the webmail. It is essential that you do this.

  • Spam filtering/Virus protection - Not there yet

  • SPF/Domain Keys - These are good for getting your mail through other people’s spam filters

  • Directory Services - There’s no expectation that we’ll need to coordinate on a big list of contacts, but Roundcube does have LDAP address book support

  • User’s can’t change their own passwords - not something we need

  • Other features we didn’t need.

Debian Setup

I always install Debian stripped down, with no package sets selected. In this case I’m using the latest release, Lenny (5.0). I edit my sources to include non-free and contrib. I then run apt-get update. I apt-get install sudo openssh-server vim-nox and add my normal user to the sudoers with ALL=(ALL) ALL. I log out and log in as my personal user. I install the necessary packages:

sudo apt-get install postfix ca-certificates cyrus-imapd-2.2 sasl2-bin libsasl2-modules cyrus-admin-2.2 cyrus-clients-2.2 apache2-mpm-prefork libapache2-mod-php5 php5-mysql php5-mcrypt mysql-server-5.0

Be sure to choose a good password for MySQL and install postfix as Internet Site.

Because this is a very small setup I’d prefer to use SQLite over MySQL. I’m not a MySQL fan at all. Unfortunately Debian prefers SQLite3 (which I also prefer) but Roundcube seems to only support SQLite2. Rather than hack it to make it work I’ll just make a different selection.

I download the 3.0 beta Roundcube tarball from

Postfix needs to be in the mail group to communicate with Cyrus the way we’re using it so I add the postfix user to the mail group.

Cyrus SASL

Cyrus SASL provides saslauthd which, for our purposes, abstracts away the complexities of various authentication mechanisms to a single interface. We’re going to use a simple database file but later on it could be scaled up to use SQL, LDAP, Kerberos, or something else.

In /etc/default/saslauthd set MECHANISMS="sasldb" and START=yes. Next we need to create users and set passwords for them. Choose good passwords, particularly for the cyrus user because that is your administrative user.

sudo saslpasswd2 -c -u hostname usera
sudo saslpasswd2 -c -u hostname userb
sudo saslpasswd2 -c -u hostname cyrus
sudo /usr/sbin/sasldblistusers2
sudo /etc/init.d/saslauthd restart
sudo testsaslauthd -u usera -r hostname -p blarg

The last command allows you to ensure authentication is working. In that example usera’s password is blarg, which is a terrible password. If a user is having trouble logging in later, ensure that this works.

Cyrus IMAP

This configuration is only allowing mail access via a web-based mail service. Therefore we don’t need IMAP remotely accessible and don’t need POP or NNTP at all.

  • In imapd.conf uncomment imap_admins: cyrus

  • In cyrus.conf, SERVICES section, set the imap line to have listen=“”, ensure the pop and nntp lines are commented out

  • Restart cyrus

cyradm –user cyrus localhost and user the password you created for the cyrus user.

> cm user.usera
> cm user.userb
> quit

The cm command creates a mailbox. Note that the usernames are prefixed with user. and the domain is not specified. This took me some time to figure out despite the fact that the logs were telling me exactly why my mail wasn’t reaching the mailboxes.


I made these edits to the In your configuration make sure that if these are duplicates of existing settings that you comment out the original settings or merge them appropriately. I’m using SSL/TLS optionally so systems that support using encryption with SMTP will do so. Those that don’t will function normally. I’m using the Debian-generated Snake Oil cert. This may be a bad choice for you. Make sure you understand where your certificate and keypair came from.

# add to
virtual_transport = lmtp:unix:/var/run/cyrus/socket/lmtp
virtual_mailbox_domains =
virtual_mailbox_maps = hash:/etc/postfix/vmailbox
virtual_alias_maps = hash:/etc/postfix/virtual

# Make sure this is in
smtpd_tls_security_level = may
smtp_tls_security_level = may
# comment out this

I have to create two new files in the /etc/postfix/ directory, virtual and vmailbox. Here are their contents:

# /etc/postfix/vmailbox usera@myhostname userb@myhostname

# /etc/postfix/virtual,

I had to edit the so that postfix could properly deliver mail to Cyrus. This required telling postfix that the Unix socket being used is not inside a chroot.

# change
lmtp unix - - - - - lmtp
# to
lmtp unix - - n - - lmtp

For speed our virtual and vmailbox files are hashed databases and those databases need to be regenerated any time the source files are changed.

jason@hostname:/etc/postfix$ sudo postmap virtual vmailbox

And restart postfix.


This Apache configuration is actually not that great. I leave it to the reader to do something better with it. The most significant issue is that it does not include access via SSL. Since you’re sending usernames and passwords to the server you should not leave it this way. There are copious guides to getting this accomplished. Again, know what you’re doing with your certificates.

Unpack tarball into /tmp

cd /var/www
sudo mv /tmp/roundcubemail-0.3-beta/* /var/www/webmail/
cd webmail

sudo chown www-data:www-data temp logs
cd /etc/apache2/mods-enabled
sudo ln -s ../mods-available/rewrite.load .
cd ..
sudo vi sites-available/default
# Add
<Directory /var/www/webmail>
Options Indexes FollowSymLinks MultiViews
AllowOverride Indexes
Order allow,deny
allow from all

Remove last two lines from webmail/.htaccess
Restart apache (not reload)
mysql -u root -p

mysql> CREATE DATABASE roundcubemail /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
Query OK, 1 row affected (0.00 sec)

mysql> GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost IDENTIFIED BY 'blarg';
Query OK, 0 rows affected (0.00 sec)

Visit http://whatever/webmail/installer/ and walk through the configuration.

Once everything is happy,

sudo rm -rf /var/www/webmail/installer/

At this point I’m able to log in as both users, send and receive mail (DNS is properly configured), manage my folders etc. Note that no folders were created automatically by Cyrus so I had to make them myself, at least the ones that Roundcube was looking for. I also had to create the Identities for each user but that was easy.


The end product is a mail system that’s simple to use, works well, and is easy to administer. New domains are added in Postfix in the, vmailbox, and virtual files (don’t forget postmap). Mailboxes are managed with cyradm. Passwords are managed with saslpasswd2.

Special thanks to directory-services ninja (among other things) subcon from In additional to having gone through this frontier before me, he also does things with LDAP that would require normal people to use Celtic runs and goat’s blood.

No comments:

Post a Comment