Appbead Blog

How to Setup Mail Server on Debian 8 Jessie with Postfix + Dovecot (2)

We have just installed the necessary softwares of our mail server in previous article. Now, let's integrate them all together against this diagram.

The Listening Ports

According to the diagram, Postfix listen the port SMTP(25) and Submission(587), and Dovecot listen the port IMAPS(993).


To configure the ports, edit the with your favorite editor:

$ sudo vi /etc/postfix/

Enable the service Submission by making the line 17 is NOT commented:

smtp      inet  n       -       -       -       -       smtpd
#smtp      inet  n       -       -       -       1       postscreen
submission inet n       -       -       -       -       smtpd
#  -o syslog_name=postfix/submission

The service SMTP is enabled by default.

Then edit the

$ sudo vi /etc/postfix/
  • Find smtpd_tls_cert_file and insert definition of smtpd_tls_CAfile as below.
  • Specify our certificate files prepared in previous article.
  • Also replace smtpd_use_tls = yes with smtpd_tls_security_level = may.
  • Add smtp_tls_security_level = may (Thanks goes to @ajdunevent, Biganon and Dave):
smtpd_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
smtpd_tls_cert_file = /etc/ssl/certs/
smtpd_tls_key_file = /etc/ssl/private/
smtpd_tls_security_level = may
smtp_tls_security_level = may


I prefer to just have a single dovecot.conf file instead of split files, so backup the original one. Then create new one and edit it.

$ sudo -i
# doveconf -n > /etc/dovecot/
# mv /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.orig
# mv /etc/dovecot/ /etc/dovecot/dovecot.conf
# vi /etc/dovecot/dovecot.conf

Note: $ for normal user, # for root.

Find the line ssl = no, and delete it. Then insert following block:

