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
|
||||
|
||||
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:
|
||||
|
||||
```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
|
||||
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
|
||||
mail_location = maildir:~/Maildir
|
||||
mail_privileged_group = mail
|
||||
namespace inbox {
|
||||
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`
|
||||
|
@ -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`:
|
||||
|
||||
```conf
|
||||
mail_location = maildir:~/mail
|
||||
namespace inbox {
|
||||
mail_path = %{owner_home}/mail
|
||||
}
|
||||
```
|
||||
|
||||
`/etc/postfix/main.cf`:
|
||||
|
@ -615,19 +640,22 @@ smtputf8_enable = no
|
|||
|
||||
## 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
|
||||
disable_plaintext_auth = yes
|
||||
auth_allow_cleartext = no
|
||||
```
|
||||
|
||||
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
|
||||
expects usernames in for authentication. Setting it to `%n` removes the domain, so to sign in to `user@domain.com`
|
||||
you'd enter your username as `user`. For this setup, you should set `auth_username_format` to `%n`, because we are
|
||||
using Unix user accounts for email accounts; Dovecot wouldn't be able to find `user@domain.com` because the mailbox
|
||||
user is just `user`.
|
||||
expects usernames in for authentication. Dovecot's variables have "filters" which can be chained with pipes. Say your
|
||||
email address is `fred@domain.com`. This is the variable `%{user}`. We want to be able to log in with just `fred` as
|
||||
our username. To do this, we apply the `username` filter, so we set
|
||||
|
||||
```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
|
||||
this to
|
||||
|
@ -655,16 +683,20 @@ We will use a file at `/etc/dovecot/passwd` to manage this. Edit `/etc/dovecot/c
|
|||
the following:
|
||||
|
||||
```conf
|
||||
passdb {
|
||||
passdb 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
|
||||
}
|
||||
```
|
||||
|
||||
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
|
||||
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
|
||||
|
@ -722,16 +754,16 @@ just change their values):
|
|||
|
||||
```conf
|
||||
ssl = required
|
||||
ssl_cert = </etc/letsencrypt/live/mail.domain.com/fullchain.pem
|
||||
ssl_key = </etc/letsencrypt/live/mail.domain.com/privkey.pem
|
||||
ssl_prefer_server_ciphers = yes
|
||||
ssl_server_cert_file = /etc/letsencrypt/live/mail.domain.com/fullchain.pem
|
||||
ssl_server_key_file = /etc/letsencrypt/live/mail.domain.com/privkey.pem
|
||||
ssl_server_prefer_ciphers = server
|
||||
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
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
|
@ -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`:
|
||||
|
||||
```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.
|
||||
|
||||
See what curves are available:
|
||||
|
@ -838,13 +872,12 @@ Give them the correct permissions:
|
|||
# chmod 644 ecpubkey.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
|
||||
plugin {
|
||||
mail_crypt_global_private_key = </etc/dovecot/ecprivkey.pem
|
||||
mail_crypt_global_public_key = </etc/dovecot/ecpubkey.pem
|
||||
mail_crypt_save_version = 2
|
||||
crypt_global_public_key_file = /etc/dovecot/ecpubkey.pem
|
||||
crypt_global_private_key main {
|
||||
crypt_private_key_file = /etc/dovecot/ecprivkey.pem
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -1787,18 +1820,23 @@ Then edit `/etc/dovecot/conf.d/20-lmtp.conf`, and add the `sieve` plugin like so
|
|||
|
||||
```conf
|
||||
protocol lmtp {
|
||||
# Space separated list of plugins to load (default is global mail_plugins).
|
||||
mail_plugins = $mail_plugins sieve
|
||||
mail_plugins = {
|
||||
sieve = yes
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
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.
|
||||
|
@ -1814,28 +1852,6 @@ could be your `~/sieve/` directory, and to make `script2.sieve` active, you woul
|
|||
|
||||
$ 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
|
||||
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
|
||||
without requiring shell access.
|
||||
|
||||
To enable ManageSieve, edit `/etc/dovecot/conf.d/20-managesieve.conf`. Make sure the following line is uncommented:
|
||||
|
||||
```conf
|
||||
protocols = $protocols sieve
|
||||
```
|
||||
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.
|
||||
|
||||
By default, ManageSieve will listen on port 4190.
|
||||
|
||||
## Sieve scripts for spam filtering
|
||||
|
||||
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:
|
||||
|
||||
```conf
|
||||
plugin {
|
||||
...
|
||||
sieve_before = /etc/dovecot/sieve/
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Now create a new sieve script, `/etc/dovecot/sieve/spam_folder.sieve`:
|
||||
`/etc/dovecot/sieve/` directory. Now create a new sieve script, `/etc/dovecot/sieve/spam_folder.sieve`:
|
||||
|
||||
```sieve
|
||||
require ["fileinto", "mailbox"];
|
||||
|
@ -1884,6 +1887,18 @@ Inbox
|
|||
|
||||
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
|
||||
|
||||
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
|
||||
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: -->
|
||||
|
||||
[^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