Serverspace launched CDN
August 13, 2022
Updated February 6, 2023

How to install and setup mail server on ubuntu 18.04

Linux Ubuntu


This guide will help you configure your mail server with Postfix, Dovecot, MySQL and SpamAssassin in Ubuntu 18.04. This setup will allow you to add virtual domains, users and aliases and protect the virtual server from spam.


  • A domain directed towards the server.
  • Pre-installed and configured MySQL DBMS.
  • Root rights.
  • Configured FQDN.
  • Optional: SSL certificate.

Install Packages:

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

When prompted to configure Postfix, select Internet Site:1

The Postfix configuration will ask about the system mail name - you can use your FDQN or the primary domain.
FQDN is a domain name with no ambiguities in the definition. It includes the names of all parent domains in the DNS hierarchy. In DNS and, most significantly, in zone files, FQDNs are terminated with a dot, i.e. include the root domain name, which is nameless.


Creating new database (MySQL) + Users

After the installation is complete, we will create a MySQL database to set up three different tables: one for domains, the other for users, and the last for aliases.

We call the database "spacemail", but you can use any name as you like.

Create the spacemail database:

mysqladmin -p create spacemail

Log in as MySQL root user

mysql -u root -p

Enter the MySQL root password; if successful, you will see the "mysql" console.

At first we need to add a new user, for mail authentication, and give him permission "SELECT"

mysql > GRANT SELECT ON spacemail.* TO 'userspace'@'' IDENTIFIED BY 'mailpassword';

After that, we need to reload MySQL privileges to make sure that it has successfully applied these permissions:


Finally, we need to use the database to create tables and enter our data:

mysql> USE spacemail;

We need to create new table for domains recognized as authorized domains.

