How To Configure a Mail Server Using Postfix, Dovecot, MySQL, and SpamAssasin

Introduction

In this tutorial, we are going to configure a mail server using Postfix, Dovecot, MySQL and SpamAssassin on Ubuntu 12.04.

Following this tutorial you'll be able to add virtual domains, users, and aliases. Moreover, your virtual server will be secure from spam hub.

Prerequisites

Before setting up your mail server, it's necessary your VPS has the following:

* Domain is forwarding to your server (setup domain)
* MySQL installed and configured (setup mysql)
* User with root privileges (setup new users- omit step 5)
*Configure and identify your FQDN (setup FQDN)

Optional: SSL certificate (setup free signed ssl certificate)

Optional ( Log in as root user )

Installing packages as the root user is useful because you have all privileges.

sudo -i

Introduce your user's password. Once it's successful, you will see that $ symbol changes to #.

Step 1: Install Packages

apt-get install postfix postfix-mysql dovecot-core dovecot-imapd dovecot-lmtpd dovecot-mysql

When Postfix configuration is prompted choose Internet Site:



Postfix configuration will ask about System mail name – you could use your FDQN or main domain.



Step 2: Create a MySQL Database, Virtual Domains, Users and Aliases

After the installation finishes, we are going to create a MySQL database to configure three different tables: one for domains, one for users and the last one for aliases.

We are going to name the database servermail, but you can use whatever name you want.

Create the servermail database:

mysqladmin -p create servermail

Log in as MySQL root user

mysql -u root -p

Enter your MySQL root's password; if it's successful you will see:

mysql >

First we need to create a new user, specific for mail authentication, and we are going to give SELECT permission.

mysql > GRANT SELECT ON servermail.* TO 'usermail'@'127.0.0.1' IDENTIFIED BY 'mailpassword';

After that, we need to reload MySQL privileges to ensure it applies those permissions successfully:

mysql > FLUSH PRIVILEGES;

Finally we need to use the database for creating tables and introduce our data:

mysql> USE servermail;

We are going to create a table for the specific domains recognized as authorized domains.


