Postfix Dovecot Mailserver on Ubuntu 9.10 Karmic/9.04 Jaunty

*UPDATE 11/07/09* – Walkthrough has been tested and works identically on Ubuntu 9.10 Karmic Koala

The Ubuntu team assembled a very convenient mail server stack package for Jaunty that performs a complete install and secure configuration of Postfix and Dovecot (both pop3 and imap) with SASL authentication TLS support and maildir style mailboxes. This walkthrough will contain everything you need to set up an internet facing mail server.

Update sources before we get started

sudo apt-get update

Install the package

sudo apt-get install dovecot-postfix

General Type of Mail Configuration: Internet Site
System mail name: yourcompany.com

That’s it! You now have a working mailserver. If you’ve never done this before, the Ubuntu team just saved you about an hour worth of configuration file editing and testing.

Now that your mail server is running we need to set up users. The default dovecot-postfix install is set up to manage email addresses based on system users. We’re going to set up a MySQL database to handle that so we don’t need to create a new system user (or alias) every time we want to add an email address.

Install MySQL and Postfix MySQL compatibility

sudo apt-get install mysql-server postfix-mysql

We need to create a user to manage the database.

Fire up MySQL

mysql -u root -p
CREATE DATABASE postfix;
CREATE USER 'postfix'@'localhost' IDENTIFIED BY 'password';
GRANT ALL ON postfix.* to 'postfix'@'localhost';
exit

Postfix admin is a web based administration panel for Postfix. It will handle creating and managing email addresses as well as other extras like vacation autoresponders. It requires a webserver with php5 support. I’ll be using Apache2 for this guide, but you can use lighttpd if you want a smaller footprint. You can also install this on a different server if you don’t want to run a webserver on your mail server. Note: if you run your webserver on another machine you’ll need to make the necessary changes to the MySQL user permissions.

Install Apache2 and php5

sudo apt-get install apache2 php5 php5-mysql php5-imap

Restart Apache so it registers PHP

sudo /etc/init.d/apache2 restart

When that’s complete confirm that you can pull up your server’s IP in a web browser. You should see: It works!

Switch over to the /var/www directory

cd /var/www

Download the postfixadmin files

sudo wget http://downloads.sourceforge.net/sourceforge/postfixadmin/postfixadmin_2.3rc7.tar.gz

Note: This address is the current release candidate so this link may change. You can find the current version at http://sourceforge.net/projects/postfixadmin/files/.

Extract the contents

sudo tar -zxvf postfixadmin_2.3rc7.tar.gz

Rename the directory to something more friendly and remove the tarball:

sudo mv postfixadmin-2.3rc7 postfixadmin
sudo rm postfixadmin_2.3rc7.tar.gz

Update the postfixadmin configuration file with your settings

cd postfixadmin
sudo nano config.inc.php

$CONF['configured'] = true;
$CONF['postfix_admin_url'] = $_SERVER['HTTP_HOST'].’/postfixadmin’;
$CONF['database_password'] = ‘yourdbpasswdhere’;

Also update the following variables to what makes sense for your installation
$CONF['admin_email']
$CONF['default_aliases']
Save and close (CTRL + X)

Browse to: http://yourserverip/postfixadmin/setup.php. You’ll likely see a warning about magic quotes. Since I *hate* magic quotes, I’ll go ahead and turn those off. You can safely skip this step if you really want to.

sudo nano /etc/php5/apache2/php.ini

magic_quotes_gpc = Off
save and close (CTRL + X)

sudo /etc/init.d/apache2 restart

Refresh the setup page and everything should read OK now. Scroll down to the bottom and enter a “Setup password”. (scroll back down to the bottom for the result) This was required in the configuration file if you noticed, so we’ll have to copy the hashed result and paste it into the config.inc.php file.

sudo nano config.inc.php

Update $CONF['setup_password']
Save and close (CTRL + X)

Back on the setup page create a new admin user. (admin must be an email address) Once you create the admin account you can now log in to http://yourserverip/postfixadmin/ The postfixadmin interface is simple and mostly self explanatory so I won’t go into it in detail here.

At this point we have a working mailserver and a MySQL powered user database, now we have to set up all the connections.

We need to create 4 files for postfix containing SQL queries that will give postfix the information it needs to delivery to active addresses.

