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.
- Internet Site
- yourdomain.com
- yourdomain
- localhost.localdomain, localhost
- No
- 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 192.168.0.0/24
- 0
- +
- 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.
- yes
- 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
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
The file name is not relevant, use whatever you want.