losurdo: enable hardened profile
[sourcephile-nix.git] / servers / mermet / dovecot.nix
index 6816738f14530600b6c65d9d0d7b93613997f9a1..2488e3cb65842ee44c50e925f222484d917d5cf9 100644 (file)
@@ -8,7 +8,7 @@ let
   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";
@@ -61,32 +61,42 @@ let
 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" ];
   # 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 not quota at the filesystem level
+  # 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}/mail/%d/%n/mail.d:UTF-8:CONTROL=${stateDir}/control/%d/%n:INDEX=${stateDir}/index/%d/%n";
+  mailLocation = "sdbox:${stateDir}/home/%d/%n/mail:UTF-8:CONTROL=${stateDir}/control/%d/%n:INDEX=${stateDir}/index/%d/%n";
   createMailUser = false;
   mailUser = "";
   mailGroup = "";
@@ -95,23 +105,23 @@ services.dovecot2 = {
     global = dovecot/sieve/global;
   };
   extraConfig = ''
-    auth_verbose = yes
-    auth_debug = yes
-    mail_debug = yes
+    auth_verbose = no
+    auth_debug = no
+    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
@@ -127,24 +137,11 @@ services.dovecot2 = {
     # 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 SSHA256 -u $user
+    # 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
-    passdb {
-      driver = ldap
-      # Because auth_bind=yes and auth_bind_userdn are used,
-      # this cannot prefetch any userdb_*.
-      args = ${dovecot/ldap/sourcephile.fr.conf}
-      default_fields =
-      override_fields =
-    }
-    userdb {
-      driver = ldap
-      # A different path than passdb's args enables non-blocking LDAP requests
-      args = ${pkgs.symlinkJoin {name="ldap"; paths=[dovecot/ldap];}}/sourcephile.fr.conf
-      default_fields =
-      override_fields =
-    }
     service auth {
       user = ${dovecot2.user}
       # auth_socket_path points to this userdb socket by default. It's typically
@@ -176,6 +173,14 @@ services.dovecot2 = {
     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 =
+    }
+
     # No dirty syncs for maildir: locations which may be used directly by neomutt
     maildir_very_dirty_syncs = no
     namespace Inbox {
@@ -195,7 +200,7 @@ services.dovecot2 = {
       # 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
@@ -212,7 +217,7 @@ services.dovecot2 = {
 
     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.
@@ -222,6 +227,9 @@ services.dovecot2 = {
 
     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
@@ -231,7 +239,9 @@ services.dovecot2 = {
       # 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
@@ -368,21 +378,22 @@ services.dovecot2 = {
         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
@@ -390,7 +401,7 @@ services.dovecot2 = {
       #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
 
@@ -417,7 +428,7 @@ services.dovecot2 = {
 
       # 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
@@ -451,8 +462,8 @@ services.dovecot2 = {
 
     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
@@ -498,21 +509,5 @@ services.dovecot2 = {
       }
     }
   '';
-  #${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));
 }