Postfix, Dovecot, ViMbAdmin, RoundCube

This article covers:

  1. Multiple domains support e.g. example.com, rtcamp.com, apple.com, google.com, etc.
  2. Virtual users support e.g. rahul@apple.com, steve@rtcamp.com, etc. Virtual users cannot login to server using shell/ftp like real-users.
  3. Alias management e.g. mails for you@example.com should be forwarded to rahul@rtcamp.com)
  4. Web-based administration interface to add/remove domains, email users and aliases.
  5. Webmail Interface for mail users can simply login with email-id & password to send/check emails.

Installing packages for postfix, dovecot, mysql

apt-get install postfix postfix-mysql dovecot-core dovecot-imapd dovecot-pop3d dovecot-lmtpd dovecot-mysql mysql-server dovecot-sieve dovecot-managesieved

If you are adding a mail server on existing system some packages might be present already. Depending on previously installed package list, you may or may not see prompts to configure mysql, postfix, etc. Choose defaults wherever possible.

Postfix Configuration

This guide is created using postfix 2.9.6. You can check postfix version installed using command: postconf mail_version

Postfix configuration has 2 important files: main.cf and master.cf. We will also add some more files for virtual domain/mail system.

Postfix master.cf

If you want to run smtp on port 465 (with SSL) and on port 587 (with TLS), you need to uncomment following lines in master.cf:

It is highly recommend to do this as most ISP block port 25 to prevent spam.

vim /etc/postfix/master.cf
submission inet n       -       -       -       -       smtpd
smtps     inet  n       -       -       -       -       smtpd

Postfix main.cf

Open main.cf file: vim /etc/postfix/main.cf

Add following lines towards end of file:

# Change postfix TLS parameter to use dovecot 
#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

#Handle SMTP authentication using Dovecot
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

# other destination domains should be handled using virtual domains 
mydestination = localhost

# using Dovecot's LMTP for mail delivery and giving it path to store mail
virtual_transport = lmtp:unix:private/dovecot-lmtp

# virtual mailbox setups
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_alias_maps = mysql:/etc/postfix/mysql/virtual_alias_maps.cf
virtual_mailbox_domains = mysql:/etc/postfix/mysql/virtual_domains_maps.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql/virtual_mailbox_maps.cf

Postfix Virtual Mailbox Config

We will be using a mysql database for virtual domains, users and aliases.

Create a separate directory to store all postfix-mysql config:

mkdir /etc/postfix/mysql

Virtual Alias Mapping

Create a file: vim /etc/postfix/mysql/virtual_alias_maps.cf
Paste following in it:

user = vimbadmin
password = password
hosts = 127.0.0.1
dbname = vimbadmin
query = SELECT goto FROM alias WHERE address = '%s' AND active = '1'

Virtual Domain Mapping

Create a file: vim /etc/postfix/mysql/virtual_domains_maps.cf
Paste following in it:

user = vimbadmin
password = password
hosts = 127.0.0.1
dbname = vimbadmin
query = SELECT domain FROM domain WHERE domain = '%s' AND backupmx = '0' AND active = '1'

Virtual Mailbox (user) Mapping

Create a file:  vim /etc/postfix/mysql/virtual_mailbox_maps.cf
Paste following in it:

user = vimbadmin
password = password
hosts = 127.0.0.1
dbname = vimbadmin
query = SELECT maildir FROM mailbox WHERE username = '%s' AND active = '1'

Dovecot Configuration

Dovecot is an IMAP and POP server. It also implements security/authentication for IMAP/POP as well as SMTP (via Postfix).

We are using dovecot version 2.0.19. You can check it using command: dovecot --version

A real linux user – vmail

Following commands create a user and a group named vmail. vmail is a linux user who will own everybody’s email! (There’s nothing to get panic about this fact…)

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

Restart postfix

service postfix restart

Dovecot Configs

This is most annoying part I found with dovecot. Configuration is literally scattered among too many files:

Enable required protocols

