A Whimsicalmind

How to setup your own Ubuntu mail server (Part 1)

| 0 comments

Many times I find myself in a conversation with people about the difficulty of hosting their own mail servers. It’s a common belief that they’re hard to build and maintain. In this series of tutorials, I will hopefully be able to disprove this idea.

I have split this into 2 parts. Part 1 (this part) will cover the initial installation and configuration of the IMAP and SMTP servers. Part 2 will cover how to add email accounts and setting up a webmail client. If it is popular, I may add more parts covering anti-spam, anti-virus… etc.

This tutorial assumes you have an Ubuntu 10.04 LTS installation, with Apache, MySQL and PHP pre installed / configured. That phpMyAdmin is installed. That you have a domain, and the DNS records are pointing to your server. That you have root access to your server via SSH. That you have a SSH client installed on your local machine. It is also assumed that you are familiar with basic Linux command line use.

If you want any additional how-tos for any of the above, then leave me a comment.

If you do not have a server, then I recommend a Linode VPS. For my email server, I am using a Linode 512. Under £15 ($20) per month.

Step 1

First we need to install the base packages. Open your SSH client and log into your server.

sudo apt-get install postfix postfix-mysql postfix-doc dovecot-common dovecot-imapd dovecot-pop3d libsasl2-2 libsasl2-modules libsasl2-modules-sql sasl2-bin libpam-mysql openssl telnet mailutils

During this installation, you will be prompted by the Postfix package configuration. In the first prompt, select “Internet Site”.

In the second prompt, you should enter the domain name of your server, eg. mail.domain.com.

Step 2

Now we need to setup MySQL for the virtual domains and users.

Log into phpMyAdmin and create a new database called “email”.

In the SQL tab of phpMyAdmin, enter the following to create an email admin user. You can change the username and password, but I will use “email_admin” and “email_admin_password” for the purpose of this tutorial.

GRANT SELECT, INSERT, UPDATE, DELETE ON mail.* TO ‘mail_admin’@'localhost’ IDENTIFIED BY ‘mail_admin_password’;
FLUSH PRIVILEGES;

Now select the email database and enter the following in the SQL tab to create tables for virtual domains, mail forwardings, users and transport.

CREATE TABLE domains (domain varchar(50) NOT NULL, PRIMARY KEY (domain));
CREATE TABLE forwardings (source varchar(80) NOT NULL, destination TEXT NOT NULL, PRIMARY KEY (source));
CREATE TABLE users (email varchar(80) NOT NULL, password varchar(20) NOT NULL, PRIMARY KEY (email));
CREATE TABLE transport (domain varchar(128) NOT NULL default ”, transport varchar(128) NOT NULL default ”, UNIQUE KEY domain (domain));

Step 3

Now we’re going to configure the SMTP server (Postfix) to use the MySQL database and tables we just setup.

Create the following files with the following contents.

FILE: /etc/postfix/mysql-virtual_domains.cf
user = email_admin
password = email_admin_password
dbname = email
query = SELECT domain AS virtual FROM domains WHERE domain=’%s’
hosts = 127.0.0.1

FILE: /etc/postfix/mysql-virtual_forwardings.cf
user = email_admin
password = email_admin_password
dbname = email
query = SELECT destination FROM forwardings WHERE source=’%s’
hosts = 127.0.0.1