cd /etc/postfix
sudo nano my_alias_maps.cf

user = postfix
password = yourdbpasswd
hosts = localhost
dbname = postfix
query = SELECT goto FROM alias WHERE address = ‘%s’ AND active = 1
save and close (CTRL+x)

sudo nano my_domains_maps.cf

user = postfix
password = yourdbpasswd
hosts = localhost
dbname = postfix
query = SELECT domain FROM domain WHERE domain = ‘%s’ AND backupmx = 0 AND active = 1
save and close (CTRL+x)

sudo nano my_mailbox_limits.cf

user = postfix
password = yourdbpasswd
hosts = localhost
dbname = postfix
query = SELECT quota FROM mailbox WHERE username = ‘%s’ AND active = 1
save and close (CTRL+x)

sudo nano my_mailbox_maps.cf

user = postfix
password = yourdbpasswd
hosts = localhost
dbname = postfix
query = SELECT CONCAT(domain,’/',maildir) FROM mailbox WHERE username = ‘%s’ AND active = 1
save and close (CTRL+x)

Now we have to update postfix’s main.cf to add the paths to the new files as well as some various other updates.

sudo nano main.cf

Add these items to the file (at the end is fine)

virtual_minimum_uid = 150
virtual_uid_maps = static:150
virtual_gid_maps = static:8
virtual_mailbox_base = /var/vmail
virtual_transport = dovecot
dovecot_destination_recipient_limit = 1

virtual_alias_maps = proxy:mysql:/etc/postfix/my_alias_maps.cf
virtual_mailbox_limit = proxy:mysql:/etc/postfix/my_mailbox_limits.cf
virtual_mailbox_domains = proxy:mysql:/etc/postfix/my_domains_maps.cf
virtual_mailbox_maps = proxy:mysql:/etc/postfix/my_mailbox_maps.cf

Comment out (or remove) the following set options:
#home_mailbox = Maildir/
#mailbox_command = /usr/lib/dovecot/deliver -c /etc/dovecot/dovecot-postfix.conf -n -m “${EXTENSION}”

Remove yourcompany.com from mydestination. (It can’t be in mydestination and virtual_mailbox_domains)

save and exit (CTRL+X)

sudo nano master.cf

dovecot unix – n n – - pipe flags=DRhu user=vmail:mail argv=/usr/lib/dovecot/deliver -c /etc/dovecot/dovecot-postfix.conf -f ${sender} -d $(recipient)

save and exit (CTRL+X)

Create the directory for the mail and user who will handle it

sudo useradd -r -u 150 -g mail -d /var/vmail -s /sbin/nologin vmail
sudo mkdir /var/vmail
sudo chmod 770 /var/vmail
sudo chown vmail:mail /var/vmail/

Finally, we have to make some changes to the dovecot configuration to accept the mail and deliver it

cd /etc/dovecot
sudo nano dovecot-sql.conf

driver = mysql
connect = host=localhost dbname=postfix user=postfix password=yourdbpassword
default_pass_scheme = MD5-CRYPT

user_query = SELECT ‘/var/vmail/%d/%n’ as home, ‘maildir:/var/vmail/%d/%n’ as mail, 150 AS uid, 8 AS gid, concat(‘dirsize:storage=’, quota) AS quota FROM mailbox WHERE username = ‘%u’ AND active = 1

password_query = SELECT username as user, password, ‘/var/vmail/%d/%n’ as userdb_home, ‘maildir:/var/vmail/%d/%n’ as userdb_mail, 150 as userdb_uid, 8 as userdb_gid FROM mailbox WHERE username = ‘%u’ AND active = 1

save and exit (CTRL+X)

sudo nano dovecot-postfix.conf

Change (or uncomment) a few options

mail_location = maildir:/var/vmail/%d/%n
first_valid_uid = 150
last_valid_uid = 150

passdb sql {
args = /etc/dovecot/dovecot-sql.conf
}

userdb sql {
args = /etc/dovecot/dovecot-sql.conf
}

master {
path = /var/run/dovecot/auth-master
mode = 0660
user = vmail
group = mail
}

save and exit (CTRL+X)

Restart both services so changes take effect

sudo /etc/init.d/postfix restart
sudo /etc/init.d/dovecot restart