Install Postfix and Postfix Admin With Dovecot

In this blog we will learn how to install postfix, postfix admin and dovecot from scratch in Ubuntu 16.04

What is Postfix?

Postfix is a Linux utility to send and receive emails for the domain(s). You can say it MTA (Mail Transport Agent)

Postfix is a modular MTA, it supports many 3rd party services to enhance its features like as Spamassassin, policyd, dovecot etc.

Text and image block

Presumptions for this guide.

  1.  You have enough knowledge of Linux console, Linux commands, installation of apps in Linux console.

  2. You have access to a dedicated server or VPS, you have root access or sudo access.

  3. You have a working domain pointing to your machine (VPS or dedicated server's IP.).

  4. You have freshly installed Ubuntu 16.04 LTS.

  5. You have public IP for your dedicated server / VPS.

  6. We assume that our Public IP is 192.168.10.120 and our domain name is example.com. Please be clever and use your own domain name and IP address while copying commands from this guide.

  7. We are using root user in this guide, if you are using other users with sudo privileges, please be clever to add sudo in each command below or simply su to root user before starting the installation.

  8. We are using VIM for the text editor, if you are not familiar with VIM you can read here how to install and use VIM for text editing, you can use any other text editor too eg NANO.

  9. I assume that your DNS entries are proper and populated to the world, example DNS entries can be seen here in this table.

Minimum Entries Required for DNS


Record NameType and priorityValue
fpadmin.example.comA192.168.10.120
mail.example.comA192.168.10.120
example.comMX : 5mail.expertpk.com


What we are going to do?

We are going to install and configure the following apps.

Nginx web server: (One can use apache2 or any other light version but this guide is for Nginx. I had also written a great article for Nginx here, you can read it to properly configure Nginx for virtual hosting.

SQLite3: I am using SQlite3 for SQL server, one can use any other SQL server eg MySQL, PostgreSQL etc but this guide will cover SQLite3 only.

Postfix Admin: Postfix Admin is a web GUI for postfix, it is used to manage postfix from the web-based graphical user interface. It is a very handy app if you prefer to work in GUI.

Postfix: You are reading this article, its mean you have enough information about postfix. You can read the detailed information here if you want but simply it is an MTA (Mail Transport Agent).

Dovecot: Dovecot is an IMAP and POP3 email server, written with security primarily in mind. 

Spamassassin: SpamAssassin is an anti-spam platform giving system administrators a filter to classify email and block spammers.


 Enough intro? Let's begin the ride. (Part One)

Step One: Login to your VPS / Dedicated Server via SSH.

If you are a windows user or at reading this guide from a windows machine, you should have a good ssh client eg Putty, you can get it from this link. I assume that you are using Linux. Open a terminal and type following command.

ssh root@example.com

If you are logging into this VPS first time, your ssh client may ask your permission to add ssh key fingerprint in your system, simply type yes. Then it will prompt you for the password (or you can configure ssh key to sign in to your VPS without a password by reading this article. Enter your password and it will log you into your VPS.

Step Two: Update your OS (Ubuntu 16.04) by typing following commands.

apt update & apt -y upgrade

It will take some time to finish this process.

Step 3: Create a new system user, we will use this user for security reasons. This user will be the owner of all Mailboxes

useradd -r -u 150 -g mail -d /var/expertpk -s /sbin/nologin -c "Virtual Mail User" expertpk

Step 4: Create a directory for Mailboxes and set its permissions.

mkdir -p /var/expertpk
chmod -R 770 /var/expertpk
chown -R expertpk:mail /var/expertpk

Step 5: Install Vim, PHP 7.0, required PHP modules, SQLite3, Nginx, Postfix, dovecot, and its dependencies. 

apt -y install dbconfig-common sqlite3 php-fpm php-cli php7.0-mbstring php7.0-imap php7.0-sqlite3 nginx wget \
dovecot-imapd dovecot-lmtpd dovecot-pop3d dovecot-sqlite

 Step 6: Install postfix. 

apt - y install postfix

It will ask you for the general type of email server, select "Internet Mail", then it will ask you system mail name, type example.com, then it will ask you about postmaster address, type postmaster@example.com

Step 7: Please get a  free Letsencrypt SSL certificate for our mail server and web server. To know the process just follow this guide. (If you had a paid SSL certificate, then you can simply skip this step. Please copy your certificate and files in appropriate locations after getting them.

The necessary installation has been finished. It is time to configure our apps. 


Configuration - (Part 2)

First of all, we will configure the web server and postfix admin.

The configuration of Nginx & Postfix Admin: Stop Nginx service.

systemctl stop nginx

Now we will create our virtual server by creating a file. Type following command.

vim /etc/nginx/sites-available/pfadmin.example.com

Now press i to get into edit mode and then copy below text and past in it.

server {
  listen 80;
  server_name pfadmin.example.com;
  return 301 https://$server_name$request_uri;
}
server {
   listen          443 ssl;
   server_name     pfadmin.example.com;
   root            /var/www/postfixadmin-3.0;
   index           index.php;
   charset         utf-8;
   ssl_certificate           /etc/ssl/certs/expertpk.pem;
   ssl_certificate_key       /etc/ssl/private/expertpk.key;
   ssl_protocols             TLSv1.2;
   ssl_prefer_server_ciphers on;
   ssl_session_cache         shared:SSL:10m;
   ssl_session_timeout       10m;
   ssl_ecdh_curve            secp521r1;
   location / {
      try_files $uri $uri/ index.php;
   }
   location ~* \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        include       fastcgi_params;
        fastcgi_pass  unix:/run/php/php7.0-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_buffer_size 16k;
        fastcgi_buffers 4 16k;
   }
}

Note 1: Please be clever and use your own domain in the above text.

Note 2: Please get Letsencrypt certificate and then move them as below. I assume that certificate files names are ssl.cert, ssl.ca and ssl.key. We have to merge ssl.cert and ssl.ca in one file.

cat ssl.ca ssl.cert > expertpk.pem
mv expertpk.pem /etc/ssl/certs/expertpk.pem
mv ssl.key /etc/ssl/private/expertpk.key

If you still don't understand what to do, please follow this link to get detailed guidelines to properly set up these files.

Now it is time to activate our new virtual server with the help of below simple command.

ln -s /etc/nginx/sites-available/pfadmin.example.com /etc/nginx/sites-enabled/pfadmin.example.com

It is time to test our configuration files and starting Nginx.

nginx -t
systemctl enable nginx
systemctl start nginx

The 1st command will test our configuration file and it should print "successful". If it is not the case then there is something wrong with our configuration file and we have to find and correct the error before typing next 2 commands.

PostfixAdmin is a PHP-based web frontend to manage the database. Later on, we will force postfix to use it for virtual domains and users. We are installing PostfixAdmin version 3, it supports MySQL PostgreSQL and SQLite databases. In this guide, we will use sqlite3.

Download the PostfixAdmin archive from SourceForge and extract it in the /var/www/ directory:

wget -q -O - "http://downloads.sourceforge.net/project/postfixadmin/postfixadmin/postfixadmin-3.0/postfixadmin-3.0.tar.gz" | sudo tar -xzf - -C /var/www

Now edit the Configuration file with below command, we need to edit this file.

vim /var/www/postfixadmin-3.0/config.inc.php

In vim editor, please change below fields

$CONF['configured'] = true;
$CONF['database_type'] = 'sqlite';
$CONF['database_name'] = '/var/postfix_db/postfixadmin.db';
// $CONF['database_host'] = 'localhost';
// $CONF['database_user'] = 'postfix';
// $CONF['database_password'] = 'postfixadmin';
// $CONF['database_name'] = 'postfix';
$CONF['domain_path'] = 'NO';
$CONF['domain_in_mailbox'] = 'YES';

Now create a postfix_db directory and a sqlite3 database file and set permissions:

mkdir -p /var/postfix_db
touch /var/postfix_db/postfixadmin.db
chown -R www-data:expertpk /var/postfix_db
usermod -a -G mail expertpk usermod -a -G expertpk www-data

Please note that DB directory and database file should be writeable for web user (in our case www-data,), and readable for mail user (in our case it is expertpk). If you are using any other user for the website then please set permissions accordingly.

One more thing to remember, your database directory must be outside of public directory (in our case it should not be located in /var/www/postfixadmin-3.0 or /var/www/html).

To populate the database go to

https://pfadmin.example.com/setup.php

and you should see something like below:

Testing database connection - OK - sqlite://:xxxxx@//var/postfix_db/postfixadmin.db

In this page please read the instruction to set your setup password, admin user and admin password etc.

It is time to set up our MTA "POSTFIX".

Let's begin the fun part.

We had installed postfix in the 1st part. Now we will create some files to ask postfix to use them.

1st file: VIRTUAL_ALIAS_MAPS

vim /etc/postfix/sqlite_virtual_alias_maps.cf
copy this code:
dbpath = /var/postfix_db/postfixadmin.db query = SELECT goto FROM alias WHERE address='%s' AND active = '1'

2nd file: SQLITE_VIRTUAL_ALIAS_DOMAIN_MAPS

vim /etc/postfix/sqlite_virtual_alias_domain_maps.cf
Copy this code:
dbpath = /var/postfix_db/postfixadmin.db
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = printf('%u', '@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'

3rd file: SQLITE_VIRTUAL_ALIAS_DOMAIN_CATCHALL_MAPS

vim /etc/postfix/sqlite_virtual_alias_domain_catchall_maps.cf
dbpath = /var/postfix_db/postfixadmin.db
query  = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = printf('@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'

4th file: SQLITE_VIRTUAL_DOMAINS_MAPS

vim /etc/postfix/sqlite_virtual_domains_maps.cf
dbpath = /var/postfix_db/postfixadmin.db
query = SELECT domain FROM domain WHERE domain='%s' AND active = '1'

5th file: SQLITE_VIRTUAL_MAILBOX_MAPS

vim/etc/postfix/sqlite_virtual_mailbox_maps.cf
dbpath = /var/postfix_db/postfixadmin.db
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'

6th file: SQLITE_VIRTUAL_ALIAS_DOMAIN_MAILBOX_MAPS

vim  /etc/postfix/sqlite_virtual_alias_domain_mailbox_maps.cf
dbpath = /var/postfix_db/postfixadmin.db
query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = printf('%u', '@', alias_domain.target_domain) AND mailbox.active = 1 AND alias_domain.active='1'

All files created successfully.

Now it is time to modify our main.cf file located in /etc/postfix/main.cf. No need to edit this file directly, we will use postconf utility to modify this file. Just copy below commands one by one and run in the console to edit this file.

postconf -e "myhostname = $(hostname -A)" 
postconf -e "virtual_mailbox_domains = sqlite:/etc/postfix/sqlite_virtual_domains_maps.cf"
postconf -e "virtual_alias_maps =  sqlite:/etc/postfix/sqlite_virtual_alias_maps.cf, sqlite:/etc/postfix/sqlite_virtual_alias_domain_maps.cf, sqlite:/etc/postfix/sqlite_virtual_alias_domain_catchall_maps.cf"
postconf -e "virtual_mailbox_maps = sqlite:/etc/postfix/sqlite_virtual_mailbox_maps.cf, sqlite:/etc/postfix/sqlite_virtual_alias_domain_mailbox_maps.cf"
postconf -e "smtpd_tls_cert_file = /etc/ssl/certs/expertpk.pem"
postconf -e "smtpd_tls_key_file = /etc/ssl/private/expertpk.key"
postconf -e "smtpd_use_tls = yes"
postconf -e "smtpd_tls_auth_only = yes" 
postconf -e "smtpd_sasl_type = dovecot"
postconf -e "smtpd_sasl_path = private/auth"
postconf -e "smtpd_sasl_auth_enable = yes"
postconf -e "smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination"
postconf -e "mydestination = localhost"
postconf -e "mynetworks = 127.0.0.0/8"
postconf -e "inet_protocols = ipv4"
postconf -e "virtual_transport = lmtp:unix:private/dovecot-lmtp"

Now it is time to edit another important file. It is located at /etc/postfix/master.cf. Use below command to edit this file:

vim /etc/postfix/master.cf

Now please make sure that you had not edited this file before if you are sure that you did not modify this file before then just copy below text and add in this file. If you had modified this file then please update its content by following these options. Please note that add this code below this line (#tlsproxy unix - - y - 0 tlsproxy)


# Code inserted manually by following http://help.expertpk.com/blog/expertpk-blog-1/post/install-postfix-and-postfix-admin-with-dovecot-1
# if anything went wrong, plese comment all below lines.
submission inet n       -       y       -       -       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
  -o milter_macro_daemon_name=ORIGINATING
smtps     inet  n       -       y       -       -       smtpd
  -o syslog_name=postfix/smtps
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING
### Modified code ends here.
### Faheem Khan

Save this file end exit from vim.

It is now time to enable and start postfix. Just type below commands.

systemctl enable postfix
systemctl start postfix

Now we will configure dovecote. Please be clever and carefully update following files. 

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

update below values in this file:

mail_location = maildir:/var/expertpk/%d/%n
mail_privileged_group = mail
mail_uid = expertpk
mail_gid = mail
first_valid_uid = 150
last_valid_uid = 150

Now edit next file:

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

update below values in this file:

auth_mechanisms = plain login
#!include auth-system.conf.ext
!include auth-sql.conf.ext

Create a new dovecot-sql.conf.ext file:

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

insert below values in this file:

driver = sqlite
connect = /var/postfix_db/postfixadmin.db
default_pass_scheme = MD5-CRYPT
password_query = \
  SELECT username as user, password, '/var/vmail/%d/%n' as userdb_home, \
  'maildir:/var/vmail/%d/%n' as userdb_mail, 150 as userdb_uid, 8 as userdb_gid \
  FROM mailbox WHERE username = '%u' AND active = '1'
user_query = \
  SELECT '/var/vmail/%d/%n' as home, 'maildir:/var/vmail/%d/%n' as mail, \
  150 AS uid, 8 AS gid, printf('dirsize:storage=', quota) AS quota \
  FROM mailbox WHERE username = '%u' AND active = '1'

Now edit next file:

Vim /etc/dovecot/conf.d/10-ssl.conf

update below values in this file:

ssl = yes
ssl_cert = </etc/ssl/certs/expertpk.pem
ssl_key = </etc/ssl/private/expertpk.key

.Edit next file:

vim /etc/dovecot/conf.d/15-lda.conf

update below values in this file:

postmaster_address = postmaster@example.com

Edit next file:

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

update below values in this file. Be careful don't add lines begins with # in below code, those are only instructions to modify this file:

service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    mode = 0600
    user = postfix
    group = postfix
  }
}
#find the service auth section and change it to:
service auth {
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
  }
  unix_listener auth-userdb {
    mode = 0600
    user = expertpk
    #group = expertpk
  }
  user = dovecot
}
#Change the service auth-worker section to the following:
service auth-worker {
  user = expertpk
}

File editing has been completed successfully. Now set the permissions:

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

Enable and restart the dovecot service

systemctl enable dovecot 
systemctl restart dovecot 

Now it is time to install and configure SpamAssassin. Please note that we do not install it in Part One, it is optional and better to install it to secure your server from spams and viruses.

SpamAssassin is a very powerful open source tool written in Perl, which helps filter out spam messages. 

To install SpamAssassin, run:

apt -y install spamassassin

Now create the spamd user:

adduserspamd --disabled-login

Edit spamassassin file and make some changes.

vim /etc/default/spamassassin

Please do the following changes:

ENABLED=1
OPTIONS="--create-prefs --max-children 5 -d 127.0.0.1 --username spamd --helper-home-dir /home/spamd/ -s /home/spamd/spamd.log"
PIDFILE="/home/spamd/spamd.pid"
CRON=1

To integrate SpamAssassin with Postfix, edit /etc/postfix/master.cf file

vim/etc/postfix/master.cf

Insert below lines at the end of this file:

smtp      inet  n       -       -       -       -       smtpd
    -o content_filter=spamassassin
spamassassin unix  -       n       n       -       -       pipe  
   user=nobody argv=/usr/bin/spamc -f -e /usr/sbin/sendmail -oi -f ${sender} ${recipient}

Enable and restart the SpamAssassin service

systemctl enable spamassassin
systemctl restart spamassassin
systemctl restart postfix


Now, if everything goes well, you had successfully installed and configure Postfix, Nginx, SQLite3, PHP-7.0, Spamassassin, Dovecote.

Feel free to comment on your thoughts about this guide, we will be happy if you share it on social media. We will be very happy to assist you further if you need any help.

If you would like to hire us to configure this for you, we will charge only $30 to set it up. Just click this link to hire us for this task.