How To Configure a Mail Server Using Postfix and Dovecot on Ubuntu 14.04 LTS

This tutorial explains how to setup mail server on Ubuntu 14.04 using Postfix and Dovecot. It’s based on few other tutorials and does not pretend to show you all the best practices. I am writing this tutorial because it’s 99.9% sure that I will forget how I configured my own mail server very very soon and I have to write down all the info while it’s still fresh in my head.

Ok, let’s start to work!

Introduction

In this tutorial, we are going to configure a mail server using Postfix and Dovecot on Ubuntu 14.04. Following this tutorial you’ll be able to send and receive emails from all your domains using POP3/IMAP and SMTP, as well as using aliases to forward mails.

Requirements

Before setting up your mail server, it’s necessary your server to met the following requirements:

  • A domain is forwarding to your server (setup domain)
  • You have a user with root privileges
  • Configure and identify your Fully Qualified Domain Name /FQDN/, i.e. setup FQDN
  • Optional: SSL certificate (setup free signed ssl certificate)

Step 1: Installing and Configuring Postfix

In this setup I assume that your domain is yourdomain.com and it has a valid MX record setup as mail.yourdomain.com. Remember to replace yourdomain.com with your actual domain in all code samples bellow. Also I assume that you know what an MX record is. To find out MX your type in a terminal:

$ dig mx yourdomain.com

Assign static IP and hostname and add a host entry for the host name.
Assign hostname if you haven’t done this already. Type the following command to open /etc/hostname for editing and type in your desired hostname.

$ sudo nano /etc/hostname

Then add a hostentry in /etc/hosts

127.0.0.1 mail.yourdomain.com

Update the repositories.

$ sudo apt-get update

… and finally install Postfix and its dependencies. Press enter for all prompted questions during the installation. We will configure Postfx in the next step.

$ sudo apt-get install postfix

After installation issue the below command to configure Postfix:

$ sudo dpkg-reconfigure postfix

Now you will be prompted for set of details. Choose the following values and replace yourdomain.com with your domain name.

  1. Internet Site
  2. yourdomain.com
  3. yourdomain
  4. localhost.localdomain, localhost
  5. No
  6. 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 192.168.0.0/24
  7. 0
  8. +
  9. all

Now configure Postfix for SMTP-AUTH using Dovecot SASL by adding the below lines to postfix config file /etc/postfix/main.cf .

broken_sasl_auth_clients = yes
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination
smtp_tls_security_level = may
smtpd_tls_security_level = may
smtp_tls_note_starttls_offer = yes
smtpd_tls_loglevel = 1
smtpd_tls_received_header = yes

virtual_mailbox_domains = /etc/postfix/vhosts
virtual_mailbox_base = /home/vmail
virtual_mailbox_maps = hash:/etc/postfix/vmaps
virtual_minimum_uid = 1000
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000

/etc/postfix/vhosts is a text file called vhosts but you can name it anything you want. Inside of it will be a simple one-column list of all the domains you are hosting. Open the file for editing and add your domains there.

$ sudo nano /etc/postfix/vhosts

Obviously, use your own domain names instead of the domain examples:

domain1.com
domain2.com

The next line virtual_mailbox_base specifies the base directory where the mail will be stored. Again, you can name it anything you want. In our case it will be the “vmail” – a subdirectory of the owner’s home directory /home/vmail

The third line points to a text file named ”vmaps”. This is a two column text file. The first column specifies a virtual email address. The second column specifies the person’s mailbox location. Just like with real domain hosting, if you specify a / at the end of the location, it designates a Maildir format. (If not, it is mbox.) In this Howto we are using the Maildir format.

Setup this file:

$ sudo nano /etc/postfix/vmaps

The format should look like:

info@domain1.com domain1.com/info/
alias@domain1.com domain1.com/info/
sales@domain1.com domain1.com/sales/
info@domain2.com domain2.com/info/
sales@domain2.com domain2.com/sales/

Note: To make an alias, map to same folder as another user.

Convert vmaps into a hash file by running:

