Introduction
This guide focuses on setting up an Ubuntu 10.04 LTS (lucid) as a mail server (yes I realize it's currently under the Debian section of the site). In the past I've always gone for a full Courier mail system but like a lot of people I've always found it to be surprisingly difficult to maintain. I'm sure if I was running a system that had a huge number of users or hundreds of domains I'd want the power Courier gives me but my needs are much more modest so I've decided to jump ship and go for a much more standard Postfix + Procmail + Dovecot + Roundcube with some SpamAssassin and ClamAV thrown in for good measure.
Postfix
Came pre-installed.
Procmail
Came pre-installed. No additional setup required.
Dovecot
Came pre-installed.
RoundCube
Setting up RoundCube was a complete nightmare. Unlike all the previous systems I've used the PHP plugin for Apache on Ubuntu 10.04 by default is suphp (CGI) rather than the old CLI version. With the old version of the plugin PHP scripts ran as the same user as the webserver (www-data). With suphp they run as the owner of the file. Sounds like a good idea but unfortunately the packaging of RoundCube (and I'm guessing a lot of other stuff) hasn't caught up with the change yet. When I installed RoundCube it with Aptitude it, of course, went in owned by root.
The first error message, which appeared in the apache error log, was:
[Fri Jun 18 16:25:41 2010] [error] [client 78.105.121.126] SoftException in Application.cpp:221: File "/usr/share/roundcube/index.php" is not in document root of Vhost "/var/lib/roundcube", referer: http://webmail.crazysquirrel.com/roundcube/
This is caused by the fact that the document root of the virtual host is set to /var/lib/roundcube but the script being run is in /usr/share/roundcube and so suphp, not Apache, is aborting the execution (it's very paranoid). The solution to this is to pop open the suphp config file (/etc/suphp/supnp.conf) and tell it to stop checking that scripts are under the document root like this:
check_vhost_docroot=false
Now you might think you can just change the docuemnt root to /usr/share/roudncube but that doesn't work if as it will then complain about /var/lib/roundcube instead. It might be possible to get round this with some serious fiddling about but lifes too short. The next problem that reared it's ugly head was one of UID and GID.
[Fri Jun 18 16:33:54 2010] [error] [client 78.105.121.126] SoftException in Application.cpp:350: UID of script "/var/lib/roundcube/index.php" is smaller than min_uid, referer: http://webmail.crazysquirrel.com/roundcube/
Suphp, by default, won't allow any scripts to run with a user or group ID under 100. Since RoundCube has all it's files installed owned by the user root (UID 0) when it's installed this poses quite a problem. One solution is to set the min_uid and min_gid values in the suphp config file to zero and let round cube run as root but this is not a good solution. If someone found a security hole in RoundCube it could compromise the whole system. A better solution is to set the min_uid and min_gid values in the suphp config to 33 which allows the scripts to run as www-data. Next change all the files in /var/lib/roundcube and /usr/share/roundcube so that they are owned by www-data like this:
chown -R www-data:www-data /var/lib/roundcube
chown -R www-data:www-data /usr/share/roundcube
The final hurdle was the error message below.
[Fri Jun 18 15:51:36 2010] [error] [client 78.105.121.126] SoftException in Application.cpp:299: Script "/var/lib/roundcube/index.php" resolving to "/usr/share/roundcube/index.php" not within configured docroot
Don't be fooled into thiking this has anything to do with the Apche virtual host document root, this is actually another setting in the suphp config file. Including the paths which contained the RoundCube scripts fixed this one. For example:
docroot=/var/www:/usr/share/roundcube:/var/lib/roundcube:${HOME}/public_html
Over all I think suphp is a good idea but boy do I look forward to the day when everything just works together with out 4 hours of reading up on why x won't talk to y and what the latest weird cryptic error message means.