[2018-01-07]

Making Postfix send emails to Dovecot

In a previous chapter we made sure that Postfix knows which emails it is allowed to receive. Now what to do with the email? It has to be stored to disk for your users. You could let Postfix handle that using its built-in mail delivery agent (MDA) called “virtual”. However compared to the capabilities that Dovecot provides like server-based sieve rules or quotas the Postfix delivery agent is pretty basic. We are using Dovecot anyway to provide the IMAP (and optionally POP3) service. So let’s use its delivery agent.

How can we make Postfix hand over the email to Dovecot? There are generally two ways to establish that link.

  1. Using the dovecot-lda (local delivery agent) process. It can process one email at a time. And it starts up a new process for every email. This was for long the default way. But you can imagine that it does not scale well.
  2. The other option is to use LMTP (local mail transport protocol) that was conceived for this purpose. It can handle multiple recipients at the same time and has a permanently running process which provides a better performance than using the LDA. In short LMTP is a variant of SMTP with fewer features. It is meant for email communication between two components that trust each other.

You guessed it already – we will go for the second option. The software package dovecot-lmtpd should already be installed on your system. So first…

Tell Dovecot where to listen for LMTP connections from Postfix

Edit Dovecot’s configuration file that deals with the LMTP daemon – you can find it at /etc/dovecot/conf.d/10-master.conf. Look for the “service lmtp” section and edit it so that it looks like:

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

This makes Dovecot’s lmtp daemon create a UNIX socket at /var/spool/postfix/private/dovecot-lmtp. Just like in the section dealing with setting up Dovecot we make it put a socket into the /var/spool/postfix chroot directory because Postfix is restricted to that directory and cannot access anything outside of it. So from Postfix’s point of view the socket is located at “/private/dovecot-lmtp”.

Restart Dovecot…

service dovecot restart

(By the way this configuration snippet has been taken from the Dovecot wiki.)

So we can now…

Tell Postfix to deliver emails to Dovecot using LMTP

This is even easier. The “virtual_transport” in Postfix defines the service to use for delivering emails to the local system. Dovecot has created a socket file and is ready to listen to incoming LMTP connections. We just need to tell Postfix to send emails there:

postconf virtual_transport=lmtp:unix:private/dovecot-lmtp

The syntax looks crazy? It’s actually simple. You just told Postfix to use the LMTP protocol. And that we want to use a UNIX socket on the same system (instead for example a TCP connection). And that the socket file is located at /var/spool/postfix/private/dovecot-lmtp.

(You will find further information on these steps in the Dovecot configuration on Postfix integration.)

Enable server-side mail rules

One of my favorite features of Dovecot are rules for incoming email that are processed on the server. You can sort away your mailing list emails into special folders. You can reject certain senders. Or you can set up vacation auto-responders. No need to have a mail client running – it all happens automatically even when your mail users are not connected.

The open-source standard (RFC 5228) for such rules is called Sieve. Simply put Sieve is a way to manage server-side email rules. A rule consists of conditions and actions. For example if the sender address matches “steve@example.org” you could tell Dovecot to move such emails to your “steve” folder automatically. These rules are stored on the Dovecot server and executed automatically. Whether you connect from your smartphone your laptop or use the webmail access – the rules always work and require no configuration on the client side.

As we use LMTP that’s where we need to tell the lmtp service that we want to use Dovecot’s “sieve” plugin. Edit the file /etc/dovecot/conf.d/20-lmtp.conf and within the “protocol lmtp” section change the “mail_plugins” line to:

mail_plugins = $mail_plugins sieve

Restart Dovecot and you are done:

service dovecot restart

3 thoughts on “Making Postfix send emails to Dovecot

  • 2018-03-08 at 11:12
    Permalink

    Hi,
    have you ever configured postfixadmin? Till Jessie everything worked great but in Stretch I can’t configure vacation module; I get this error:
    relay=vacation, delay=3.6, delays=3.4/0.01/0/0.16, dsn=5.3.0, status=bounced (Command died with status 255: “/var/spool/vacation/vacation.pl”. Command output: Can’t use ‘defined(@array)’ (Maybe you should just omit the defined()?) at /usr/share/perl5/Mail/Sender.pm line 318. Compilation failed in require at /var/spool/vacation/vacation.pl line 129. BEGIN failed–compilation aborted at /var/spool/vacation/vacation.pl line 129. )
    Can you help me please?
    Thanks

    Reply
  • 2018-10-25 at 18:50
    Permalink

    What an awesomely-written tutorial! I’ve been wanting to build a mail server for a long time, and until now, I was unable to find a document that clearly explained the processes and pieces needed to make a mail server work.

    I was able to build a mail server that can receive and send mail to the world, but when I look at the mail.log file, I notice a couple of lines generated every time the user account attempts to authenticate:
    Oct 25 13:55:34 mailserver dovecot: auth-worker(32750): Warning: mysql: Query failed, retrying: Table ‘mailserver.users’ doesn’t exist
    Oct 25 13:55:34 mailserver dovecot: auth-worker(32750): Error: sql(john@example.org,::1,): User query failed: Table ‘mailserver.users’ doesn’t exist (using built-in default user_query: SELECT home, uid, gid FROM users WHERE username = ‘%n’ AND domain = ‘%d’)

    But then it appears to work:
    Oct 25 13:55:34 mailserver dovecot: imap-login: Login: user=, method=PLAIN, rip=::1, lip=::1, mpid=32751, secured, session=

    I followed the Stretch tutorial.

    Is there another line that would need to be included in /etc/dovecot/dovecot-sql.conf.ext to eliminate this error?

    Thanks!

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *