Based on Debian 11 "Bullseye" environment.

Postfix and Dovecot LMTP

Postfix is one of the most famous MTA (Mail Transfer Agent). It can receive emails from the internet and deliver them to the user directories, but this time I use Dovecot LMTP for the local delivery.

Here I start with simple integration of Postfix and Dovecot LMTP, then start adding functionalities and configurations gradually.



# apt install postfix

The install will ask 2 questions.

  • General type of mail configuration: Internet Site
  • System mail name:
    The installer will pick up the FQDN for the server as the default for the system mail name.

Open the ports for Postfix. 25 for SMTP and 587 for SMTP Submission.

# firewall-cmd --add-service=smtp --permanent
# firewall-cmd --add-service=smtp-submission --permanent
# firewall-cmd --reload

There is another port for SMTPS(465), which I don't use this time. Encryption is available in both SMTP(25) and Submission(587) with STARTTLS.

Virtual Mailbox

Virtual Mailbox account

This time, mail users will not have any UNIX account. All emails will be stored under /home/vmail, which is the home directory for the user "vmail".
Disable shell login for additional security.

# adduser vmail
# usermod -s /usr/sbin/nologin vmail

Configuration for Virtual Users

The Postfix document has an example of the "Non-Postfix mailbox store: separate domains, non-UNIX accounts", which means using virtual accounts with non-Postfix delivery (this case maildrop) for the virtual domains.
Cf. Non-Postfix mailbox store: separate domains, non-UNIX accounts

Modify /etc/postfix/ to send all mails to virtual mailbox.

myhostname =
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = localhost # Delete domains on the mydestination line
relayhost = 
mynetworks = [::ffff:]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all

# Virtual Mailbox
virtual_mailbox_domains =,
virtual_transport = lmtp:unix:private/dovecot-lmtp 
virtual_alias_maps = hash:/etc/postfix/virtual

To catch local system mails (e.g. cron job), edit (or crete) /etc/postfix/virtual.

Make the db file using postmap.

# postmap virtual

Reload Postfix to apply changes on

# systemctl reload postfix



Deovecot-LMTP will take over the mail from Postfix and deliver them to the final destination directory. Postfix can deliver the mail without any external software, but integration with Dovecot enables the Sieve filtering and incoming mail indexing for the Dovecot IMAP server.

# apt install dovecot-lmtpd


As explained in the Dovecot Wiki, dovecot-lmtpd will be integrated with Postfix via the unix socket.

Tweak the lmtp section in /etc/dovecot/conf.d/10-master.conf to open the socket where Postfix can access.

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

Enable passwdfile configuration in the bottom of /etc/dovecot/conf.d/10-auth.conf

!include auth-system.conf.ext
#!include auth-sql.conf.ext
#!include auth-ldap.conf.ext
!include auth-passwdfile.conf.ext # Uncomment this line
#!include auth-checkpassword.conf.ext
#!include auth-vpopmail.conf.ext
#!include auth-static.conf.ext

Set up passdb and userdb, and set defaults for the userdb information in /etc/dovecot/conf.d/auth-passwdfile.conf.ext

passdb {
  driver = passwd-file
  args = scheme=CRYPT username_format=%u /etc/dovecot/users

userdb {
  driver = passwd-file
  args = username_format=%u /etc/dovecot/users

  # Default fields that can be overridden by passwd-file
  default_fields = uid=vmail gid=vmail home=/home/vmail/%d/%n mail=sdbox:~/dbox
  • passdb and userdb can be the same file. (And that's convenient. Just adding 1 line is the only task to add a new user.)
  • Password scheme is CRYPT, which is the default.
  • Username will be mail address. e.g.
  • userdb has to have uid, gid, home directory, and additionally mail location. In my case, the server is newly built that everyone will use the common configuration.
    • uid and gid are "vmail" that will store all users mail.
    • Virtual users home directory will be /home/vmail/domain/username.
    • Every virtual user will use Dovecot single-dbox style mail storage. (You may want to use Maildir for the compatibility.)

Reload Dovecot to apply the configuration.

# systemctl reload dovecot


The userdb (this case /etc/dovecot/users) will keep the list of usernames and their encrypted passwords. The command doveadm will give you the password to copy and paste.
For example, the word "password" will be;

# doveadm pw
Enter new password:       # Nothing displayed when typing
Retype new password:      # Ditto

Now copy and paste this encrypted password to the userdb (/etc/dovecot/users) file for the user ""{CRYPT}$2y-snip-bxi::::::

The trailing six colons (::::::) are for uid/gid/home. In addition to these 3, mail_location is set in the conf file. If everything is written inline, then it should look like below.
See passwd-file explanation here for details.{CRYPT}$2y-snip-bxi:vmail:vmail::/home/vmail/%d/%n::userdb_mail=sdbox:~/dbox

If you need to change these parameters per user, you can override the default value by writing explicitly.
If you have a bunch of users, it would be better to use a DB to manage them.

Dovecot will check the userdb every time it gets a mail. No reload required for the userdb update.


Send a test mail to the valid user on this server. The successful logs should come up. (You still can't connect from your MTA. Please check /var/log/mail.log or mail.err)
When the first mail has come to the new user, dovecot will make a new directory to store the mail under the specified home directory.

If you have any troubles, dovecot can provide you the detailed debugging logs. Turn on the debug switches in /etc/dovecot/conf.d/10-logging.conf

auth_verbose = yes
auth_debug = yes
auth_debug_passwords = yes
mail_debug = yes

Update History


  • Change from ufw to firewall-cmd commands