Compare commits
2 commits
0d76c2bf8b
...
2f7d5bd542
Author | SHA1 | Date | |
---|---|---|---|
2f7d5bd542 | |||
4680eca001 |
1 changed files with 87 additions and 65 deletions
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue