-{ inputs, pkgs, lib, config, system, host, ... }:
+{ pkgs, lib, config, host, ... }:
let
- inherit (builtins) toString toFile readFile;
- inherit (lib) types;
- inherit (pkgs.lib) loadFile unlines unlinesAttrs unlinesValues unwords;
+ inherit (builtins) toString;
inherit (config) networking;
- inherit (config.services) dovecot2 postfix openldap;
+ inherit (config.services) dovecot2 postfix;
- # NOTE: nixpkgs' dovecot2.stateDir is currently not exported
stateDir = "/var/lib/dovecot";
sieve_pipe_bin_dir = pkgs.buildEnv {
all younger 172800
'';
};
- dovecot-virtual-pop3 = pkgs.writeTextFile {
- name = "dovecot-virtual-pop3";
- destination = "/pop3/INBOX/dovecot-virtual";
- text = ''
- All
- All+*
- all
- '';
- };
in
{
-imports = [
- dovecot/sourcephile.fr.nix
- dovecot/autogeree.net.nix
-];
-users.groups.acme.members = [ dovecot2.user ];
-systemd.services.dovecot2 = {
- after = [
- "postfix.service"
- "openldap.service"
+ imports = [
+ dovecot/sourcephile.fr.nix
+ dovecot/autogeree.net.nix
];
- /*
- preStart = ''
- # SEE: http://wiki2.dovecot.org/SharedMailboxes/Permissions
- install -D -d -m 0771 \
- -o "${dovecot2.user}" \
- -g "${dovecot2.group}" \
- ${stateDir}/mail
- '';
- */
- preStart = ''
- ln -fns -t ${stateDir}/virtual/ \
- ${dovecot-virtual-all}/All \
- ${dovecot-virtual-recents}/Recents
- '';
- serviceConfig = {
- #ExecStart = lib.mkForce "${pkgs.utillinux}/bin/setarch x86_64 --addr-no-randomize /bin/sh -c 'LD_PRELOAD=${pkgs.gcc-unwrapped.lib}/lib/libasan.so ${pkgs.dovecot}/sbin/dovecot -F'";
- # Dovecot2 does not work with environment.memoryAllocator.provider="scudo"
- # https://wiki.dovecot.org/Design/Memory
- # Scudo ERROR: CHECK failed at /build/compiler-rt-7.1.0.src/lib/scudo/../sanitizer_common/sanitizer_allocator_primary64.h:
- # 644 ((beg)) == ((address_range.MapOrDie(beg, size))) (4398046511092, 4398046507008)
- BindReadOnlyPaths = [ "/dev/null:/etc/ld-nix.so.preload" ];
- StateDirectory = ["dovecot/virtual"];
- };
-};
-#users.users."${dovecot2.mailUser}".isSystemUser = true; # Fix nixpkgs
-networking.nftables.ruleset = ''
- add rule inet filter net2fw tcp dport 993 counter accept comment "IMAPS"
- #add rule inet filter net2fw tcp dport 995 counter accept comment "POP3S"
- add rule inet filter net2fw tcp dport 4190 counter accept comment "Sieve"
-'';
-fileSystems."/var/lib/dovecot" = {
- device = "rpool/var/mail";
- fsType = "zfs";
-};
-services.sanoid.datasets."rpool/var/mail" = {
- use_template = [ "snap" ];
- hourly = 12;
- daily = 7;
-};
-services.dovecot2 = {
- enable = true;
- modules = [
+ environment.systemPackages = [
pkgs.dovecot_pigeonhole
- pkgs.dovecot_fts_xapian
];
- enablePAM = false;
- enableImap = true;
- enableLmtp = true;
- enablePop3 = false;
- protocols = [ "sieve" ];
- # 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 = "";
- sslServerCert = null;
- sieveScripts = {
- global = dovecot/sieve/global;
+ users.groups.acme.members = [ dovecot2.user ];
+ systemd.services.dovecot2 = {
+ after = [
+ "postfix.service"
+ "openldap.service"
+ ];
+ /*
+ preStart = ''
+ # SEE: http://wiki2.dovecot.org/SharedMailboxes/Permissions
+ install -D -d -m 0771 \
+ -o "${dovecot2.user}" \
+ -g "${dovecot2.group}" \
+ ${stateDir}/mail
+ '';
+ */
+ preStart = ''
+ ln -fns -t ${stateDir}/virtual/ \
+ ${dovecot-virtual-all}/All \
+ ${dovecot-virtual-recents}/Recents
+ '';
+ serviceConfig = {
+ #ExecStart = lib.mkForce "${pkgs.utillinux}/bin/setarch x86_64 --addr-no-randomize /bin/sh -c 'LD_PRELOAD=${pkgs.gcc-unwrapped.lib}/lib/libasan.so ${pkgs.dovecot}/sbin/dovecot -F'";
+ # Dovecot2 does not work with environment.memoryAllocator.provider="scudo"
+ # https://wiki.dovecot.org/Design/Memory
+ # Scudo ERROR: CHECK failed at /build/compiler-rt-7.1.0.src/lib/scudo/../sanitizer_common/sanitizer_allocator_primary64.h:
+ # 644 ((beg)) == ((address_range.MapOrDie(beg, size))) (4398046511092, 4398046507008)
+ BindReadOnlyPaths = [ "/dev/null:/etc/ld-nix.so.preload" ];
+ StateDirectory = [ "dovecot/virtual" ];
+ };
};
- extraConfig = ''
- auth_verbose = no
- auth_debug = no
- mail_debug = no
- verbose_ssl = no
- log_timestamp = "%Y-%m-%d %H:%M:%S "
-
- ssl = required
- ssl_dh = <${inputs.secrets + "/openssl/dh.pem"}
- ssl_cipher_list = HIGH:!LOW:!SSLv2:!EXP:!aNULL
- 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
- # FIXME: change to TLSv1.3 when supported by K-9 Mail
- ssl_min_protocol = TLSv1.2
-
- listen = *
- 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
- # intended to catch and kill processes that leak memory before they eat up everything.
- # Increased for fts_xapian.
- default_vsz_limit = 1G
-
- # 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 {
- 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
- }
- unix_listener /var/lib/postfix/queue/private/auth {
- user = ${postfix.user}
- group = ${postfix.group}
- mode = 0660
+ #users.users."${dovecot2.mailUser}".isSystemUser = true; # Fix nixpkgs
+ networking.nftables.ruleset = ''
+ table inet filter {
+ chain input-net {
+ tcp dport imaps counter accept comment "dovecot: IMAPS"
+ #tcp dport 995 counter accept comment "dovecot: POP3S"
+ tcp dport sieve counter accept comment "dovecot: Sieve"
}
}
- service auth-worker {
- user = ${dovecot2.user}
- }
- auth_cache_verify_password_with_worker = yes
- # SEE: http://wiki2.dovecot.org/Quota/FS
- # NOTE: postfix does not supply a client cert.
- auth_ssl_require_client_cert = no
- #auth_ssl_username_from_cert = yes
- # NOTE: lowercase the username, help with LDAP?
- auth_username_format = %Lu
- # NOTE: sync with LDAP's data.
- first_valid_uid = 1000
- disable_plaintext_auth = yes
-
- 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 =
- }
+ '';
+ fileSystems."/var/lib/dovecot" = {
+ device = "rpool/var/mail";
+ fsType = "zfs";
+ };
+ services.sanoid.datasets."rpool/var/mail" = {
+ use_template = [ "snap" ];
+ daily = 7;
+ };
+ services.dovecot2 = {
+ enable = true;
+ modules = [
+ pkgs.dovecot_pigeonhole
+ # Commented out because it uses too much disk space
+ #pkgs.dovecot_fts_xapian
+ ];
+ enablePAM = false;
+ enableImap = true;
+ enableLmtp = true;
+ enablePop3 = false;
+ protocols = [ "sieve" ];
+ # 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 = "";
+ sslServerCert = null;
+ sieveScripts = {
+ global = dovecot/sieve/global;
+ };
+ extraConfig = ''
+ auth_verbose = no
+ auth_debug = no
+ mail_debug = no
+ verbose_ssl = no
+ log_timestamp = "%Y-%m-%d %H:%M:%S "
- # No dirty syncs for maildir: locations which may be used directly by neomutt
- maildir_very_dirty_syncs = no
- namespace Inbox {
- type = private
- inbox = yes
- hidden = no
- list = yes
- prefix =
- separator = +
- }
- namespace Shared {
- type = shared
- #list = children
- # NOTE: always listed in the LIST command.
- list = yes
- # NOTE: how to access the other users' mailboxes.
- # 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}/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 virtual
- namespace Virtual {
- prefix = Virtual+
- separator = +
- hidden = no
- list = yes
- subscriptions = no
- location = virtual:${dovecot-virtual}:UTF-8:INDEX=${stateDir}/index/%d/%n/virtual
- }
+ ssl = required
+ ssl_dh = <${dovecot/dh4096.pem}
+ ssl_cipher_list = HIGH:!LOW:!SSLv2:!EXP:!aNULL
+ 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
+ # FIXME: change to TLSv1.3 when supported by K-9 Mail
+ ssl_min_protocol = TLSv1.2
- mail_plugins = $mail_plugins acl
- plugin {
- 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.
- # FIXME: %d not working with userdb ldap
- acl_shared_dict = file:${stateDir}/acl/%d/acl.db
- }
+ listen = *
+ mail_home = ${stateDir}/home/%d/%n
+ # Read multiple mails in parallel, improves performance
+ mail_prefetch_count = 20
- 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
- fts_autoindex_exclude = \Junk
- fts_autoindex_exclude2 = \Trash
- fts_enforced = 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 attachments=1 verbose=0
- fts_languages = en fr
- #fts_dovecot_fs = posix:prefix=%h/fts/
- }
+ # 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 {
+ 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
+ }
+ unix_listener /var/lib/postfix/queue/private/auth {
+ user = ${postfix.user}
+ group = ${postfix.group}
+ mode = 0660
+ }
+ }
+ service auth-worker {
+ user = ${dovecot2.user}
+ }
+ auth_cache_verify_password_with_worker = yes
+ # SEE: http://wiki2.dovecot.org/Quota/FS
+ # NOTE: postfix does not supply a client cert.
+ auth_ssl_require_client_cert = no
+ #auth_ssl_username_from_cert = yes
+ # NOTE: lowercase the username, help with LDAP?
+ auth_username_format = %Lu
+ # NOTE: sync with LDAP's data.
+ first_valid_uid = 1000
+ disable_plaintext_auth = yes
- mail_plugins = $mail_plugins quota
- plugin {
- quota = maildir:User quota
- quota_rule = *:storage=256M
- quota_rule2 = Trash:storage=+64M
- quota_max_mail_size = 20M
- #quota_exceeded_message = </path/to/quota_exceeded_message.txt
- quota_warning = storage=95%% quota-warning 95 %u
- quota_warning2 = storage=80%% quota-warning 80 %u
- quota_warning3 = -storage=100%% quota-warning below %u
- }
+ 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 =
+ }
- protocol lda {
- hostname = ${networking.domain}
- mail_plugins = $mail_plugins sieve
- postmaster_address = postmaster+dovecot+lda@${networking.domain}
- syslog_facility = mail
- }
- lda_mailbox_autocreate = yes
- lda_mailbox_autosubscribe = yes
+ # No dirty syncs for maildir: locations which may be used directly by neomutt
+ maildir_very_dirty_syncs = no
+ namespace Inbox {
+ type = private
+ inbox = yes
+ hidden = no
+ list = yes
+ prefix =
+ separator = +
+ }
+ namespace Shared {
+ type = shared
+ #list = children
+ # NOTE: always listed in the LIST command.
+ list = yes
+ # NOTE: how to access the other users' mailboxes.
+ # 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}/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 virtual
+ namespace Virtual {
+ prefix = Virtual+
+ separator = +
+ hidden = no
+ list = yes
+ subscriptions = no
+ location = virtual:${dovecot-virtual}:UTF-8:INDEX=${stateDir}/index/%d/%n/virtual
+ }
- protocol lmtp {
- mail_plugins = $mail_plugins sieve
- postmaster_address = postmaster+dovecot+lmtp@${networking.domain}
- }
- service lmtp {
- process_min_avail = ${toString host.CPUs}
- unix_listener /var/lib/postfix/queue/private/dovecot-lmtp {
- user = ${postfix.user}
- group = ${postfix.group}
- mode = 0600
+ mail_plugins = $mail_plugins acl
+ plugin {
+ 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.
+ # FIXME: %d not working with userdb ldap
+ acl_shared_dict = file:${stateDir}/acl/%d/acl.db
}
- }
- plugin {
- # Let extension.sieve do the handling of the detail
- #lmtp_save_to_detail_mailbox = yes
- recipient_delimiter = ${postfix.recipientDelimiter}
- }
- service imap {
- # Most of the memory goes to mmap()ing files.
- # You may need to increase this limit if you have huge mailboxes.
- #vsz_limit =
- process_limit = 1024
- }
- service imap-login {
- #inet_listener imap {
- # address = 127.0.0.1
- # port = 143
- # ssl = no
+ #mail_plugins = $mail_plugins fts fts_xapian
+ # Default VSZ (virtual memory size) limit for service processes. This is mainly
+ # intended to catch and kill processes that leak memory before they eat up everything.
+ # Increased for fts_xapian.
+ #default_vsz_limit = 1G
+ #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
+ # fts_autoindex_exclude = \Junk
+ # fts_autoindex_exclude2 = \Trash
+ # fts_enforced = 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 attachments=1 verbose=0
+ # fts_languages = en fr
+ # #fts_dovecot_fs = posix:prefix=%h/fts/
#}
- inet_listener imaps {
- port = 993
- ssl = yes
+
+ mail_plugins = $mail_plugins quota
+ plugin {
+ quota = maildir:User quota
+ quota_rule = *:storage=256M
+ quota_rule2 = Trash:storage=+64M
+ quota_max_mail_size = 20M
+ #quota_exceeded_message = </path/to/quota_exceeded_message.txt
+ quota_warning = storage=95%% quota-warning 95 %u
+ quota_warning2 = storage=80%% quota-warning 80 %u
+ quota_warning3 = -storage=100%% quota-warning below %u
}
- }
- # Store METADATA information within user's HOME directory
- mail_attribute_dict = file:%h/dovecot-attributes
- # If you have Dovecot v2.2.8+ you may get a significant performance improvement with fetch-headers:
- imapc_features = $imapc_features fetch-headers
- protocol imap {
- #mail_max_userip_connections = 10
- mail_plugins = $mail_plugins imap_acl imap_quota imap_sieve virtual
- imap_metadata = yes
- # DOC: https://wiki.dovecot.org/MailboxSettings
- # Due to a bug in Dovecot v2.2.30+ if special-use flags are used,
- # SPECIAL-USE needs to be added to post-login CAPABILITY response as RFC 6154 mandates.
- imap_capability = +SPECIAL-USE
+ protocol lda {
+ hostname = ${networking.domain}
+ mail_plugins = $mail_plugins sieve
+ postmaster_address = root+dovecot+lda@${networking.domain}
+ syslog_facility = mail
+ }
+ lda_mailbox_autocreate = yes
+ lda_mailbox_autosubscribe = yes
- namespace Inbox {
- mailbox "Archives" {
- auto = subscribe
- special_use = \Archive
- }
- mailbox "Drafts" {
- auto = no
- special_use = \Drafts
- }
- mailbox "Brouillons" {
- auto = subscribe
- special_use = \Drafts
- }
- mailbox "Junk" {
- auto = no
- #autoexpunge = 30d
- special_use = \Junk
- }
- mailbox "Spams" {
- auto = no
- special_use = \Junk
- }
- mailbox "Spam" {
- auto = no
- special_use = \Junk
- }
- mailbox "Pourriels" {
- auto = no
- special_use = \Junk
- }
- mailbox "Pourriel" {
- auto = no
- special_use = \Junk
- }
- mailbox "Sent" {
- auto = no
- special_use = \Sent
- }
- mailbox "Sent Items" {
- auto = no
- special_use = \Sent
- }
- mailbox "Sent Messages" {
- auto = no
- special_use = \Sent
- }
- mailbox "Envoyés" {
- auto = no
- special_use = \Sent
- }
- mailbox "Trash" {
- auto = no
- special_use = \Trash
- #autoexpunge = 30d
+ protocol lmtp {
+ mail_plugins = $mail_plugins sieve
+ postmaster_address = root+dovecot+lmtp@${networking.domain}
+ }
+ service lmtp {
+ process_min_avail = ${toString host.CPUs}
+ unix_listener /var/lib/postfix/queue/private/dovecot-lmtp {
+ user = ${postfix.user}
+ group = ${postfix.group}
+ mode = 0600
}
- mailbox "Corbeille" {
- auto = no
- special_use = \Trash
+ }
+ plugin {
+ # Let extension.sieve do the handling of the detail
+ #lmtp_save_to_detail_mailbox = yes
+ recipient_delimiter = ${postfix.recipientDelimiter}
+ }
+
+ service imap {
+ # Most of the memory goes to mmap()ing files.
+ # You may need to increase this limit if you have huge mailboxes.
+ #vsz_limit =
+ process_limit = 1024
+ }
+ service imap-login {
+ #inet_listener imap {
+ # address = 127.0.0.1
+ # port = 143
+ # ssl = no
+ #}
+ inet_listener imaps {
+ port = 993
+ ssl = yes
}
}
- namespace Virtual {
- mailbox All {
- auto = no
- comment = All messages from all mailboxes
- # This flag is confused with \Archives by K9-Mail
- special_use = \All
+ # Store METADATA information within user's HOME directory
+ mail_attribute_dict = file:%h/dovecot-attributes
+ # If you have Dovecot v2.2.8+ you may get a significant performance improvement with fetch-headers:
+ imapc_features = $imapc_features fetch-headers
+ protocol imap {
+ #mail_max_userip_connections = 10
+ mail_plugins = $mail_plugins imap_acl imap_quota imap_sieve virtual
+ imap_metadata = yes
+
+ # DOC: https://wiki.dovecot.org/MailboxSettings
+ # Due to a bug in Dovecot v2.2.30+ if special-use flags are used,
+ # SPECIAL-USE needs to be added to post-login CAPABILITY response as RFC 6154 mandates.
+ imap_capability = +SPECIAL-USE
+
+ namespace Inbox {
+ mailbox "Archives" {
+ auto = subscribe
+ special_use = \Archive
+ }
+ mailbox "Drafts" {
+ auto = no
+ special_use = \Drafts
+ }
+ mailbox "Brouillons" {
+ auto = subscribe
+ special_use = \Drafts
+ }
+ mailbox "Junk" {
+ auto = no
+ #autoexpunge = 30d
+ special_use = \Junk
+ }
+ mailbox "Spams" {
+ auto = no
+ special_use = \Junk
+ }
+ mailbox "Spam" {
+ auto = no
+ special_use = \Junk
+ }
+ mailbox "Pourriels" {
+ auto = no
+ special_use = \Junk
+ }
+ mailbox "Pourriel" {
+ auto = no
+ special_use = \Junk
+ }
+ mailbox "Sent" {
+ auto = no
+ special_use = \Sent
+ }
+ mailbox "Sent Items" {
+ auto = no
+ special_use = \Sent
+ }
+ mailbox "Sent Messages" {
+ auto = no
+ special_use = \Sent
+ }
+ mailbox "Envoyés" {
+ auto = no
+ special_use = \Sent
+ }
+ mailbox "Trash" {
+ auto = no
+ special_use = \Trash
+ #autoexpunge = 30d
+ }
+ mailbox "Corbeille" {
+ auto = no
+ special_use = \Trash
+ }
}
- mailbox Recents {
- auto = no
- comment = All messages from all mailboxes, arrived in the past 48h
+ namespace Virtual {
+ 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
+ }
}
}
- }
- plugin {
- sieve_plugins = sieve_imapsieve sieve_extprograms
- sieve_global_extensions = +vnd.dovecot.environment +vnd.dovecot.pipe
- #sieve_extensions = +editheader
- 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_quota_max_storage = 10M
- #sieve_spamtest_max_value = 10
- #sieve_spamtest_status_header = X-Spam-Score
- #sieve_spamtest_status_type = strlen
- #sieve_user_log = ~/sieve.log
- # Enables support for user Sieve scripts in IMAP
- #imapsieve_url = sieve://mail.${networking.domain}:4190
+ plugin {
+ sieve_plugins = sieve_imapsieve sieve_extprograms
+ sieve_global_extensions = +vnd.dovecot.environment +vnd.dovecot.pipe
+ #sieve_extensions = +editheader
+ 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_quota_max_storage = 10M
+ #sieve_spamtest_max_value = 10
+ #sieve_spamtest_status_header = X-Spam-Score
+ #sieve_spamtest_status_type = strlen
+ #sieve_user_log = ~/sieve.log
+ # Enables support for user Sieve scripts in IMAP
+ #imapsieve_url = sieve://mail.${networking.domain}:4190
- # When a flag changes, spam or ham according to the \Junk or \NonJunk flags
- imapsieve_mailbox1_name = *
- imapsieve_mailbox1_causes = FLAG
- imapsieve_mailbox1_before = file:${stateDir}/sieve/global/spam-or-ham.sieve
+ # When a flag changes, spam or ham according to the \Junk or \NonJunk flags
+ imapsieve_mailbox1_name = *
+ imapsieve_mailbox1_causes = FLAG
+ imapsieve_mailbox1_before = file:${stateDir}/sieve/global/spam-or-ham.sieve
- # From elsewhere to Junk folder
- imapsieve_mailbox2_name = Pourriel
- imapsieve_mailbox2_causes = COPY APPEND
- imapsieve_mailbox2_before = file:${stateDir}/sieve/global/report-spam.sieve
+ # From elsewhere to Junk folder
+ imapsieve_mailbox2_name = Pourriel
+ imapsieve_mailbox2_causes = COPY APPEND
+ imapsieve_mailbox2_before = file:${stateDir}/sieve/global/report-spam.sieve
- # From Junk folder to elsewhere
- imapsieve_mailbox3_name = *
- imapsieve_mailbox3_from = Pourriel
- imapsieve_mailbox3_causes = COPY
- imapsieve_mailbox3_before = file:${stateDir}/sieve/global/report-ham.sieve
- }
- protocol sieve {
- # Maximum number of ManageSieve connections allowed for a user from each IP address.
- # NOTE: The username is compared case-sensitively.
- mail_max_userip_connections = 10
+ # From Junk folder to elsewhere
+ imapsieve_mailbox3_name = *
+ imapsieve_mailbox3_from = Pourriel
+ imapsieve_mailbox3_causes = COPY
+ imapsieve_mailbox3_before = file:${stateDir}/sieve/global/report-ham.sieve
+ }
+ protocol sieve {
+ # Maximum number of ManageSieve connections allowed for a user from each IP address.
+ # NOTE: The username is compared case-sensitively.
+ mail_max_userip_connections = 10
- # 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 timesieved v2.2.13'
- managesieve_implementation_string = Dovecot Pigeonhole
+ # 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 timesieved v2.2.13'
+ managesieve_implementation_string = Dovecot Pigeonhole
- # The maximum number of compile errors that are returned to the client upon script
- # upload or script verification.
- managesieve_max_compile_errors = 5
+ # The maximum number of compile errors that are returned to the client upon script
+ # upload or script verification.
+ managesieve_max_compile_errors = 5
- #mail_max_userip_connections = 10
- #managesieve_implementation_string = Dovecot Pigeonhole
- managesieve_max_compile_errors = 5
- #managesieve_max_line_length = 65536
- #managesieve_notify_capability = mailto
- #managesieve_sieve_capability = fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date ihave
- }
- service managesieve-login {
- inet_listener sieve {
- port = 4190
- #ssl = yes
+ #mail_max_userip_connections = 10
+ #managesieve_implementation_string = Dovecot Pigeonhole
+ managesieve_max_compile_errors = 5
+ #managesieve_max_line_length = 65536
+ #managesieve_notify_capability = mailto
+ #managesieve_sieve_capability = fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date ihave
}
+ service managesieve-login {
+ inet_listener sieve {
+ port = 4190
+ #ssl = yes
+ }
- # Number of connections to handle before starting a new process. Typically
- # the only useful values are 0 (unlimited) or 1. 1 is more secure, but 0
- # is faster. <doc/wiki/LoginProcess.txt>
- service_count = 1
+ # Number of connections to handle before starting a new process. Typically
+ # the only useful values are 0 (unlimited) or 1. 1 is more secure, but 0
+ # is faster. <doc/wiki/LoginProcess.txt>
+ service_count = 1
- # Number of processes to always keep waiting for more connections.
- process_min_avail = 0
+ # Number of processes to always keep waiting for more connections.
+ process_min_avail = 0
- # If you set service_count=0, you probably need to grow this.
- #vsz_limit = 64M
- }
+ # If you set service_count=0, you probably need to grow this.
+ #vsz_limit = 64M
+ }
- service quota-warning {
- executable = script ${
- pkgs.writeShellScript "quota-warning" ''
- set -eu
- PERCENT=$1
- USER=$2
- cat << EOF | ${pkgs.dovecot}/libexec/dovecot/dovecot-lda -d $USER -o
- "plugin/quota=maildir:User quota:noenforcing"
- From: postmaster@${networking.domain}
- Subject: [WARNING] your mailbox is now $PERCENT% full.
+ service quota-warning {
+ executable = script ${
+ pkgs.writeShellScript "quota-warning" ''
+ set -eu
+ PERCENT=$1
+ USER=$2
+ cat << EOF | ${pkgs.dovecot}/libexec/dovecot/dovecot-lda -d $USER -o
+ "plugin/quota=maildir:User quota:noenforcing"
+ From: root+docevot@${networking.domain}
+ Subject: [WARNING] your mailbox is now $PERCENT% full.
- Please remove some mails to make room for new ones.
- EOF
- ''
- }
- # use some unprivileged user for executing the quota warnings
- user = ${dovecot2.user}
- unix_listener quota-warning {
+ Please remove some mails to make room for new ones.
+ EOF
+ ''
+ }
+ # use some unprivileged user for executing the quota warnings
+ user = ${dovecot2.user}
+ unix_listener quota-warning {
+ }
}
- }
- protocol pop3 {
- mail_plugins = $mail_plugins virtual
- #mail_max_userip_connections = 10
- # Virtual namespace for the virtual INBOX.
- # Use a global directory for dovecot-virtual files.
- #namespace Inbox {
- # hidden = yes
- # list = no
- # location = virtual:''${dovecot-virtual-pop3}/pop3:INDEX=${stateDir}/index/%d/%n/virtual/pop3:LAYOUT=fs
- # prefix = pop3+
- #}
- pop3_client_workarounds =
- pop3_fast_size_lookups = yes
- pop3_lock_session = yes
- pop3_no_flag_updates = yes
- # Use GUIDs to avoid accidental POP3 UIDL changes instead of IMAP UIDs.
- pop3_uidl_format = %g
- }
- service pop3 {
- process_limit = 1024
- }
- service pop3-login {
- inet_listener pop3s {
- port = 995
- ssl = yes
+ protocol pop3 {
+ mail_plugins = $mail_plugins virtual
+ #mail_max_userip_connections = 10
+ # Virtual namespace for the virtual INBOX.
+ # Use a global directory for dovecot-virtual files.
+ #namespace Inbox {
+ # hidden = yes
+ # list = no
+ # location = virtual:''${dovecot-virtual-pop3}/pop3:INDEX=${stateDir}/index/%d/%n/virtual/pop3:LAYOUT=fs
+ # prefix = pop3+
+ #}
+ pop3_client_workarounds =
+ pop3_fast_size_lookups = yes
+ pop3_lock_session = yes
+ pop3_no_flag_updates = yes
+ # Use GUIDs to avoid accidental POP3 UIDL changes instead of IMAP UIDs.
+ pop3_uidl_format = %g
}
- }
- '';
-};
+ service pop3 {
+ process_limit = 1024
+ }
+ service pop3-login {
+ inet_listener pop3s {
+ port = 995
+ ssl = yes
+ }
+ }
+ '';
+ };
}