service imap-login {
  inet_listener imap {
    port = 0
  inet_listener imaps {
    port = 993

ssl = required
ssl_ca = </etc/ssl/certs/ca-certificates.crt
ssl_cert = </etc/ssl/certs/
ssl_key = </etc/ssl/private/

Listen the IMAPS port 993 by define the service imap-login
To disable IMAP, set port to 0
Force SSL connect, and use our certificate files

Don't allow systemd monitor the IMAP(143) port to prevent error:

# cp /lib/systemd/system/dovecot.socket /etc/systemd/system/
# systemctl reenable dovecot.socket
# sed -i '/:143$/s/^/#/' /etc/systemd/system/dovecot.socket


On the Server side:

# systemctl restart postfix
# systemctl restart dovecot
# netstat -lnpt

Check if the ports (25, 587 and 993) are listed in the column 'Local Address'. Also check the logs:
less /var/log/mail.log and less /var/log/syslog

On the Local side:

$ openssl s_client -starttls smtp -crlf -connect <your_mail_server>:587
$ openssl s_client -connect <your_mail_server>:993

In both cases, the third line from the bottom of output should be:

    Verify return code: 0 (ok)

Authentication and Mailbox


$ sudo vi /etc/postfix/

Handing off authentication to Dovecot. Insert following block:

smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
# The path is relative to $queue_directory:
#   # postconf |grep queue_directory
#   queue_directory = /var/spool/postfix
smtpd_sasl_path = private/auth
# Do not accept SASL authentication over unencrypted connections
smtpd_tls_auth_only = yes


$ sudo vi /etc/dovecot/dovecot.conf

Insert following block

# Allows plaintext authentication only when SSL/TLS is used first.
auth_mechanisms = plain login
disable_plaintext_auth = yes

service auth-worker {
  # Forbid to access /etc/shadow
  user = $default_internal_user

service auth {
  # IMPORTANT: Match the path to smtpd_sasl_path of Postfix
  unix_listener /var/spool/postfix/private/auth {
    group = postfix
    user = postfix
    mode = 0666

Replace the definition of mail_location, passdb and userdb as following:

mail_location = maildir:/var/vmail/%d/%n

passdb {
  driver = passwd-file
  # The entire email address will be used as the username for email client.
  # Don't bother about the scheme here, will be overwritten by a strong scheme from file.
  #    (
  args = scheme=CRYPT username_format=%u /etc/dovecot/users

userdb {
  # For static type, LDA verify the user's existence by lookup passdb
  #   ( )
  driver = static
  args = uid=vmail gid=vmail home=/var/vmail/%d/%n

For details of variables(%d, %n, and %u), see
Why not use the existing mail as UID instead of new one? Check this error.

For the first time, either authenticate successfully, or new mail arrive. All the special directories of the mailbox will be automatically created by Dovecot, for that account. So we need specify the format of mailbox in mail_location, also a system user to execute the operations of mailbox.

Add the system user vmail:

# adduser --system --home /var/vmail --uid 550 --group --disabled-login vmail

The directory /var/vmail will be created, and owned by system user vmail.

The First Mail Account

  • Generate a password HASH with SHA512-CRYPT scheme.
$ doveadm pw -s SHA512-CRYPT

Input your password, and the output may looks like,

  • Append the user record into the passwd-file /etc/dovecot/users, and the format is user:{SCHEME}password. We run the command cat as root.
sudo -i
cat << EOF >> /etc/dovecot/users{SHA512-CRYPT}$6$VaEOV5mzsbP1q2H9$Ctar1HzJCZGXmlXcJDluXEFjGdEwjDKIZ80I0KhG6YD4c2X13YDX/dIb1kGPLAwo7.fTnRaQpcsN5O5O9QjaJ0
  • Set the file modes:
# chmod 640 /etc/dovecot/users
# chown root:dovecot /etc/dovecot/users


On the Server side:

Restart service, and confirm the Unix socket file created automatically.

# systemctl restart postfix
# systemctl restart dovecot
# ls -l /var/spool/postfix/private/auth

On the Local side:

$ openssl s_client -connect <your_mail_server>:993
* OK ......
a login mypassword  <- Input Line
a OK [......] Logged in
b logout  <- Input Line

Mail Delivery (LMTP)


$ sudo vi /etc/postfix/

Add a line mydomain = before $myhostname. And change variables as following:

mydomain =
myhostname = mx.$mydomain
myorigin = $mydomain
mydestination = localhost

Replace with yours. The value of $mydomain and $myhostname must match to the names used to request your SSL certification. The common usages of variables:

  • $myhostname: The hostname to send in the SMTP HELO or EHLO command, and SMTP greeting banner.
  • $myorigin, $mydestination: For aliases, see comments in /etc/postfix/virtual_aliases later.
  • $myorigin, $virtual_mailbox_domains, $virtual_alias_maps: reject_unauth_destination

Insert following lines:

# Handing off local delivery to Dovecot's LMTP
# The path relative to $queue_directory, that is:
#    /var/spool/postfix/private/dovecot-lmtp
virtual_transport = lmtp:unix:private/dovecot-lmtp

# Check domains only, query users and aliases in Dovecot
# IMPORTANT: Don't overlap with $mydestination
#virtual_mailbox_domains =,
virtual_mailbox_domains = $mydomain

#virtual_alias_domains = $virtual_alias_maps
virtual_alias_maps = hash:/etc/postfix/virtual_aliases


# vi /etc/postfix/virtual_aliases

And fill with these lines:

# The input(left column) without domain, will match user@$myorigin
#   and user@$mydestination (e.g., root@localhost)
# The result(right column) without domain, Postfix will append
#   $myorigin as $append_at_myorigin=yes
# So the user must exists in /etc/dovecot/users
# See: The section TABLE FORMAT in manual virtual(5)

postmaster          root
webmaster           root

# Person who should get root's mail
root                user1    user1

# A catch-all address is at the risk of spam       user1

Replace user1 and with yours, and feel free to add or remove maps for any users.

Then build the necessary DB file after every change:

# postmap /etc/postfix/virtual_aliases
# postfix reload


$ sudo vi /etc/dovecot/dovecot.conf

Insert following block:

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

IMPORTANT: The full path of dovecot-lmtp must match to $virtual_transport in Postfix.


On the Server side:

Restart service, and confirm the Unix socket file created automatically.

# systemctl restart postfix
# systemctl restart dovecot
# ls -l /var/spool/postfix/private/dovecot-lmtp

Send out an email report. With above alias maps, the will receive that message:

$ sendmail -bv webmaster
$ sudo ls -l /var/vmail/

DNS Records

It's time to configure our DNS records, so outside mail server knows what's the IP our mail server uses. In the control panel of your domain service provider, add two records as follows:

Type Host Answer Prio
A -
MX 10

In order to avoid being a victim of Sender Address Forgery, also add this SPF record (syntax).

Type Host Answer Prio
TXT "v=spf1 a mx -all" -
  • Replace with your IP.
  • Replace with the host name of your mail server, it must be same as the $myhostname in /etc/postfix/
  • Replace with your domain name.
  • You may use "@" instead of "" in the column "Host" for some providers.

Also in the control panel of your hosting service provider, add this PTR record:

Type Host Answer Prio

Without this record, the emails sending by our MTA may be rejected by others.
The steps to modify PTR record on DigitalOcean is:
Click Droplets > Droplet > Settings > Rename
Fill with (your host name of mail server)

Use dig to test:

$ dig +short mx |awk '{print $2}'
$ dig +short a
$ dig +short -x

Read and Send Emails with MUA

We have a new email on the server just a moment ago. To read it on the local, or even use the mail account to send mails to others, open your favorite MUA, and create a new email account with following information:

Configuring IMAP accounts

Server Name:
Port: 993
Connection security: SSL/TLS
Authentication method: Normal password
User Name:

Configuring the outgoing (SMTP) server

Server Name:
Port: 587
Connection security: STARTTLS
Authentication method: Normal password
User Name:


Now your mail server is up and running. And you can receive and send emails with your favorite MUA on the local!

You may stop configuration here, and wait for a couple of days to see interesting things happen, but keep an eye on your /var/log/mail.log!

However, I'd recommend you to take a break, then continue to the next page. It's the most important and interesting part of our mail server!

< Previous Page Next Page >


UID Error

~# doveadm user
doveadm(root): Error: user Mail access for users with UID 8 not permitted (see first_valid_uid in config file, uid from userdb lookup).
field   value
~# doveconf |grep first_valid_uid
first_valid_uid = 500

Obviouslly the UID of user mail is 8, it's not meet the condition of first_valid_uid.