{ pkgs, lib, config, system, ... }: let inherit (builtins) toString toFile readFile; inherit (builtins.extraBuiltins) pass; inherit (lib) types; inherit (pkgs.lib) loadFile unlines unlinesAttrs unlinesValues unwords; inherit (config) networking; inherit (config.services) dovecot2 postfix openldap; # NOTE: nixpkgs' dovecot2.stateDir is currently not exported stateDir = "/var/lib/dovecot"; sieve_pipe_bin_dir = pkgs.buildEnv { name = "sieve_pipe_bin_dir"; pathsToLink = [ "/bin" ]; paths = [ learn-spam learn-ham ]; }; learn-spam = pkgs.writeShellScriptBin "learn-spam.sh" '' exec ${pkgs.rspamd}/bin/rspamc -h /run/rspamd/learner.sock learn_spam ''; learn-ham = pkgs.writeShellScriptBin "learn-ham.sh" '' exec ${pkgs.rspamd}/bin/rspamc -h /run/rspamd/learner.sock learn_ham ''; dovecot-virtual = pkgs.buildEnv { name = "dovecot-virtual"; pathsToLink = [ "/" ]; paths = [ dovecot-virtual-all dovecot-virtual-recents ]; }; dovecot-virtual-all = pkgs.writeTextFile { name = "dovecot-virtual-all"; destination = "/All/dovecot-virtual"; text = '' * all ''; }; dovecot-virtual-recents = pkgs.writeTextFile { name = "dovecot-virtual-recents"; destination = "/Recents/dovecot-virtual"; text = '' * all younger 172800 ''; }; dovecot-virtual-pop3 = pkgs.writeTextFile { name = "dovecot-virtual-pop3"; destination = "/pop3/INBOX/dovecot-virtual"; text = '' All All+* all ''; }; in { imports = [ dovecot/autoconfig.nix ]; systemd.services.dovecot2 = { after = [ "postfix.service" "openldap.service" "${networking.domain}.key.pem-key.service" ]; }; #users.users."${dovecot2.mailUser}".isSystemUser = true; # Fix nixpkgs services.dovecot2 = { enable = true; modules = [ pkgs.dovecot_pigeonhole pkgs.dovecot_fts_xapian ]; enablePAM = false; enableImap = true; enableLmtp = true; enablePop3 = true; 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 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"; createMailUser = false; mailUser = ""; mailGroup = ""; sslServerCert = null; sieveScripts = { global = dovecot/sieve/global; }; extraConfig = '' auth_verbose = yes auth_debug = yes mail_debug = yes 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 = service_count = 1 # 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 } service quota-warning { executable = script ${ pkgs.writeScript "quota-warning" '' #!/bin/sh -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. 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 } } ''; #${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)); }