{ pkgs, lib, config, system, ... }:
let
- inherit (builtins) toString toFile;
+ inherit (builtins) toString toFile readFile;
inherit (builtins.extraBuiltins) pass;
inherit (lib) types;
inherit (pkgs.lib) loadFile unlines unlinesAttrs unlinesValues unwords;
inherit (config.services) dovecot2 postfix openldap;
# NOTE: nixpkgs' dovecot2.stateDir is currently not exported
- stateDir = "/var/lib/dovecot";
+ stateDir = "/var/lib/dovecot";
sieve_pipe_bin_dir = pkgs.buildEnv {
name = "sieve_pipe_bin_dir";
in
{
imports = [
- dovecot/autoconfig.nix
+ dovecot/sourcephile.fr.nix
+ dovecot/autogeree.net.nix
];
+users.groups.acme.members = [ dovecot2.user ];
systemd.services.dovecot2 = {
after = [
"postfix.service"
"openldap.service"
- "${networking.domain}.key.pem-key.service"
];
+ /*
+ preStart = ''
+ # SEE: http://wiki2.dovecot.org/SharedMailboxes/Permissions
+ install -D -d -m 0771 \
+ -o "${dovecot2.user}" \
+ -g "${dovecot2.group}" \
+ ${stateDir}/mail
+ '';
+ */
};
#users.users."${dovecot2.mailUser}".isSystemUser = true; # Fix nixpkgs
services.dovecot2 = {
- enable = true;
- modules = [
+ enable = true;
+ modules = [
pkgs.dovecot_pigeonhole
pkgs.dovecot_fts_xapian
];
enablePAM = false;
enableImap = true;
enableLmtp = true;
- enablePop3 = true;
+ enablePop3 = false;
protocols = [ "sieve" ];
- mailLocation = "sdbox:${stateDir}/mail/%d/%n/mail.d:UTF-8:CONTROL=${stateDir}/control/%d/%n:INDEX=${stateDir}/index/%d/%n";
+ # If needed, may be overrided by userdb_mail= in passdb, or mail= in userdb
+ # Here INDEX and CONTROL are separated,
+ # it's not useful since there is no quota at the filesystem level
+ # it's just to let this possibility later on.
+ mailLocation = "sdbox:${stateDir}/home/%d/%n/mail:UTF-8:CONTROL=${stateDir}/control/%d/%n:INDEX=${stateDir}/index/%d/%n";
createMailUser = false;
mailUser = "";
mailGroup = "";
extraConfig = ''
auth_verbose = no
auth_debug = no
- mail_debug = yes
+ mail_debug = no
verbose_ssl = no
log_timestamp = "%Y-%m-%d %H:%M:%S "
ssl = required
ssl_dh = <${../../../sec/openssl/dh.pem}
ssl_cipher_list = HIGH:!LOW:!SSLv2:!EXP:!aNULL
- ssl_cert = <${loadFile (../../../sec + "/openssl/${networking.domain}/cert.self-signed.pem")}
- ssl_key = </run/keys/${networking.domain}.key.pem
+ ssl_prefer_server_ciphers = yes
+ ssl_cert = </var/lib/acme/${networking.domain}/fullchain.pem
+ ssl_key = </var/lib/acme/${networking.domain}/key.pem
#ssl_ca = <''${caPath}
#ssl_verify_client_cert = yes
listen = *
- # If needed, may be overrided by userdb_mail
- mail_home = ${stateDir}/mail/%d/%n
+ mail_home = ${stateDir}/home/%d/%n
# Read multiple mails in parallel, improves performance
mail_prefetch_count = 20
# Default VSZ (virtual memory size) limit for service processes. This is mainly
# Increased for fts_xapian.
default_vsz_limit = 1G
- passdb {
- driver = ldap
- args = ${loadFile (dovecot/ldap + "/${networking.domainBase}.conf")}
- default_fields = userdb_mail_access_groups=${networking.domainBase}
- override_fields =
- }
- userdb {
- driver = prefetch
- }
- userdb {
- # NOTE: this userdb is only used by lda.
- driver = ldap
- args = ${loadFile (dovecot/ldap + "/${networking.domainBase}.conf")}
- default_fields = mail_access_groups=${networking.domainBase}
- override_fields =
- skip = found
- }
+ # DOC: https://doc.dovecot.org/configuration_manual/authentication/authentication_mechanisms/
+ # DOC: https://ldapwiki.com/wiki/DIGEST-MD5
+ # The misunderstanding is the notion "password sent over the network in plain-text" is not secure,
+ # when in fact, storing the password in the directory server using a Salted SHA-2 hash
+ # and transmitting the clear text password over a secure connection
+ # is more secure than having the directory server store the password in clear text
+ # or in a reversible encryption scheme.
+ # Therefore, SASL with DIGEST-MD5 (or CRAM-MD5) should be avoided.
+ # Use doveadm pw -s SSHA
+ # or doveadm pw -s PBKDF2 -r 10000
+ # or slappasswd -o module-load=pw-pbkdf2 -h "{PBKDF2-SHA256}"
+ auth_mechanisms = plain login
+ auth_username_format = %Ln
service auth {
- # FIXME: may be user=dovecot-auth with LDAP?
- user = root
+ user = ${dovecot2.user}
+ # auth_socket_path points to this userdb socket by default. It's typically
+ # used by dovecot-lda, doveadm, possibly imap process, etc.
+ # Users that have access to this socket are able to get a list
+ # of all usernames and get results of everyone's userdb lookups.
unix_listener auth-userdb {
user = ${dovecot2.user}
group = ${dovecot2.group}
mode = 0660
}
}
+ service auth-worker {
+ user = ${dovecot2.user}
+ }
auth_cache_verify_password_with_worker = yes
- # NOTE: if needed, may be overrided by userdb_mail
- # NOTE: INDEX and CONTROL are on a partition without quota, as explain in the doc.
# SEE: http://wiki2.dovecot.org/Quota/FS
- auth_mechanisms = plain login
# NOTE: postfix does not supply a client cert.
auth_ssl_require_client_cert = no
#auth_ssl_username_from_cert = yes
first_valid_uid = 1000
disable_plaintext_auth = yes
- #passdb {
- # driver = passwd-file
- # args = scheme=crypt username_format=%n ${stateDir}/passwd/%d
- #}
- #userdb {
- # # NOTE: this userdb is only used by LDA.
- # driver = passwd-file
- # args = username_format=%n ${stateDir}/passwd/%d
- # #default_fields = home=${stateDir}/mail/%d/%n
- # skip = found
- #}
+ userdb {
+ driver = ldap
+ # A different path than passdb's args enables non-blocking LDAP requests
+ args = ${pkgs.symlinkJoin {name="ldap"; paths=[./dovecot];}}/ldap.conf
+ default_fields =
+ override_fields =
+ }
# No dirty syncs for maildir: locations which may be used directly by neomutt
maildir_very_dirty_syncs = no
# NOTE: %var expands to the logged in user's variable, while
# %%var expands to the other users' variables.
# NOTE: INDEX and CONTROL are shared, INDEXPVT is not.
- location = sdbox:${stateDir}/mail/%%d/%%n/${stateDir}/mail.d:UTF-8:CONTROL=${stateDir}/control/%%d/%%n/Shared:INDEX=${stateDir}/index/%%d/%%n/Shared:INDEXPVT=${stateDir}/index/%d/%n/Shared/%%n
+ location = sdbox:${stateDir}/home/%%d/%%n/${stateDir}/mail:UTF-8:CONTROL=${stateDir}/control/%%d/%%n/shared:INDEX=${stateDir}/index/%%d/%%n/shared:INDEXPVT=${stateDir}/index/%d/%n/shared/%%n
prefix = Partages+%%n+
separator = +
subscriptions = yes
mail_plugins = $mail_plugins acl
plugin {
- acl = vfile:/etc/dovecot/acl/global.d
+ acl = vfile:/etc/dovecot/acl/global
acl_anyone = allow
# NOTE: to let users LIST mailboxes shared by other users,
# Dovecot needs a shared mailbox dictionary.
mail_plugins = $mail_plugins fts fts_xapian
plugin {
+ # WARNING: doveadm fts rescan is buggy, it will delete the index:
+ # https://dovecot.org/pipermail/dovecot/2019-February/114709.html
+ # If need be, use rather: doveadm index -u "*@sourcephile.fr" -q '*'
plugin = fts fts_xapian
fts = xapian
fts_autoindex = yes
# 2 and 20 are the NGram values for header fields, which means the
# keywords created for fields (To, Cc, ...) are between is 2 and 20 chars long.
# Full words are also added by default.
- fts_xapian = partial=2 full=20 verbose=0
+ fts_xapian = partial=2 full=20 attachments=1 verbose=0
+ fts_languages = en fr
+ #fts_dovecot_fs = posix:prefix=%h/fts/
}
mail_plugins = $mail_plugins quota
}
protocol lda {
- auth_socket_path = /var/run/dovecot/auth-userdb
- hostname = ${networking.domain}
- info_log_path =
- log_path =
- mail_plugins = $mail_plugins sieve
+ hostname = ${networking.domain}
+ mail_plugins = $mail_plugins sieve
postmaster_address = postmaster+dovecot+lda@${networking.domain}
syslog_facility = mail
}
lda_mailbox_autosubscribe = yes
protocol lmtp {
- #info_log_path = /tmp/dovecot-lmtp.log
mail_plugins = $mail_plugins sieve
postmaster_address = postmaster+dovecot+lmtp@${networking.domain}
}
service lmtp {
- #executable = lmtp -L
process_min_avail = ${toString config.nix.maxJobs}
unix_listener /var/lib/postfix/queue/private/dovecot-lmtp {
user = ${postfix.user}
group = ${postfix.group}
mode = 0600
}
- #user = mail
}
plugin {
# Let extension.sieve do the handling of the detail
mailbox All {
auto = no
comment = All messages from all mailboxes
+ # This flag is confused with \Archives by K9-Mail
special_use = \All
}
mailbox Recents {
auto = no
- comment = All messages from all mailboxes arrived in the past 48h
+ comment = All messages from all mailboxes, arrived in the past 48h
}
}
}
plugin {
- #sieve_default = file:${stateDir}/mail/%u/default.sieve
- #sieve_default_name = default
sieve_plugins = sieve_imapsieve sieve_extprograms
- sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.environment
+ sieve_global_extensions = +vnd.dovecot.environment +vnd.dovecot.pipe
#sieve_extensions = +editheader
- sieve = file:~/sieve.d;active=~/sieve
+ sieve = file:~/sieve;active=~/active.sieve
+ sieve_default = file:${stateDir}/sieve/global/default.sieve
+ sieve_default_name = main
sieve_pipe_bin_dir = ${sieve_pipe_bin_dir}/bin
sieve_max_script_size = 1M
sieve_quota_max_scripts = 0
#sieve_spamtest_max_value = 10
#sieve_spamtest_status_header = X-Spam-Score
#sieve_spamtest_status_type = strlen
- sieve_user_log = /var/log/dovecot/%d/sieve.%n.log
+ #sieve_user_log = ~/sieve.log
# Enables support for user Sieve scripts in IMAP
#imapsieve_url = sieve://mail.${networking.domain}:4190
# To fool ManageSieve clients that are focused on CMU's timesieved you can specify
# the IMPLEMENTATION capability that the dovecot reports to clients.
- # For example: 'Cyrus timsieved v2.2.13'
+ # For example: 'Cyrus timesieved v2.2.13'
managesieve_implementation_string = Dovecot Pigeonhole
# The maximum number of compile errors that are returned to the client upon script
service quota-warning {
executable = script ${
- pkgs.writeScript "quota-warning" ''
- #!/bin/sh -eu
+ pkgs.writeShellScript "quota-warning" ''
+ set -eu
PERCENT=$1
USER=$2
cat << EOF | ${pkgs.dovecot}/libexec/dovecot/dovecot-lda -d $USER -o
}
}
'';
- #${lib.concatMapStringsSep "\n"
- # (dom: ''
- # local_name mail.${dom} {
- # #ssl_ca = <''${caPath}
- # ssl_cert = <${x509.cert dom}
- # ssl_key = <${x509.key dom}
- # }
- # '')
- # dovecot2.domains
- #}
};
-#services.postfix.mapFiles."transport-dovecot" =
-# toFile "transport-dovecot"
-# (unlines
-# (lib.mapAttrsToList
-# (dom: {...}: "${transportSubDomain}.${dom} lmtp:unix:private/dovecot-lmtp")
-# dovecot2.domains));
}