{ lib, pkgs, config, ... }: let sieve_bin = pkgs.runCommand "sieve_bin" { buildInputs = [ pkgs.makeWrapper ]; } '' cp -a ${./sieve_bin} $out chmod -R u+w $out patchShebangs $out for i in $out/*; do wrapProgram "$i" --prefix PATH : ${lib.makeBinPath [ pkgs.coreutils ]} done ''; in { config = lib.mkIf config.myServices.mail.enable { services.duplyBackup.profiles.mail.excludeFile = '' + /var/lib/dhparams + /var/lib/dovecot ''; secrets.keys = [ { dest = "dovecot/ldap"; user = config.services.dovecot2.user; group = config.services.dovecot2.group; permissions = "0400"; text = '' hosts = ${config.myEnv.mail.dovecot.ldap.host} tls = yes dn = ${config.myEnv.mail.dovecot.ldap.dn} dnpass = ${config.myEnv.mail.dovecot.ldap.password} auth_bind = yes ldap_version = 3 base = ${config.myEnv.mail.dovecot.ldap.base} scope = subtree pass_filter = ${config.myEnv.mail.dovecot.ldap.filter} pass_attrs = ${config.myEnv.mail.dovecot.ldap.pass_attrs} user_attrs = ${config.myEnv.mail.dovecot.ldap.user_attrs} user_filter = ${config.myEnv.mail.dovecot.ldap.filter} iterate_attrs = ${config.myEnv.mail.dovecot.ldap.iterate_attrs} iterate_filter = ${config.myEnv.mail.dovecot.ldap.iterate_filter} ''; } ]; users.users.vhost = { group = "vhost"; uid = config.ids.uids.vhost; }; users.groups.vhost.gid = config.ids.gids.vhost; # https://blog.zeninc.net/index.php?post/2018/04/01/Un-annuaire-pour-les-gouverner-tous....... services.dovecot2 = { enable = true; enablePAM = false; enablePop3 = true; enableImap = true; enableLmtp = true; protocols = [ "sieve" ]; modules = [ pkgs.dovecot_pigeonhole pkgs.dovecot_fts-xapian ]; mailUser = "vhost"; mailGroup = "vhost"; createMailUser = false; mailboxes = [ { name = "Trash"; auto = "subscribe"; specialUse = "Trash"; } { name = "Junk"; auto = "subscribe"; specialUse = "Junk"; } { name = "Sent"; auto = "subscribe"; specialUse = "Sent"; } { name = "Drafts"; auto = "subscribe"; specialUse = "Drafts"; } ]; mailLocation = "mbox:~/Mail:INBOX=~/Mail/Inbox:INDEX=~/.imap"; sslServerCert = "/var/lib/acme/mail/fullchain.pem"; sslServerKey = "/var/lib/acme/mail/key.pem"; sslCACert = "/var/lib/acme/mail/fullchain.pem"; extraConfig = builtins.concatStringsSep "\n" [ '' postmaster_address = postmaster@immae.eu mail_attribute_dict = file:%h/dovecot-attributes imap_idle_notify_interval = 20 mins namespace inbox { type = private separator = / inbox = yes list = yes } '' # ACL '' mail_plugins = $mail_plugins acl plugin { acl = vfile:${pkgs.writeText "dovecot-acl" '' Backup/* owner lrp ''} acl_globals_only = yes } '' # Full text search '' # needs to be bigger than any mailbox size default_vsz_limit = 2GB mail_plugins = $mail_plugins fts fts_xapian plugin { plugin = fts fts_xapian fts = xapian fts_xapian = partial=2 full=20 fts_autoindex = yes fts_autoindex_exclude = \Junk fts_autoindex_exclude2 = \Trash fts_autoindex_exclude3 = Virtual/* } '' # Antispam # https://docs.iredmail.org/dovecot.imapsieve.html '' # imap_sieve plugin added below plugin { sieve_plugins = sieve_imapsieve sieve_extprograms imapsieve_url = sieve://127.0.0.1:4190 sieve_before = file:${./sieve_scripts}/backup.sieve;bindir=/var/lib/vhost/.sieve_bin # From elsewhere to Junk folder imapsieve_mailbox1_name = Junk imapsieve_mailbox1_causes = COPY APPEND imapsieve_mailbox1_before = file:${./sieve_scripts}/report_spam.sieve;bindir=/var/lib/vhost/.imapsieve_bin # From Junk folder to elsewhere imapsieve_mailbox2_name = * imapsieve_mailbox2_from = Junk imapsieve_mailbox2_causes = COPY imapsieve_mailbox2_before = file:${./sieve_scripts}/report_ham.sieve;bindir=/var/lib/vhost/.imapsieve_bin # From anywhere to NoJunk folder imapsieve_mailbox3_name = NoJunk imapsieve_mailbox3_causes = COPY APPEND imapsieve_mailbox3_before = file:${./sieve_scripts}/report_ham.sieve;bindir=/var/lib/vhost/.imapsieve_bin sieve_pipe_bin_dir = ${sieve_bin} sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.environment } '' # Services to listen '' service imap-login { inet_listener imap { } inet_listener imaps { } } service pop3-login { inet_listener pop3 { } inet_listener pop3s { } } service imap { } service pop3 { } service auth { unix_listener auth-userdb { } unix_listener ${config.services.postfix.config.queue_directory}/private/auth { mode = 0666 } } service auth-worker { } service dict { unix_listener dict { } } service stats { unix_listener stats-reader { user = vhost group = vhost mode = 0660 } unix_listener stats-writer { user = vhost group = vhost mode = 0660 } } '' # Authentification '' first_valid_uid = ${toString config.ids.uids.vhost} disable_plaintext_auth = yes passdb { driver = ldap args = ${config.secrets.fullPaths."dovecot/ldap"} } userdb { driver = ldap args = ${config.secrets.fullPaths."dovecot/ldap"} } '' # Zlib '' mail_plugins = $mail_plugins zlib plugin { zlib_save_level = 6 zlib_save = gz } '' # Sieve '' plugin { sieve = file:~/sieve;bindir=~/.sieve-bin;active=~/.dovecot.sieve } service managesieve-login { } service managesieve { } '' # Virtual mailboxes '' mail_plugins = $mail_plugins virtual namespace Virtual { prefix = Virtual/ location = virtual:~/Virtual } '' # Protocol specific configuration # Needs to come last if there are mail_plugins entries '' protocol imap { mail_plugins = $mail_plugins imap_sieve imap_acl } protocol lda { mail_plugins = $mail_plugins sieve } '' ]; }; networking.firewall.allowedTCPPorts = [ 110 143 993 995 4190 ]; system.activationScripts.dovecot = { deps = [ "users" ]; text ='' install -m 0755 -o vhost -g vhost -d /var/lib/vhost ''; }; services.cron.systemCronJobs = let cron_script = pkgs.writeScriptBin "cleanup-imap-folders" '' ${pkgs.dovecot}/bin/doveadm expunge -A MAILBOX "Backup/*" NOT UID 1:256 2>&1 > /dev/null | grep -v "Mailbox doesn't exist:" | grep -v "Info: Opening DB" ${pkgs.dovecot}/bin/doveadm expunge -A MAILBOX Junk SEEN NOT FLAGGED BEFORE 4w 2>&1 > /dev/null | grep -v "Mailbox doesn't exist:" | grep -v "Info: Opening DB" ${pkgs.dovecot}/bin/doveadm expunge -A MAILBOX Trash NOT FLAGGED BEFORE 4w 2>&1 > /dev/null | grep -v "Mailbox doesn't exist:" | grep -v "Info: Opening DB" ''; in [ "0 2 * * * root ${cron_script}/bin/cleanup-imap-folders" ]; security.acme.certs."mail" = { postRun = '' systemctl restart dovecot2.service ''; extraDomains = { "imap.immae.eu" = null; "pop3.immae.eu" = null; }; }; }; }