FILE: /etc/postfix/mysql-virtual_mailboxes.cf
user = email_admin
password = email_admin_password
dbname = email
query = SELECT CONCAT(SUBSTRING_INDEX(email,’@',-1),’/',SUBSTRING_INDEX(email,’@',1),’/') FROM users WHERE email=’%s’
hosts = 127.0.0.1

FILE: /etc/postfix/mysql-virtual_email2email.cf
user = email_admin
password = email_admin_password
dbname = email
query = SELECT email FROM users WHERE email=’%s’
hosts = 127.0.0.1

Now change the permissions and ownership of these files.

chmod o= /etc/postfix/mysql-virtual_*.cf

chgrp postfix /etc/postfix/mysql-virtual_*.cf

Then we create a user and group for mail handling.

groupadd -g 5000 vmail

useradd -g vmail -u 5000 vmail -d /home/vmail -m

Now enter the following commands to complete the Postfix configuration.

sudo postconf -e ‘myhostname = mail.domain.com’

sudo postconf -e ‘mydestination = mail.domain.com, localhost’

sudo postconf -e ‘mynetworks = 127.0.0.0/8′

sudo postconf -e ‘message_size_limit = 30720000′

sudo postconf -e ‘virtual_alias_domains =’

sudo postconf -e ‘virtual_alias_maps = proxy:mysql:/etc/postfix/mysql-virtual_forwardings.cf, mysql:/etc/postfix/mysql-virtual_email2email.cf’

sudo postconf -e ‘virtual_mailbox_domains = proxy:mysql:/etc/postfix/mysql-virtual_domains.cf’

sudo postconf -e ‘virtual_mailbox_maps = proxy:mysql:/etc/postfix/mysql-virtual_mailboxes.cf’

sudo postconf -e ‘virtual_mailbox_base = /home/vmail’

sudo postconf -e ‘virtual_uid_maps = static:5000′

sudo postconf -e ‘virtual_gid_maps = static:5000′

sudo postconf -e ‘smtpd_sasl_auth_enable = yes’

sudo postconf -e ‘broken_sasl_auth_clients = yes’

sudo postconf -e ‘smtpd_sasl_authenticated_header = yes’

sudo postconf -e ‘smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination’

sudo postconf -e ‘smtpd_use_tls = yes’

sudo postconf -e ‘smtpd_tls_cert_file = /etc/postfix/smtpd.cert’

sudo postconf -e ‘smtpd_tls_key_file = /etc/postfix/smtpd.key’

sudo postconf -e ‘virtual_create_maildirsize = yes’

sudo postconf -e ‘virtual_maildir_extended = yes’

sudo postconf -e ‘proxy_read_maps = $local_recipient_maps $mydestination $virtual_alias_maps $virtual_alias_domains $virtual_mailbox_maps $virtual_mailbox_domains $relay_recipient_maps $relay_domains $canonical_maps $sender_canonical_maps $recipient_canonical_maps $relocated_maps $transport_maps $mynetworks $virtual_mailbox_limit_maps’

sudo postconf -e virtual_transport=dovecot

sudo postconf -e dovecot_destination_recipient_limit=1

Step 4

Now we need to create a SSL Certificate for our SMTP server.

cd /etc/postfix

sudo openssl req -new -outform PEM -out smtpd.cert -newkey rsa:2048 -nodes -keyout smtpd.key -keyform PEM -days 365 -x5

You will be prompted to enter a few details. These will show when someone views the details of the certificate. The one to make sure you get right here, is when you’re prompted “Common Name (eg, YOUR name) []:”. This is where you must enter the name of your server, eg. mail.domain.com.

chmod o= /etc/postfix/smtpd.key

Step 5

Now we need to configure saslauthd to use MySQL.

sudo mkdir -p /var/spool/postfix/var/run/saslauthd

Whilst making sure you enter your own username and password where necessary, replace the contents of the following files.

FILE: /etc/default/saslauthd
START=yes
DESC=”SASL Authentication Daemon”
NAME=”saslauthd”
MECHANISMS=”pam”
MECH_OPTIONS=”"
THREADS=5
OPTIONS=”-c -m /var/spool/postfix/var/run/saslauthd -r”

FILE: /etc/pam.d/smtp
auth    required   pam_mysql.so user=email_admin passwd=email_admin_password host=127.0.0.1 db=email table=users usercolumn=email passwdcolumn=password crypt=1
account sufficient pam_mysql.so user=email_admin passwd=email_admin_password host=127.0.0.1 db=email table=users usercolumn=email passwdcolumn=password crypt=1

FILE: /etc/postfix/sasl/smtpd.conf
pwcheck_method: saslauthd
mech_list: plain login
allow_plaintext: true
auxprop_plugin: mysql
sql_hostnames: 127.0.0.1
sql_user: email_admin
sql_passwd: email_admin_password
sql_database: email
sql_select: select password from users where email = ‘%u’

Change file permissions and restart services.

sudo chmod o= /etc/pam.d/smtp

sudo chmod o= /etc/postfix/sasl/smtpd.conf

sudo adduser postfix sasl

sudo service postfix restart

sudo service saslauthd restart

Step 6

Now we need to configure our IMAP server (Dovecot).

Whilst making sure you enter your own username and password where necessary, replace the contents of the following files.

FILE: /etc/postfix/master.cf (append to bottom)
dovecot   unix  -       n       n       -       -       pipe
flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -d ${recipient}

FILE: /etc/dovecot/dovecot.conf
protocols = imap imaps
log_timestamp = “%Y-%m-%d %H:%M:%S ”
mail_location = maildir:/home/vmail/%d/%n/Maildir
ssl_cert_file = /etc/ssl/certs/dovecot.pem
ssl_key_file = /etc/ssl/private/dovecot.pem
namespace private {
separator = .
prefix = INBOX.
inbox = yes
}
protocol lda {
log_path = /home/vmail/dovecot-deliver.log
auth_socket_path = /var/run/dovecot/auth-master
postmaster_address = postmaster@example.com
mail_plugins = sieve
global_script_path = /home/vmail/globalsieverc
}
auth default {
user = root
passdb sql {
args = /etc/dovecot/dovecot-sql.conf
}
userdb static {
args = uid=5000 gid=5000 home=/home/vmail/%d/%n allow_all_users=yes
}
socket listen {
master {
path = /var/run/dovecot/auth-master
mode = 0600
user = vmail
}
client {
path = /var/spool/postfix/private/auth
mode = 0660
user = postfix
group = postfix
}
}
}

FILE: /etc/dovecot/dovecot-sql.conf
driver = mysql
connect = host=127.0.0.1 dbname=email user=email_admin password=email_admin_password
default_pass_scheme = CRYPT
password_query = SELECT email as user, password FROM users WHERE email=’%u’;

Change file permissions and restart services.

sudo chgrp vmail /etc/dovecot/dovecot.conf

sudo chmod g+r /etc/dovecot/dovecot.conf

sudo service dovecot restart

Step 7

Now we simply need to test our IMAP server is working.

telnet localhost imap

If you see output similar to the following, then it’s working correctly.

Trying 127.0.0.1…
Connected to localhost.localdomain.
Escape character is ‘^]’.
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE STARTTLS AUTH=PLAIN] Dovecot ready.

 

Look out for Part 2 in the next day or so, to find out how to setup email addresses and an email client.

Leave a Reply

Required fields are marked *.

*