CREATE TABLE `virtual_domains` (
`id`  INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

We are going to create a table to introduce the users. Here you will add the email address and passwords. It is necessary to associate each user with a domain.

CREATE TABLE `virtual_users` (
`id` INT NOT NULL AUTO_INCREMENT,
`domain_id` INT NOT NULL,
`password` VARCHAR(106) NOT NULL,
`email` VARCHAR(120) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Finally we are going to create a virtual aliases table to specify all the emails that you are going to forward to the other email.


CREATE TABLE `virtual_aliases` (
`id` INT NOT NULL AUTO_INCREMENT,
`domain_id` INT NOT NULL,
`source` varchar(100) NOT NULL,
`destination` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

We have created the three tables successfully. Now we are going to introduce the data.

Virtual Domains

Here we are going to introduce your domains inside the virtual_domains table. You can add all the domains you want, but in this tutorial we are going to introduce just the primary domain (example.com) and your FQDN (hostname.example.com).


INSERT INTO `servermail`.`virtual_domains`
(`id` ,`name`)
VALUES
('1', 'example.com'),
('2', 'hostname.example.com');

Virtual Emails

We are going to introduce the email address and passwords associated for each domain. Make sure you change all the info with your specific information.


INSERT INTO `servermail`.`virtual_users`
(`id`, `domain_id`, `password` , `email`)
VALUES
('1', '1', ENCRYPT('firstpassword', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), '[email protected]'),
('2', '1', ENCRYPT('secondpassword', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), '[email protected]');

Virtual Aliases

We are going to introduce the email address (source) that we are going to forward to the other email address (destination).


INSERT INTO `servermail`.`virtual_aliases`
(`id`, `domain_id`, `source`, `destination`)
VALUES
('1', '1', '[email protected]', '[email protected]');

Exit MySQL

 mysql > exit

Step 3: Configure Postfix

We are going to configure Postfix to handle the SMTP connections and send the messages for each user introduced in the MySQL Database.

First we need to create a copy of the default file, in case you want to revert to the default configuration.

cp /etc/postfix/main.cf /etc/postfix/main.cf.orig

Open the main.cf file to modify it:

nano /etc/postfix/main.cf

First we need to comment the TLS Parameters and append other parameters. In this tutorial, we are using the Free SSL certificates and the paths that are suggested in the tutorial (link), but you could modify depending your personal configurations.


# TLS parameters
#smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
#smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
#smtpd_use_tls=yes
#smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
#smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache 
smtpd_tls_cert_file=/etc/ssl/certs/dovecot.pem
smtpd_tls_key_file=/etc/ssl/private/dovecot.pem
smtpd_use_tls=yes
smtpd_tls_auth_only = yes

Then we are going to append the following parameters below the TLS settings that we have changed in the previous step:


smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions =
permit_sasl_authenticated,
permit_mynetworks,
reject_unauth_destination

We need to comment the mydestination default settings and replace it with localhost. This change allows your VPS to use the virtual domains inside the MySQL table.


#mydestination = example.com, hostname.example.com, localhost.example.com, localhost
mydestination = localhost 

Verify that myhostname parameter is set with your FQDN.


myhostname = hostname.example.com

Append the following line for local mail delivery to all virtual domains listed inside the MySQL table.

virtual_transport = lmtp:unix:private/dovecot-lmtp

Finally, we need to add these three parameters to tell Postfix to configure the virtual domains, users and aliases.


virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql-virtual-alias-maps.cf

Note: Compare these changes with this file to detect mistakes or errors:

https://www.dropbox.com/s/x9fpm9v1dr86gkw/etc-postfix-main.cf.txt

We are going to create the final three files that we append in the main.cf file to tell Postfix how to connect with MySQL.

First we need to create the mysql-virtual-mailbox-domains.cf file. It's necessary to change the values depending your personal configuration.


nano /etc/postfix/mysql-virtual-mailbox-domains.cf
		
user = usermail
password = mailpassword
hosts = 127.0.0.1
dbname = servermail
query = SELECT 1 FROM virtual_domains WHERE name='%s'

Then we need to restart Postfix.


service postfix restart

We need to ensure that Postfix finds your domain, so we need to test it with the following command. If it is successful, it should returns 1:


postmap -q example.com mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf

Then we need to create the mysql-virtual-mailbox-maps.cf file.


nano /etc/postfix/mysql-virtual-mailbox-maps.cf 
		
user = usermail
password = mailpassword
hosts = 127.0.0.1
dbname = servermail
query = SELECT 1 FROM virtual_users WHERE email='%s'

We need to restart Postfix again.

service postfix restart

At this moment we are going to ensure Postfix finds your first email address with the following command. It should return 1 if it's successful:

postmap -q [email protected] mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf

Finally, we are going to create the last file to configure the connection between Postfix and MySQL.


nano /etc/postfix/mysql-virtual-alias-maps.cf
		
user = usermail
password = mailpassword
hosts = 127.0.0.1
dbname = servermail
query = SELECT destination FROM virtual_aliases WHERE source='%s'

Restart Postfix

service postfix restart

We need to verify Postfix can find your aliases. Enter the following command and it should return the mail that's forwarded to the alias:

postmap -q [email protected] mysql:/etc/postfix/mysql-virtual-alias-maps.cf

If you want to enable port 587 to connect securely with email clients, it is necessary to modify the /etc/postfix/master.cf file


nano /etc/postfix/master.cf

We need to uncomment these lines and append other parameters:


submission inet n       -       -       -       -       smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject

In some cases, we need to restart Postfix to ensure port 587 is open.

service postfix restart

Note: You can use this tool to scan your domain ports and verify that port 25 and 587 are open (http://mxtoolbox.com/SuperTool.aspx)

Step 4: Configure Dovecot

We are going to copy the 7 files we're going to modify, so that you could revert it to default if you needed to. Enter the following commands one by one:


        
  • 15 Users Found This Useful
  • Was this answer helpful?

    Related Articles

    Cheapest Linux VPS Hosting in the world!

    Access the best web hosting vps to enhance the efficiencyWeb hosting is an obligatory service if...

    Virtual Hosting with Apache Linux Server

    How to Setup Multiple Hosts on ApacheIt's the example to configure virtual hostings. Following...

    Install MySQL for Database Server on CentOS VPS

     Install MySQL for Database Server. [root@www ~]# yum -y install mysql-server...

    Add a HardDrive to Your Linux VPS

     This is an example to create a partition when you add a new hard drive. root@dlp:~#...

    HowTo: Shrink size of ext4 LVM logical volume

    HowTo: Shrink size of ext4 LVM logical volume LVM, the Logical Volume Manager, is...