vim /etc/dovecot/dovecot.conf
# Enable installed protocols
!include_try /usr/share/dovecot/protocols.d/*.protocol
protocols = imap pop3 lmtp sieve

Configure mail storage location

vim /etc/dovecot/conf.d/10-mail.conf
mail_location = maildir:/var/vmail/%d/%n

Configure authentication

vim /etc/dovecot/conf.d/10-auth.conf
disable_plaintext_auth = no
auth_mechanisms = plain login

Also comment out line: #!include auth-system.conf.ext to disable system user authentication.

Finally add support for mysql based authentication at the bottom:

passdb {
    driver = sql
    args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
    driver = static
    args = uid=5000 gid=5000 home=/var/vmail/%d/%n allow_all_users=yes
}

Configure mysql parameters in dovecot

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

Paste following to the bottom:

driver = mysql
connect = host=127.0.0.1 dbname=vimbadmin user=vimbadmin password=password
password_query = \
  SELECT username AS user, password, \
    homedir AS userdb_home, uid AS userdb_uid, gid AS userdb_gid \
  FROM mailbox WHERE username = '%u'
iterate_query = SELECT username AS user FROM mailbox

Change master config file

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

Make sure it looks like following:

service lmtp {
 unix_listener /var/spool/postfix/private/dovecot-lmtp {
   mode = 0600
   user = postfix
   group = postfix
  }
}

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

  unix_listener auth-userdb {
    mode = 0600
    user = vmail
  }

  user = dovecot
}

service auth-worker {
  user = vmail
}

Configure Logging

vim /etc/dovecot/conf.d/10-logging.conf
log_path = /var/log/dovecot.log

Debug logging

If you want to enable debug logs, use following:

#debuggign authentication requests
auth_debug = yes

#debugging other mail related stuff
mail_debug = yes

For more details about debug logging, check available parameters in dovecot docs.

Doveconf

As we are changing many files, we may lose track. You can run doveconf -n at those times.

doveconf -n displays list of changes made across entire dovecot.

Similarly, doveconf -a displays entire dovecot config (including defaults).

Restart dovecot

service dovecot restart

ViMbAdmin – Virtual Mail Server Administration

There are many postfix web interfaces available but we choose to go with ViMbAdmin. It “looks” nice and it uses PHP.

If you prefer ruby/rails, there is a promising alternative – posty.

ViMbAdmin v3 Installation

Vimbadmin requires composer so install it first.

curl -sS https://getcomposer.org/installer | php

Then…

cd /usr/local
apt-get install subversion git-core 
git clone git://github.com/opensolutions/ViMbAdmin.git vimbadmin 
cd /usr/local/vimbadmin 
php composer.phar install
chown -R www-data: /usr/local/vimbadmin

When composer will prompt you:

Do you want to remove the existing VCS (.git, .svn..) history? [Y,n]?

Answer no n.

Create a mysql database and user for vimbadmin

Run following from mysql shell

CREATE DATABASE `vimbadmin`;
GRANT ALL ON `vimbadmin`.* TO `vimbadmin`@`127.0.0.1` IDENTIFIED BY 'password';
FLUSH PRIVILEGES;

vimbadmin config file

cp application/configs/application.ini.dist application/configs/application.ini
vim application/configs/application.ini
securitysalt = "superadmin-password"
defaults.mailbox.uid = 5000
defaults.mailbox.gid = 5000
defaults.mailbox.homedir = "/var/vmail/"
resources.doctrine2.connection.options.driver   = 'pdo_mysql'
resources.doctrine2.connection.options.dbname   = 'vimbadmin'
resources.doctrine2.connection.options.user     = 'vimbadmin'
resources.doctrine2.connection.options.password = 'password'
resources.doctrine2.connection.options.host     = 'localhost'

Make sure mysql setting are correct in above config.

Memcache glitch

If you are using memcache, comment out

;resources.session.save_path = APPLICATION_PATH "/../var/session"

Create mysql tables

Following will create mysql tables for which we already tweaked postfix and dovecot.

./bin/doctrine2-cli.php orm:schema-tool:create

Chnage Ownership

chown -R www-data:www-data /usr/local/vimbadmin

set timezone in php

Open /etc/php5/fpm/php.ini

Add/update

date.timezone = "UTC"

Restart PHP-FPM using service php5-fpm restart

Open VimbAdmin interface and follow instructions from there.

ViMbAdmin v2 Installation

Following commands are for Vimbadmin V2. I am sorry to say I did not get time to try V3. But I hope to add v3 instructions soon.

cd /usr/local
git clone -b v2 git://github.com/opensolutions/ViMbAdmin.git vimbadmin
apt-get install subversion
cd /usr/local/vimbadmin
./bin/library-init.sh

Run following from mysql shell

CREATE DATABASE `vimbadmin`;
GRANT ALL ON `vimbadmin`.* TO `vimbadmin`@`127.0.0.1` IDENTIFIED BY 'password';
FLUSH PRIVILEGES;

vimbadmin config file

cp application/configs/application.ini.dist application/configs/application.ini
vim application/configs/application.ini
securitysalt = "superadmin-password"
defaults.mailbox.uid = 5000
defaults.mailbox.gid = 5000
defaults.mailbox.homedir = "/var/vmail/"
resources.doctrine.connection_string = "mysql://vimbadmin:password@127.0.0.1/vimbadmin"

Memcache glitch

If you are using memcache, comment out

;resources.session.save_path = APPLICATION_PATH "/../var/session"

Create mysql tables

Following will create mysql tables for which we already tweaked postfix and dovecot.

bin/doctrine-cli.php create-tables

Chnage Ownership

chown -R www-data:www-data /usr/local/vimbadmin

Nginx config

server {
	server_name vma.example.com;

	access_log   /var/log/nginx/vma.example.com.access.log;
	error_log    /var/log/nginx/vma.example.com.error.log;

	root /usr/local/vimbadmin/public;
	index index.php;

	location / {
		try_files $uri $uri/ /index.php?$args;
	}

	location ~ \.php$ {
		try_files $uri =404;
		include fastcgi_params;
		fastcgi_pass 127.0.0.1:9000;
	}

}

At this point you can open vma.example.com and create an ViMbAdmin admin account. Please note that ViMbAdmin account is not virtual email account.

You can add domain, virtual mail-users after logging into vma.example.com using ViMbAdmin account.

Roundcube for Webmail Interface

You can literally use email client which supports smtp and pop/imap. So webmail part is completely optional.

apt-get install roundcube roundcube-plugins roundcube-plugins-extra

Above install roundcube inside /usr/share/roundcube

Roundcube config files are present in: /etc/roundcube

Open vim /etc/roundcube/main.inc.php

Add/change following:

$rcmail_config['default_host'] = 'localhost';
$rcmail_config['imap_cache'] = memcache;
$rcmail_config['messages_cache'] = db

Nginx config

server {
	server_name mail.example.com;

	access_log   /var/log/nginx/mail.example.com.access.log;
	error_log    /var/log/nginx/mail.example.com.error.log;

	root /usr/share/roundcube;
	index index.php;

	location / {
		try_files $uri $uri/ /index.php?$args;
	}

	location ~ \.php$ {
		try_files $uri =404;
		include fastcgi_params;
		fastcgi_pass 127.0.0.1:9000;
	}

}

You can open mail.example.com in browser and login using a virtual user-email and password.

Testing

At this point, we have SMTP (via Postfix), POP/IMAP (via dovecot) and a web-interface (via Vimbadmin) to manage virtual domains and users.

Before we proceed with remaining goals lets test if we have a working setup (so far).

Testing SMTP, IMAP and POP is covered here in detail.

 

Discuss your project
with our experts

No obligation. Limited slots.

Contact Form Business Enquiry

"*" indicates required fields

Please attach any RFP, project specification, or document that you would like to share.
Drop files here or
Max. file size: 5 GB.
    This field is for validation purposes and should be left unchanged.