Compare commits

...

2 commits

View file

@ -507,6 +507,17 @@ Check the Dovecot version with:
$ dovecot --version $ dovecot --version
Before you do anything, Dovecot requires that `dovecot_config_version` and `dovecot_storage_version` are the first
defined variables in `/etc/dovecot/dovecot.conf`. Edit this file and add, prior to any other settings,
```conf
dovecot_config_version = 2.4.1
dovecot_storage_version = 2.4.1
```
Or whatever the output of `dovecot --version` is, though note that, if different, some of this guide may not apply to
your version of Dovecot.
Now let's enable IMAP by editing `/etc/dovecot/dovecot.conf`. Find a `protocols = ` line, or add one, and set it to: Now let's enable IMAP by editing `/etc/dovecot/dovecot.conf`. Find a `protocols = ` line, or add one, and set it to:
```conf ```conf
@ -552,11 +563,23 @@ You should already have an `/etc/logrotate.d/dovecot` file. If not, create it wi
You probably want to use the Maildir format for storing emails, where each user's mail is stored at `~/Maildir` (this You probably want to use the Maildir format for storing emails, where each user's mail is stored at `~/Maildir` (this
can be set to another location if desired). can be set to another location if desired).
In `/etc/dovecot/conf.d/10-mail.conf`, set: In `/etc/dovecot/conf.d/10-mail.conf`, in `namespace inbox` (or create the section if it does not exist):
```conf ```conf
mail_location = maildir:~/Maildir namespace inbox {
mail_privileged_group = mail mail_driver = maildir
mail_path = %{owner_home}/Maildir
}
```
If there is not already `inbox = yes` in the `inbox` namespace, add it:
```conf
namespace inbox {
# ...
inbox = yes
# ...
}
``` ```
`mail_privileged_group` tells us which group of Unix users can send mail; in this case, it's anyone in the `mail` `mail_privileged_group` tells us which group of Unix users can send mail; in this case, it's anyone in the `mail`
@ -573,7 +596,9 @@ To change the Maildir directory, e.g. to set it to `~/mail`, you would set the f
`/etc/dovecot/conf.d/10-mail.conf`: `/etc/dovecot/conf.d/10-mail.conf`:
```conf ```conf
mail_location = maildir:~/mail namespace inbox {
mail_path = %{owner_home}/mail
}
``` ```
`/etc/postfix/main.cf`: `/etc/postfix/main.cf`:
@ -615,19 +640,22 @@ smtputf8_enable = no
## Configuring authentication ## Configuring authentication
Edit `/etc/dovecot/conf.d/10-auth.conf` and uncomment the following line: Edit `/etc/dovecot/conf.d/10-auth.conf` and add the following line (or change it if the setting is set to `yes`):
```conf ```conf
disable_plaintext_auth = yes auth_allow_cleartext = no
``` ```
This disables plaintext authentication *unless* SSL/TLS is used. This disables plaintext authentication *unless* SSL/TLS is used.
In the same file, configure `auth_username_format`. As the variable name suggests, this denotes the format the server In the same file, configure `auth_username_format`. As the variable name suggests, this denotes the format the server
expects usernames in for authentication. Setting it to `%n` removes the domain, so to sign in to `user@domain.com` expects usernames in for authentication. Dovecot's variables have "filters" which can be chained with pipes. Say your
you'd enter your username as `user`. For this setup, you should set `auth_username_format` to `%n`, because we are email address is `fred@domain.com`. This is the variable `%{user}`. We want to be able to log in with just `fred` as
using Unix user accounts for email accounts; Dovecot wouldn't be able to find `user@domain.com` because the mailbox our username. To do this, we apply the `username` filter, so we set
user is just `user`.
```conf
auth_username_format = %{user | username}
```
In the same file again, `auth_mechanisms` is a space-separated list of authentication mechanisms your server uses. Set In the same file again, `auth_mechanisms` is a space-separated list of authentication mechanisms your server uses. Set
this to this to
@ -655,16 +683,20 @@ We will use a file at `/etc/dovecot/passwd` to manage this. Edit `/etc/dovecot/c
the following: the following:
```conf ```conf
passdb { passdb passwd-file {
driver = passwd-file driver = passwd-file
args = scheme=argon2id username_format=%n /etc/dovecot/passwd auth_username_format = %{user | username}
default_password_scheme = argon2id
passwd_file_path = /etc/dovecot/passwd
} }
userdb { userdb passwd-file {
driver = passwd driver = passwd
} }
``` ```
Your `auth_username_format` should match the one you set in `/etc/dovecot/conf.d/10-auth.conf`.
See [this documentation](https://doc.dovecot.org/main/core/config/auth/schemes.html) to decide on a password scheme to See [this documentation](https://doc.dovecot.org/main/core/config/auth/schemes.html) to decide on a password scheme to
use. I picked `argon2id` as the most secure option, however also the most expensive option, so it may be a poor option use. I picked `argon2id` as the most secure option, however also the most expensive option, so it may be a poor option
if you have many users. Dovecot recommends that, if using ARGON2ID, you set `vsz_limit = 2G` for the `auth` service. To if you have many users. Dovecot recommends that, if using ARGON2ID, you set `vsz_limit = 2G` for the `auth` service. To
@ -722,16 +754,16 @@ just change their values):
```conf ```conf
ssl = required ssl = required
ssl_cert = </etc/letsencrypt/live/mail.domain.com/fullchain.pem ssl_server_cert_file = /etc/letsencrypt/live/mail.domain.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.domain.com/privkey.pem ssl_server_key_file = /etc/letsencrypt/live/mail.domain.com/privkey.pem
ssl_prefer_server_ciphers = yes ssl_server_prefer_ciphers = server
ssl_min_protocol = TLSv1.2 ssl_min_protocol = TLSv1.2
ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305 ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305
``` ```
Replace `mail.domain.com` with the domain you obtained your TLS certificate for. You can check Replace `mail.domain.com` with the domain you obtained your TLS certificate for. You can check
$ ls /etc/letsencrypt/live # ls /etc/letsencrypt/live
if you're not sure. if you're not sure.
@ -809,9 +841,11 @@ reading our mail since they can't read the private key.
If you want to implement it, declare usage of the `mail_crypt` plugin in `/etc/dovecot/dovecot.conf`: If you want to implement it, declare usage of the `mail_crypt` plugin in `/etc/dovecot/dovecot.conf`:
```conf ```conf
mail_plugins = $mail_plugins mail_crypt mail_plugins = mail_crypt
``` ```
If you already have plugins declared in `mail_plugins`, append `mail_crypt`.
Now let's generate some elliptic curve keys for this. Now let's generate some elliptic curve keys for this.
See what curves are available: See what curves are available:
@ -838,13 +872,12 @@ Give them the correct permissions:
# chmod 644 ecpubkey.pem # chmod 644 ecpubkey.pem
# chmod 600 ecprivkey.pem # chmod 600 ecprivkey.pem
Anyway, create and edit `/etc/dovecot/conf.d/90-mail_crypt.conf` and configure the plugin as follows: Create and edit `/etc/dovecot/conf.d/90-mail_crypt.conf` and configure the plugin as follows:
```conf ```conf
plugin { crypt_global_public_key_file = /etc/dovecot/ecpubkey.pem
mail_crypt_global_private_key = </etc/dovecot/ecprivkey.pem crypt_global_private_key main {
mail_crypt_global_public_key = </etc/dovecot/ecpubkey.pem crypt_private_key_file = /etc/dovecot/ecprivkey.pem
mail_crypt_save_version = 2
} }
``` ```
@ -1787,18 +1820,23 @@ Then edit `/etc/dovecot/conf.d/20-lmtp.conf`, and add the `sieve` plugin like so
```conf ```conf
protocol lmtp { protocol lmtp {
# Space separated list of plugins to load (default is global mail_plugins). mail_plugins = {
mail_plugins = $mail_plugins sieve sieve = yes
}
} }
``` ```
To configure Pigeonhole and sieve, edit `/etc/dovecot/conf.d/90-sieve.conf`. Sieve's options will be configured in the To configure Pigeonhole and sieve, edit `/etc/dovecot/conf.d/90-sieve.conf`. Sieve's options will be configured in the
`plugin {}` block in this file. `plugin {}` block in this file.
We can set the location of user sieve scripts with the `sieve` option. Let's set the location of user sieve scripts as follows:
```conf ```conf
sieve = file:~/sieve;active=~/.dovecot.sieve sieve_script personal {
driver = file
path = ~/sieve
active_path = ~/.dovecot.sieve
}
``` ```
means that `~/sieve` is a directory of sieve scripts, whilst `~/.dovecot.sieve` is a symlink to the "active" one, e.g. means that `~/sieve` is a directory of sieve scripts, whilst `~/.dovecot.sieve` is a symlink to the "active" one, e.g.
@ -1814,28 +1852,6 @@ could be your `~/sieve/` directory, and to make `script2.sieve` active, you woul
$ ln -s ~/sieve/script2.sieve ~/.dovecot.sieve $ ln -s ~/sieve/script2.sieve ~/.dovecot.sieve
`sieve_before` defines a directory of sieve scripts which will be executed *prior* to any user scripts. e.g.
```conf
sieve_before = /etc/dovecot/sieve
```
means that the sieve scripts in `/etc/dovecot/sieve` will be executed first, then the user's personal scripts at
`~/.dovecot.sieve`.
You can specify multiple directories in order, like so:
```conf
sieve_before = /var/lib/dovecot/sieve.d/
sieve_before2 = ldap:/etc/sieve-ldap.conf;name=ldap-domain
sieve_before3 = /etc/dovecot/sieve
```
etc. The `sieve_after` option also exists, and works the same way.
This is not the same as `sieve_default`, which is *overridden* by user sieve scripts and only executes when a user has
no sieve script.
You can review [this documentation](https://doc.dovecot.org/main/core/plugins/sieve.html) for a full list of Pigeonhole You can review [this documentation](https://doc.dovecot.org/main/core/plugins/sieve.html) for a full list of Pigeonhole
options. options.
@ -1845,28 +1861,15 @@ Users can configure their own user sieve scripts using a protocol called ManageS
read their emails without having shell access to the mail server, ManageSieve allows users to write sieve scripts read their emails without having shell access to the mail server, ManageSieve allows users to write sieve scripts
without requiring shell access. without requiring shell access.
To enable ManageSieve, edit `/etc/dovecot/conf.d/20-managesieve.conf`. Make sure the following line is uncommented: To enable ManageSieve, edit `/etc/dovecot/conf.d/20-managesieve.conf`. Make sure that the `service managesieve-login`,
`service managesieve`, and `protocol sieve` lines are uncommented.
```conf
protocols = $protocols sieve
```
By default, ManageSieve will listen on port 4190. By default, ManageSieve will listen on port 4190.
## Sieve scripts for spam filtering ## Sieve scripts for spam filtering
Let's use a system-wide sieve script to file SpamAssassin-marked spam into a Spam folder. Create an Let's use a system-wide sieve script to file SpamAssassin-marked spam into a Spam folder. Create an
`/etc/dovecot/sieve/` directory, and add it to your `sieve_before` settings: `/etc/dovecot/sieve/` directory. Now create a new sieve script, `/etc/dovecot/sieve/spam_folder.sieve`:
```conf
plugin {
...
sieve_before = /etc/dovecot/sieve/
...
}
```
Now create a new sieve script, `/etc/dovecot/sieve/spam_folder.sieve`:
```sieve ```sieve
require ["fileinto", "mailbox"]; require ["fileinto", "mailbox"];
@ -1884,6 +1887,18 @@ Inbox
you would write `"Inbox.Spam"` in that case. you would write `"Inbox.Spam"` in that case.
Now we want to have this run *before* any personal sieve scripts. To do this, add the following to
`/etc/dovecot/conf.d/90-sieve.conf`:
```conf
sieve_script spam_folder {
type = before
path = /etc/dovecot/sieve/spam_folder.sieve
}
```
`type = before` specifies that we want this to execute before the `personal` sieve script.
# Miscellaneous suggestions # Miscellaneous suggestions
To use fail2ban for your mail server, create `/etc/fail2ban/jail.d/mail.local`: To use fail2ban for your mail server, create `/etc/fail2ban/jail.d/mail.local`:
@ -1911,6 +1926,13 @@ admins can submit their domain and IP address to indicate trustworthiness.
Finally, you can [PGP-encrypt users' incoming mail with their public keys, much like Finally, you can [PGP-encrypt users' incoming mail with their public keys, much like
Protonmail](/blog/pgp_encrypting_all_incoming_emails/). Protonmail](/blog/pgp_encrypting_all_incoming_emails/).
# Changelog
* **2025/06/04:** Dovecot's 2.4 update introduced [many breaking changes to the config
syntax](https://doc.dovecot.org/2.4.1/core/config/service.html#protocol). This post has been updated
to reflect the 2.4 syntax. If you want to set up a 2.3 server, see [this
commit](https://git.revsuine.xyz/revsuine/revsuine.xyz/src/commit/94d49bae8315a6ca761859591eb8d9b7566718e7/content/blog/mail_server_alpine_postfix_dovecot_tutorial/index.md)
<!-- FOOTNOTES: --> <!-- FOOTNOTES: -->
[^server_trust]: This is only true to the extent that your server is not compromised. You could say there's an order of [^server_trust]: This is only true to the extent that your server is not compromised. You could say there's an order of