$ sudo postmap /etc/postfix/vmaps

Remember to execute the above command every time when you add a new map.

Now you should generate a digital certificate for TLS. Issue the commands one by one and provide details as per your domain.

$ openssl genrsa -des3 -out server.key 2048
$ openssl rsa -in server.key -out server.key.insecure
$ mv server.key server.key.secure
$ mv server.key.insecure server.key
$ openssl req -new -key server.key -out server.csr
$ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
$ sudo cp server.crt /etc/ssl/certs
$ sudo cp server.key /etc/ssl/private

Now configure certificate path

$ sudo postconf -e 'smtpd_tls_key_file = /etc/ssl/private/server.key'
$ sudo postconf -e 'smtpd_tls_cert_file = /etc/ssl/certs/server.crt'

The next step is enabling submission for smtp access through 587. Open /etc/postfix/master.cf file and uncomment below lines:

submission inet n - - - - smtpd
 -o syslog_name=postfix/submission
 -o smtpd_tls_security_level=encrypt
 -o smtpd_sasl_auth_enable=yes
 -o smtpd_sasl_type=dovecot
 -o smtpd_sasl_path=private/auth_client
 -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
 -o milter_macro_daemon_name=ORIGINATING

and then execute

$ sudo echo "mech_list: cram-md5" > /etc/postfix/sasl/smtpd.conf

to finish configuring Postfix for SASL.
Restart Postfix to make the changes take effect.

$ sudo service postfix restart

Installing mailutils package is recommended. It allows you to test and debug quick and easy using set of command line utilities.

$ sudo apt-get install mailutils

You can now test virtual mailbox setup. The directory structure for a particular user is created when he or she gets his/her first mail.

Send a mail to info@domain1.com from the command line using the mail utility:

$ mail info@domain1.com

…and check the mailbox:

$ cd /home/vmail/domain1/info/new
$ ls 

You should see a mail file there. If so, you’ve done it!

Step 2: installing and Configuring Dovecot SASL

$ sudo apt-get install dovecot-common

Issue the following values for the prompts during installation.

  1. yes
  2. mail.yourdomain.com

Make changes to the files as follows.
Open /etc/dovecot/conf.d/10-master.conf file and find # Postfix smtp-auth line ( line no:95 ) and add the below lines:

# Postfix smtp-auth
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = postfix
}

Open /etc/dovecot/conf.d/10-auth.conf file and find (line no:100)

auth_mechanisms = plain

and replace with

auth_mechanisms = plain cram-md5

Then remove ‘#’ to uncomment and use passwd-file:

!include auth-passwdfile.conf.ext

In conf.d/auth-passwdfile.conf.ext you should have:

passdb {
 driver = passwd-file
 args = scheme=CRYPT username_format=%u /etc/dovecot/passwd
}

userdb {
 driver = passwd-file
 args = username_format=%u /etc/dovecot/users
}

The files /etc/dovecot/passwd and /etc/dovecot/users are similar to the /etc/passwd and /etc/shadow system files.

The format of these files is similar to this:

# /etc/dovecot/users:
info@domain1.com::5000:5000::/home/vmail/domain1.com/:/bin/false::
# /etc/dovecot/passwd:
info@domain1.com:$1$G/FqlOG5$Vj0xmc9fKY.UVr8OWr/7C1

The 5000:5000 corresponds to the uid and gid of the “virtual” called vmail (which owns all the mailboxes in the system). The home directory includes everything but the word before the @ in the email address.

Note: It is possible to use a single file for the user/passwd with the following format:

# /etc/dovecot/passwd:
info@domain1.com:$1$G/FqlOG5$Vj0xmc9fKY.UVr8OWr/7C1:5000:5000::/home/vmail/domain1.com/:/bin/false::

Restart postfix and dovecot services

$ sudo service postfix restart
$ sudo service dovecot restart

Now test SMTP-AUTH and smtp/pop3 port access. Type the below command and should get below response.

$ telnet mail.yourdomain.com smtp
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mail.yourdomain.com ESMTP Postfix (Ubuntu)