CREATE TABLE `virtual_domains` (
`name` VARCHAR(50) NOT NULL,

Creating new table for introduce new users.  At this table you need to add your email and password. You should associate each user with a domain.

CREATE TABLE `virtual_users` (
`domain_id` INT NOT NULL,
`password` VARCHAR(106) NOT NULL,
`email` VARCHAR(120) NOT NULL,
UNIQUE KEY `email` (`email`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE

We will create a table of virtual aliases to specify the mail and any emails you intend to forward to another one.

CREATE TABLE `virtual_aliases` (
`domain_id` INT NOT NULL,
`source` varchar(100) NOT NULL,
`destination` varchar(100) NOT NULL,
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE

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

Virtual Domains

Here we are going to enter your domains into the virtual_domains table. You can add as many domains as you like, but in this guide we will only enter the primary domain ( and your FQDN (

INSERT INTO `spacemail`.`virtual_domains`
(`id` ,`name`)
('1', ''),
('2', '');

Virtual Emails

We are going to enter the email addresses and passwords associated with each domain. Make sure you change all the information to your specific one.

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

Virtual aliases

We are going to enter an email address (source) that we are going to forward to another email address (destination).

INSERT INTO `spacemail`.`virtual_aliases`
(`id`, `domain_id`, `source`, `destination`)
('1', '1', '', '');

Now u need to exit from database:


Postfix settings

We are going to configure Postfix to handle SMTP connections and send messages for each user entered 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/ /etc/postfix/

Open the file with any text editor to change it:

sudo vi /etc/postfix/

First we need to comment out the TLS parameters and add other parameters. We will also need SSL certificates. You can get them for free.

# TLS parameters
#smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
#smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_tls_auth_only = yes

We will then add the following settings below the TLS settings we changed in the previous step:

smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions =

We need to comment out the default mydestination setting and replace it with localhost. This change will allow your VPS to use virtual domains inside the MySQL table.

#mydestination =,,, localhost
mydestination = localhost

Make sure the myhostname parameter is set to your FQDN.

myhostname =

Add the following line for local mail delivery to all virtual domains listed in the MySQL table.

virtual_transport = lmtp:unix:private/dovecot-lmtp

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

virtual_mailbox_domains = mysql:/etc/postfix/
virtual_mailbox_maps = mysql:/etc/postfix/
virtual_alias_maps = mysql:/etc/postfix/

We will create the last three files, which we will add to the file to tell Postfix how to connect to MySQL Database.

First we need to create a file You will need to modify the values depending on your personal configuration.

nano /etc/postfix/

user = usermail
password = mailpassword
hosts =
dbname = spacemail
query = SELECT 1 FROM virtual_domains WHERE name='%s'

Postfix needs to be restarted.

service postfix restart

We need to make sure that Postfix finds your domain, so we need to check this with the following command. If successful, the command should return a value of 1:

postmap -q mysql:/etc/postfix/

Then we need to create a file.

nano /etc/postfix/

user = usermail
password = mailpassword
hosts =
dbname = spacemail
query = SELECT 1 FROM virtual_users WHERE email='%s'

Rebooting Postfix again

service postfix restart

At this point we need to make sure that Postfix has found the first email address using the following command. If successful, it should return 1:

postmap -q mysql:/etc/postfix/

We will create one last file to set up the connection between Postfix and MySQL.

nano /etc/postfix/

user = usermail
password = mailpassword
hosts =
dbname = spacemail
query = SELECT destination FROM virtual_aliases WHERE source='%s'

Postfix restart

service postfix restart

We need to check that Postfix can find your aliases. Enter the following command and it should return mail redirected to an alias:

postmap -q mysql:/etc/postfix/

If you want to enable port 587 for secure connection to email clients, you need to modify /etc/postfix/

nano /etc/postfix/

We need to uncomment these lines and add 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 that port 587 is open.

service postfix restart

Setting up Dovecot

We will copy the 7 files we will be modifying so that we can reset everything to default if necessary. Enter the following commands in turn.

cp /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.orig
cp /etc/dovecot/conf.d/10-mail.conf /etc/dovecot/conf.d/10-mail.conf.orig
cp /etc/dovecot/conf.d/10-auth.conf /etc/dovecot/conf.d/10-auth.conf.orig
cp /etc/dovecot/dovecot-sql.conf.ext /etc/dovecot/dovecot-sql.conf.ext.orig
cp /etc/dovecot/conf.d/10-master.conf /etc/dovecot/conf.d/10-master.conf.orig
cp /etc/dovecot/conf.d/10-ssl.conf /etc/dovecot/conf.d/10-ssl.conf.orig

Editing the configuration file from Dovecot.

nano /etc/dovecot/dovecot.conf

Make sure this parameter is not commented out.

!include conf.d/*.conf

We are going to include protocols (add pop3 if you want) below the line !include_try /usr/share/dovecot/protocols.d/*.protocol

!include_try /usr/share/dovecot/protocols.d/*.protocol
protocols = imap lmtp

Edit the mail configuration file:

nano /etc/dovecot/conf.d/10-mail.conf

Find the "mail_location" line, comment it out and put in the following parameter:

mail_location = maildir:/var/mail/vhosts/%d/%n

Find the "mail_privileged_group" line, comment it out and add the mail parameter as follows:

mail_privileged_group = mail

Verify permissions

Use this command:

ls -ld /var/mail

Make sure that the permissions look as follows:

drwxrwsr-x 3 root vmail 4096 Jan 24 21:23 /var/mail

We are going to create a folder for each domain that we register in the MySQL table:

mkdir -p /var/mail/vhosts/

Create a vmail user and group with ID 5000

groupadd -g 5000 vmail
useradd -g vmail -u 5000 vmail -d /var/mail

We need to change the owner of the /var/mail folder to the user vmail.

chown -R vmail:vmail /var/mail

then we need to edit the file /etc/dovecot/conf.d/10-auth.conf:

nano /etc/dovecot/conf.d/10-auth.conf

Authenticate the plain text and add this line:

disable_plaintext_auth = yes

Change the auth_mechanisms parameter:

auth_mechanisms = plain login

Comment this line:

#!include auth-system.conf.ext

Enable MySQL authorisation by commenting out this line:

!include auth-sql.conf.ext
nano /etc/dovecot/conf.d/auth-sql.conf.ext

We need to create an /etc/dovecot/dovecot-sql.conf.ext file with your authentication information:
Enter the following code in the file:

passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
userdb {
driver = static
args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n

We need to change the file /etc/dovecot/dovecot-sql.conf.ext with our MySQL user information:

nano /etc/dovecot/dovecot-sql.conf.ext

Uncomment the driver parameter and set mysql as the parameter:

driver = mysql

Comment out the connect line and enter the MySQL-specific information:

connect = host= dbname=spacemail user=usermail password=mailpassword

Comment out the default_pass_scheme line and change it to SHA-512.

default_pass_scheme = SHA512-CRYPT

Comment out the password_query line and add this information:

password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';

Change the owner and group of the dovecot folder to the user vmail:

chown -R vmail:dovecot /etc/dovecot
chmod -R o-rwx /etc/dovecot

Open and modify /etc/dovecot/conf.d/10-master.conf (be careful as various parameters will be changed).

nano /etc/dovecot/conf.d/10-master.conf

##Uncomment inet_listener_imap and modify to port 0
service imap-login {
inet_listener imap {
port = 0

#Create LMTP socket and this configurations
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
#inet_listener lmtp {
# Avoid making LMTP visible for the entire internet
#address =
#port =

Change the unix_listener parameter in service_auth as follows:

service auth {

unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix

unix_listener auth-userdb {
mode = 0600
user = vmail
#group =

#unix_listener /var/spool/postfix/private/auth {
# mode = 0666

user = dovecot

Change the auth-worker service as follows:

service auth-worker {
# Auth worker process is run as root by default, so that it can access
# /etc/shadow. If this isn't necessary, the user should be changed to
# $default_internal_user.
user = vmail

The SSL configuration file from Dovecot must be changed (Skip if you will use the default configuration)

# nano /etc/dovecot/conf.d/10-ssl.conf

Change the ssl parameter to the required one:

ssl = required

And change the path for ssl_cert and ssl_key:

ssl_cert = </etc/ssl/certs/dovecot.pem
ssl_key = </etc/ssl/private/dovecot.pem

Restart Dovecot:

service dovecot restart

You should check that port 993 is open and working (in case you have enabled pop3; you should also check port 995).

telnet 993

Configure SpamAssassin

First we need to install SpamAssassin.

apt-get install spamassassin spamc

Then we need to create a user for SpamAssassin.

adduser spamd --disabled-login

To successfully configure SpamAssassin, it's necessary to open and modify the configuration settings.

nano /etc/default/spamassassin

We need to change the ENABLED parameter to enable SpamAssassin daemon.


We need to configure the home and options settings.

OPTIONS="--create-prefs --max-children 5 --username spamd --helper-home-dir ${SPAMD_HOME} -s ${SPAMD_HOME}spamd.log"

We then need to specify the PID_File parameter as follows:


It is required to specify that SpamAssassin rules will be updated automatically.


We need to open the file /etc/spamassassin/ to configure the anti-spam rules.

nano /etc/spamassassin/

SpamAssassin will evaluate each email and if it determines that the email is greater than 5.0 when checking for spam, it will automatically be considered spam. You can use the following settings to configure the anti-spam rules:

rewrite_header Subject ***** SPAM _SCORE_ *****
report_safe 0
required_score 5.0
use_bayes 1
use_bayes_rules 1
bayes_auto_learn 1
skip_rbl_checks 0
use_razor2 0
use_dcc 0
use_pyzor 0

We need to modify the Postfix file /etc/postfix/ to specify that each email will be checked by SpamAssassin.

nano /etc/postfix/

Then we need to find the next line and add the spamassassin filter:

smtp inet n - - - - smtpd
-o content_filter=spamassassin

The following parameters must be added:

spamassassin unix - n n - - pipe
user=spamd argv=/usr/bin/spamc -f -e
/usr/sbin/sendmail -oi -f ${sender} ${recipient}

SpamAssassin must be started and Postfix restarted to start checking spam from the emails.

service spamassassin start
service postfix restart

You have successfully set up a mail server with Postfix and Dovecot with MySQL authentication and spam filtering using SpamAssassin!

4 out of 5
Аverage rating : 4.2
Rated by: 11
1101 CT Amsterdam The Netherlands, Herikerbergweg 292
+31 20 262-33-82
700 300
700 300
We use cookies to make your experience on the Serverspace better. By continuing to browse our website, you agree to our
Use of Cookies and Privacy Policy.