{"id":139,"date":"2019-06-02T22:52:39","date_gmt":"2019-06-02T21:52:39","guid":{"rendered":"https:\/\/blog.inplico.uk\/?p=139"},"modified":"2025-12-15T14:50:37","modified_gmt":"2025-12-15T14:50:37","slug":"dovecot","status":"publish","type":"post","link":"https:\/\/blog.inplico.uk\/?p=139","title":{"rendered":"Dovecot (UP TO 2.3 ONLY)"},"content":{"rendered":"<p>While postfix provides SMTP outgoing mail services dovecot manages the inbound traffic and the mail boxes.<\/p>\n<p>In the previous parts of this guide we configured postfixadmin so that we can add domains and mailboxes to the database. This information is also useful to dovecot so as part of our configuration of dovecot we are going to use that same database to look up information for dovecot.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Installation<\/strong><\/p>\n<p>The first thing that we need to do is install a number of dovecot packages<\/p>\n<p style=\"padding-left: 40px;\"><strong>dovecot-pgsql<\/strong><\/p>\n<p style=\"padding-left: 40px;\"><strong>dovecot-imapd<\/strong><\/p>\n<p style=\"padding-left: 40px;\"><strong>dovecot-lmtpd<\/strong><\/p>\n<p style=\"padding-left: 40px;\"><strong>dovecot-managesieved<\/strong><\/p>\n<p>&nbsp;<\/p>\n<pre class=\"lang:sh decode:true\">#apt-get install dovecot-pgsql dovecot-imapd dovecot-lmtpd dovecot-managesieved<\/pre>\n<p>We are not going to bother with pop3 because I cannot thing of a single application where we would use it. Once everything is installed we can move on to the configuration<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Configuration dovecot.conf<\/strong><\/p>\n<p>Most of the documentation tells you to add \u201cprotocols = imap lmtp sieve\u201d to dovecot conf however this is no longer necessary as dovecot now looks in the <strong>\/usr\/share\/dovecot\/protocols.d<\/strong> directory to find what protocols to enable.<\/p>\n<p>You just have to make sure that the line<\/p>\n<pre class=\"lang:sh highlight:0 decode:true \">!include_try \/usr\/share\/dovecot\/protocols.d\/*.protocol<\/pre>\n<p>is uncommented (which it is by default). You can use either\/or method to enable the installed protocols, but do not use both. The advantage of using the newer method is that any newly installed protocols are automatically enabled by default.<\/p>\n<p>The only thing that you should actually have to worry about in dovecot.conf is<\/p>\n<pre class=\"lang:sh highlight:0 decode:true \">listen =*, ::<\/pre>\n<p>needs to be uncommented, and that is it.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Configuration dovecot-sql.conf.ext<\/strong><\/p>\n<p>As we mentioned, dovecot needs to talk to the postfix database so that it can use it for authentication and to lookup domains, mailboxes etc. In order for it to do this we need to supply it with the connection details and the sql statements that will be used to retrieve information from the database. <strong>\/etc\/dovecot\/dovecot.sql.conf<\/strong> is the configuration file that stores this information<\/p>\n<pre class=\"lang:sh highlight:0 decode:true \">driver = pgsql\r\nconnect = host=localhost dbname=postfix user=postfixro password=secret\r\ndefault_pass_scheme = MD5<\/pre>\n<p>These 3 lines all relate to the connection information and will require editing with the correct credentials to connect to the database. We also need to add 2 sql statements<\/p>\n<p>The first of these queries the data for the user. The first part of this statement \u201c<strong>SELECT \u2018\/var\/mail\/vmail\/\u2019||maildir<\/strong>\u201d is actually wrong for our configuration as we are keeping our mail in <strong>\/home\/mailstore<\/strong> rather than \/var\/mail\/vmail\/.\u00a0 If, as I believe is best practice, you have created a separate partition for your mail store you need to adjust this accordingly (how to do so is explained below).<\/p>\n<pre class=\"lang:sh highlight:0 decode:true\">user_query = \\\r\nSELECT '\/var\/mail\/vmail\/'||maildir AS home, '*:bytes='||quota AS quota_rule \\\r\nFROM mailbox \\\r\nWHERE username = '%u' \\\r\nAND active = TRUE<\/pre>\n<p>NOTE: The backslash \u201c\\\u201d at the end of the line is simply to tell the configuration file that the statement continues onto the next line and must be omitted unless you are running on to the next line.<\/p>\n<p>If you run \u201c<strong>SELECT &#8216;var\/mail\/vmail\/&#8217;||maildir FROM mailbox;<\/strong>\u201d in psql when connected to the postfix database it should return the path to the directory where the mail is stored for each user in the database; something like<\/p>\n<pre class=\"lang:sh highlight:0 decode:true\">\/var\/mail\/vmail\/fqdn.suffix\/mailboxname<\/pre>\n<p>however we want it to return<\/p>\n<pre class=\"lang:sh highlight:0 decode:true \">\/home\/mailstore\/fqdn.suffix\/mailboxname<\/pre>\n<p>Thankfully this is easy enough as we simply replace <strong>\u2018\/var\/mail\/vmail\/\u2019 <\/strong>with <strong>\u2019\/home\/mailstore\/\u2019<\/strong> in the statement. Under the hood the sql statement gets the contents of the column \u201cmaildir\u201d in the table \u201cmailbox\u201d and prepends it with whatever string you place in the single inverted commas before the \u201c||\u201d. The \u201cAS home\u201d and \u201cAS quota_rule\u201d parts<\/p>\n<p>To clarify, the actual statement that we want for this configuration is<\/p>\n<pre class=\"lang:sh highlight:0 decode:true\">user_query = \\\r\nSELECT '\/home\/mailstore\/'||maildir AS home, '*:bytes='||quota AS quota_rule \\\r\nFROM mailbox \\\r\nWHERE username = '%u' \\\r\nAND active = TRUE<\/pre>\n<p>This statement will pass the full path of the mail directory and the quota rule to dovecot.<\/p>\n<p>And here we have the second statement:<\/p>\n<pre class=\"lang:sh highlight:0 decode:true\">password_query = \\\r\nSELECT '\/home\/mailstore\/'||maildir AS userdb_home, username AS user, password, '*:bytes='||quota AS userdb_quota_rule \\\r\nFROM mailbox \\\r\nWHERE username = '%u' \\\r\nAND active = TRUE<\/pre>\n<p>This statement returns the mailbox path, the mailbox user, a hash of the password; and the quota rule.<\/p>\n<p>The rest of the configuration files are in the folder <strong>\/etc\/dovecot\/conf.d<\/strong>. Navigate to that folder now and edit the following files<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Configuration 10-mail.conf<\/strong><\/p>\n<p>This is the file that we use to set up dovecot to access the mail directory and. First we tell it where to find the mail directory (which in our case is <strong>\/home\/mailstore<\/strong>).<\/p>\n<pre class=\"lang:sh highlight:0 decode:true\">mail_location = maildir:\/home\/mailstore\/%d\/%n\/<\/pre>\n<p>The \u201c%d\/%n\u201d just represents the fqdn and the mailbox name.<\/p>\n<p>&nbsp;<\/p>\n<p>These directives all relate to the userid and groupid that will have access to the mailstore directory. If you remember, when we configured postfix we also created the <strong>\/home\/mailstore<\/strong> directory and a user and group both called mailer that were granted ownership of the directory. We then ran the <strong>id command<\/strong> to obtain the <strong>uid<\/strong> and <strong>gid<\/strong> of the mailer user which was <strong>1001<\/strong> for both the user and the group. Now we need to tell dovecot what uid and gid will be required to access this directory.<\/p>\n<pre class=\"lang:sh highlight:0 decode:true\">mail_uid = 1001\r\nmail_gid = 1001\r\nfirst_valid_uid = 1001\r\nlast_valid_uid = 1001\r\nfirst_valid_gid = 1001\r\nlast_valid_gid = 1001<\/pre>\n<p>The only other thing we need to do is tell dovecot that we want to enable the quota plugin<\/p>\n<pre class=\"lang:sh highlight:0 decode:true \">mail_plugins = quota<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Configuration 15-mailboxes.conf<\/strong><\/p>\n<p>This is optional, but if you want to autocreate folders for junk, trash and sent, or even some other folder the first time that a user logs on then this is where you do it. There is good documentation within the file but in brief, if you want to enable the auto creation of a particular folder then add<\/p>\n<pre class=\"lang:sh highlight:0 decode:true\">auto=subscribe<\/pre>\n<p>within its stanza.<\/p>\n<p>If you want to create a folder inside another then you need to use a period \u201c.\u201d as a separator. The period \u201c.\u201d after INBOX will cause dovecot to create the Junk folder inside INBOX.<\/p>\n<pre class=\"lang:sh highlight:0 decode:true \">mailbox INBOX.Junk {\r\n    auto=subscribe\r\n    special_use = \\Junk\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Configuration 20-lmtp.conf<\/strong><\/p>\n<p>Within the protocol lmtp stanza you need to add the following<\/p>\n<pre class=\"lang:sh decode:true\">protocol lmtp {\r\n    mail_plugins = $mail_plugins sieve\r\n    postmaster_address=postmaster@fqdn.suffix\r\n    hostname=server.fqdn.suffix\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Configuration 20-imap.conf<\/strong><\/p>\n<p>Only one line to check here<\/p>\n<pre class=\"lang:sh highlight:0 decode:true \">mail_plugins = $mail_plugins imap_quota<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Configuration 10-master.conf<\/strong><\/p>\n<p>Now on to 10-master.conf and change the unix_listner auth-userdb directives within the \u201cservice auth\u201d stanza to<\/p>\n<pre class=\"lang:sh highlight:0 decode:true\">unix_listener auth-userdb {\r\n    mode = 0600\r\n    user = mailer\r\n    group = mailer\r\n}<\/pre>\n<p>and add the following, also within the service auth stanza<\/p>\n<pre class=\"lang:sh highlight:0 decode:true \">unix_listener \/var\/spool\/postfix\/private\/auth {\r\n    mode = 0666\r\n    user = postfix\r\n    group = postfix\r\n}<\/pre>\n<p>In the service auth-worker stanza add<\/p>\n<pre class=\"lang:sh highlight:0 decode:true \">service auth-worker {\r\n    user = $default_internal_user\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Configuration 10-auth.conf<\/strong><\/p>\n<p>Here you need to uncomment <strong>!include auth-sql.conf.ext<\/strong> and comment out <strong>!include auth-system.conf.ext<\/strong> so that dovecot knows that it is using our sql server for authentication. We also want to make sure that we are not allowing plain text authorisation (note you might want to temporarily enable plain text while you are testing, but make sure you turn it off when you are done)<\/p>\n<pre class=\"lang:sh highlight:0 decode:true \">disable_plaintext_auth = yes\r\n#!include auth-system.conf.ext\r\n!include auth-sql.conf.ext<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Configuration 15-lda.conf<\/strong><\/p>\n<p>This is a fairly simple one, just don\u2019t forget to set the postmaster address to the proper value<\/p>\n<pre class=\"lang:c++ decode:true \">postmaster_address = postmaster@domain.net\r\n    protocol lda {\r\n    mail_plugins = $mail_plugins sieve\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Configuration 90-plugin.conf<\/strong><\/p>\n<p>Now we need to provide some information about sieve<\/p>\n<pre class=\"lang:sh highlight:0 decode:true \">plugin {\r\n    sieve = ~\/.dovecot.sieve\r\n    sieve_global_path = \/var\/lib\/dovecot\/sieve\/default.sieve\r\n    sieve_dir = ~\/sieve\r\n    sieve_global_dir = \/var\/lib\/dovecot\/sieve\/global\/\r\n}<\/pre>\n<p>We also need to create the <strong>\/var\/lib\/dovecot\/sieve<\/strong> directory and change the owner to mailer:mailer<\/p>\n<pre class=\"lang:sh decode:true\">#mkdir \/var\/lib\/dovecot\/sieve\r\n#chown \u2013R mailer:mailer \/var\/lib\/dovecot\/sieve<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>Configuration 10-ssl.conf<\/strong><\/p>\n<p>The final configuration file is the ssl configuration that tells dovecot where to look for the certificates. We need to tell dovecot that we want to use ssl so we need to change \u201cssl =\u201d to yes<\/p>\n<pre class=\"lang:sh highlight:0 decode:true\">ssl = yes<\/pre>\n<p>Back when we configured apache we created the certificates \u201cmailserver.pem\u201d and \u201cmailserver.key\u201d in \/etc\/ssl\/certs and \/etc\/ssl\/private respectively so all we need to do is add the following 2 lines (NOTE:\u00a0 If you want to use certbot certificates then you need to set these directives to the path of those instead)<\/p>\n<pre class=\"lang:sh highlight:0 decode:true\">ssl_cert = &lt;\/etc\/ssl\/certs\/mailserver.pem\r\nssl_key = &lt;\/etc\/ssl\/private\/mailserver.key<\/pre>\n<p>It is not clear why the \u201c&lt;\u201d is there, but it is necessary.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>Final actions\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <\/strong><\/p>\n<p>The final step is to tell Postfix to use this socket for final delivery, in this case in a virtual user scenario. All you have to do is add<\/p>\n<pre class=\"lang:sh highlight:0 decode:true \">virtual_transport = lmtp:unix:private\/dovecot-lmtp<\/pre>\n<p>to the end of \/etc\/postfix\/main.cf<\/p>\n<p>You should now be able to restart dovecot and provided that you have added a domain and user you should be able to connect to the server using a client.<\/p>\n<p>Enable debugging and check the logs. At the top of \/etc\/dovecot\/dovecot.conf add<\/p>\n<pre class=\"lang:sh highlight:0 decode:true \">mail_debug = yes<\/pre>\n<p>You will want to remove this when you are sure your configuration is ok<\/p>\n<p>If for some reason the server is not working as it should, check the log file for errors<\/p>\n<pre class=\"lang:sh decode:true\">#tail \u2013f \/var\/log\/mail.log<\/pre>\n<p>If you need authentication and password related debug message, turn on related settings and restart dovecot service.<\/p>\n<pre class=\"lang:sh highlight:0 decode:true\">auth_verbose = yes\r\nauth_debug = yes\r\nauth_debug_passwords = yes\r\nauth_verbose_passwords = yes<\/pre>\n<p>If you see many error message (like\u00a0dovecot fails, spawning too quickly) in Dovecot error log while restarting Dovecot, there might be something wrong in Dovecot config file. Please try to start it on command line manually, it will report configuration error if any, fix them and start it again:<\/p>\n<pre class=\"lang:sh decode:true \">#dovecot -c \/etc\/dovecot\/dovecot.conf<\/pre>\n<p>&nbsp;<\/p>\n<p>ADDENDUM<\/p>\n<p>By default dovecot is initialised with diffie-hellman parameters file that is 1024 bit encrypted. This is pretty insecure for todays systems so is adviseable to up it a bit. 2048 will take it a little time to start but you could probably live with it, but once you get to 4096 it becomes painful (hours painful) for dovecot to generate the key.<\/p>\n<p>The workaround for this is to leave your dovecot server running and run a second instance that will just create the key. To do this you need to observe the following steps:<\/p>\n<p>&nbsp;<\/p>\n<p>Generate a temporary minimal config:<\/p>\n<pre class=\"lang:sh decode:true\">#cat &lt;&lt;EOF &gt; \/tmp\/ssl-params.conf ssl_dh_parameters_length = 4096 state_dir = \/tmp\/ EOF<\/pre>\n<p>creates a small configuration file.<\/p>\n<p>Remove any old attempts and then start an instance to automatically generate the file<\/p>\n<pre class=\"lang:sh decode:true\">#rm -f \/tmp\/ssl-parameters.dat*\r\n#nice -n 19 \/path\/to\/ssl-params -c \/tmp\/ssl-params.conf<\/pre>\n<p>If you have an uncommented ssl_dh_parameters_length directive in your main instance\u2019 10-ssl.conf file then you need to comment it out, otherwise it will try to generate a new key when you restart the server.<\/p>\n<pre class=\"lang:sh decode:true\">#vi \/etc\/dovecot\/conf.d\/10-ssl.conf<\/pre>\n<p>Once the file has been generated you can move it to your running configuration<\/p>\n<pre class=\"lang:c++ decode:true\">#mv \/tmp\/ssl-parameters.dat \/var\/lib\/dovecot\/\r\n#doveadm reload<\/pre>\n<p>You can now remove the configuration file you created earlier if you wish.<\/p>\n<pre class=\"lang:sh decode:true \">#rm \/tmp\/ssl-params.conf<\/pre>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>While postfix provides SMTP outgoing mail services dovecot manages the inbound traffic and the mail boxes. In the previous parts of this guide we configured postfixadmin so that we can add domains and mailboxes to the database. This information is also useful to dovecot so as part of our configuration of dovecot we are going [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[],"class_list":["post-139","post","type-post","status-publish","format-standard","hentry","category-debian-server"],"_links":{"self":[{"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=\/wp\/v2\/posts\/139","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=139"}],"version-history":[{"count":2,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=\/wp\/v2\/posts\/139\/revisions"}],"predecessor-version":[{"id":547,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=\/wp\/v2\/posts\/139\/revisions\/547"}],"wp:attachment":[{"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=139"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=139"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.inplico.uk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=139"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}