now type ehlo mail.yourdomain.com and should get below response , please make sure you get lines 4-6.

ehlo mail.yourdomain.com
250-mail.yourdomain.com
--------
250-STARTTLS
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
---------
250 DSN

and try the same with port 587 (telnet mail.yourdomain.com 587).
Postfix configuration is over, continue for dovecot installation.

Step 3: Installing and configuring dovecot

Install dovecot using the below command

$ sudo apt-get install dovecot-imapd dovecot-pop3d

Now configure mailbox. Open /etc/dovecot/conf.d/10-mail.conf file and find (Line no:30 )

mail_location = mbox:~/mail:INBOX=/var/mail/%u

and replace with

mail_location = maildir:/home/vmail/%d/%

The line “mail_location = maildir:/home/vmail/%d/%n” is particularly important. In our virtual hosting set up, the way we distinguish one user from another is to have them log in with their full email address. For example, when the email account is “info@domain1.com”, Dovecot does some guessing on its end about your user name. If it just sees something like “info”, it sets a variable called “%n”to “info”. If it sees “info@domain1.com”, it will split it up and set “%d” to domain1.com and “%n” to “info”. Using that paradigm, if we replace the variables in this line , we get something like: maildir:/home/vmail/domain1.com/info

Now change pop3_uidl_format to prevent issues using Outlook 2003. Open /etc/dovecot/conf.d/20-pop3.conf file and find and uncomment the below line ( Line no : 50 )

pop3_uidl_format = %08Xu%08Xv

The next step is to enable SSL. Open /etc/dovecot/conf.d/10-ssl.conf file, find and uncomment the below line ( Line no : 6 )

ssl = yes

Restart dovecot service.

$ sudo service dovecot restart

Now test pop3 and imap port access using the telnet command.

$ telnet mail.yourdomain.com 110
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
+OK Dovecot (Ubuntu) ready.

Repeat the same for 995,993,143 ports or check for listening ports using netstat command .

$ netstat -nl4

You should get the result like below.

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:993 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:995 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:10026 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:587 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:110 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:143 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN

Create Dovecot Users

There are no commands like useradd and passwd to add users and passwords for our mail system. A bash script provides a small and quick solution.
Files:

  • /etc/dovecot/users – Similar to /etc/passwd
  • /etc/dovecot/passwd – Similar to /etc/shadow
  • /etc/postfix/vmaps – Map virtual users to mail directory (for postfix). If changes are made, use postmap /etc/postfix/vmaps && service postfix reload.

Scripts to Add and Delete Users

Create file:

$ sudo nano /usr/local/sbin/adddovecotuser 

Add the following code segment and save the file:

#!/bin/sh
if [ ! $# = 1 ]
 then
 echo "Usage: $0 username@domain"
 exit 1
 else
 user=`echo "$1" | cut -f1 -d "@"`
 domain=`echo "$1" | cut -s -f2 -d "@"`
 if [ -x $domain ]
 then
 echo "No domain given\nUsage: $0 username@domain"
 exit 2
 fi
 echo "Adding user $user@$domain to /etc/dovecot/users"
 echo "$user@$domain::5000:5000::/home/vmail/$domain/$user/:/bin/false::" >> /etc/dovecot/users

# Create the needed Maildir directories
 echo "Creating user directory /home/vmail/$domain/$user"
 # maildirmake.dovecot does only chown on user directory, we'll create domain directory instead
 if [ ! -x /home/vmail/$domain ]
 then
 mkdir /home/vmail/$domain
 chown 5000:5000 /home/vmail/$domain
 chmod 700 /home/vmail/$domain
 fi
 /usr/bin/maildirmake.dovecot /home/vmail/$domain/$user 5000:5000
 # Also make folders for Drafts, Sent, Junk and Trash
 /usr/bin/maildirmake.dovecot /home/vmail/$domain/$user/.Drafts 5000:5000
 /usr/bin/maildirmake.dovecot /home/vmail/$domain/$user/.Sent 5000:5000
 /usr/bin/maildirmake.dovecot /home/vmail/$domain/$user/.Junk 5000:5000
 /usr/bin/maildirmake.dovecot /home/vmail/$domain/$user/.Trash 5000:5000

# To add user to Postfix virtual map file and relode Postfix
 echo "Adding user to /etc/postfix/vmaps"
 echo $1 $domain/$user/ >> /etc/postfix/vmaps
 postmap /etc/postfix/vmaps
 postfix reload
fi
echo "\nCreate a password for the new email user"
#SWAP THE FOLLOWING passwd LINES IF USING A UBUNTU VERSION PRIOR TO 12.04
#passwd=`dovecotpw`
passwd=`doveadm pw -u $user`
echo "Adding password for $user@$domain to /etc/dovecot/passwd"
if [ ! -x /etc/dovecot/passwd ]
 then
 touch /etc/dovecot/passwd
 chmod 640 /etc/dovecot/passwd
fi
echo "$user@$domain:$passwd" >> /etc/dovecot/passwd

exit 0

Make the file executable:

$ sudo chmod +x /usr/local/sbin/adddovecotuser

Add a user like this:

$ sudo adddovecotuser info@domain1.com

We’ll create one for deleting users too:

$ sudo nano /usr/local/sbin/deldovecotuser

Add the following code segment and save the file:

 #!/bin/bash
#
# deldovecotuser - for deleting virtual dovecot users
#
if [ ! $# = 1 ]
 then
 echo -e "Usage: $0 username@domain"
 exit 1
 else
 user=`echo "$1" | cut -f1 -d "@"`
 domain=`echo "$1" | cut -s -f2 -d "@"`
 if [ -x $domain ]
 then
 echo -e "No domain given\nUsage: $0 username@domain: "
 exit 2
 fi
fi
read -n 1 -p "Delete user $user@$domain from dovecot? [Y/N]? "
echo
case $REPLY in
 y | Y)
 new_users=`grep -v $user@$domain /etc/dovecot/users`
 new_passwd=`grep -v $user@$domain /etc/dovecot/passwd`
 new_vmaps=`grep -v $user@$domain /etc/postfix/vmaps`
 echo "Deleting $user@$domain from /etc/dovecot/users"
 echo "$new_users" > /etc/dovecot/users
 echo "Deleting $user@$domain from /etc/dovecot/passwd"
 echo "$new_passwd" > /etc/dovecot/passwd
 echo "Deleting $user@$domain from /etc/postfix/vmaps"
 echo "$new_vmaps" > /etc/postfix/vmaps
 postmap /etc/postfix/vmaps
 postfix reload
 read -n1 -p "Delete all files in /home/vmail/$domain/$user? [Y/N]? " DELETE
 echo
 case $DELETE in
 y | Y)
 echo "Deleting files in /home/vmail/$domain/$user"
 rm -fr /home/vmail/$domain/$user
 ;;
 * )
 echo "Not deleting files in /home/vmail/$domain/$user"
 ;;
 esac
 ;;
 * )
 echo "Aborting..."
 ;;
esac

Make the file executable:

$ sudo chmod +x /usr/local/sbin/deldovecotuser

Delete a user like this:

$ sudo deldovecotuser info@domain1.com

To restart Devecot again

$ sudo service dovecot restart

Now mail server is ready, you can send and receive mail using the server.
I hope that you know how to configure a email client like Thunderbird, yeah?

This tutorial is based on the following articles

2 thoughts on “How To Configure a Mail Server Using Postfix and Dovecot on Ubuntu 14.04 LTS

  1. Nick Heywood

    Hi Vladimir,

    I\’ve followed your tutorial, and it\’s excellent, thank you very much.

    I\’m not able to get a mail client to authenticate and I suspect it\’s a problem with the generation of SSL Certs.

    In the \”Generate SSL Certificates\” section you mention…

    openssl genrsa -des3 -out server.key 2048

    is the
    server.key ….
    mail.domain.key or
    domain.key ?

    Thank you.
    Regards
    Nick Heywood

Comments are closed.