diff --git a/modules/mailserver/dovecot.nix b/modules/mailserver/dovecot.nix index 53523ec..edbf7be 100644 --- a/modules/mailserver/dovecot.nix +++ b/modules/mailserver/dovecot.nix @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2021-2023 Simon Bruder +# SPDX-FileCopyrightText: 2021-2024 Simon Bruder # # SPDX-License-Identifier: AGPL-3.0-or-later @@ -38,14 +38,58 @@ lib.mkIf cfg.enable { Spam = { specialUse = "Junk"; auto = "subscribe"; }; }; - sieveScripts = { - before = pkgs.writeText "spam.sieve" '' - require "fileinto"; + mailPlugins.perProtocol = { + imap.enable = [ "imap_sieve" ]; + lmtp.enable = [ "sieve" ]; + }; - if header :is "X-Spam" "Yes" { - fileinto "Spam"; - } - ''; + sieve = { + scripts = { + before = pkgs.writeText "spam.sieve" '' + require "fileinto"; + + if header :is "X-Spam" "Yes" { + fileinto "Spam"; + } + ''; + }; + extensions = [ "fileinto" ]; + pipeBins = lib.mkIf cfg.spam.enable [ + "${pkgs.rspamd}/bin/rspamc" + ]; + }; + + imapsieve.mailbox = lib.mkIf cfg.spam.enable [ + { + name = "Spam"; + causes = [ "COPY" ]; + before = pkgs.writeText "learn-spam.sieve" '' + require ["vnd.dovecot.pipe", "copy", "imapsieve"]; + pipe :copy "rspamc" ["learn_spam"]; + ''; + } + { + name = "*"; + from = "Spam"; + causes = [ "COPY" ]; + before = pkgs.writeText "learn-ham.sieve" '' + require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"]; + + if environment :matches "imap.mailbox" "*" { + set "mailbox" "''${1}"; + } + + if string "''${mailbox}" "Trash" { + stop; + } + + pipe :copy "rspamc" ["learn_ham"]; + ''; + } + ]; + + pluginSettings = { + sieve = "file:/var/lib/sieve/%d/%n/scripts;active=/var/lib/sieve/%d/%n/active.sieve"; }; extraConfig = '' @@ -56,14 +100,6 @@ lib.mkIf cfg.enable { ssl_cipher_list = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 ssl_prefer_server_ciphers = no - protocol imap { - mail_plugins = $mail_plugins imap_sieve - } - - protocol lmtp { - mail_plugins = $mail_plugins sieve - } - service imap-login { inet_listener imap { } @@ -98,25 +134,6 @@ lib.mkIf cfg.enable { lda_mailbox_autosubscribe = yes lda_mailbox_autocreate = yes - plugin { - sieve_plugins = sieve_imapsieve sieve_extprograms - sieve = file:/var/lib/sieve/%d/%n/scripts;active=/var/lib/sieve/%d/%n/active.sieve - - ${lib.optionalString cfg.spam.enable '' - imapsieve_mailbox1_name = Spam - imapsieve_mailbox1_causes = COPY - imapsieve_mailbox1_before = file:/var/lib/dovecot/sieve/learn-spam.sieve - - imapsieve_mailbox2_name = * - imapsieve_mailbox2_from = Spam - imapsieve_mailbox2_causes = COPY - imapsieve_mailbox2_before = file:/var/lib/dovecot/sieve/learn-ham.sieve - sieve_pipe_bin_dir = ${pkgs.symlinkJoin { name = "sieve-pipe-bin-dir"; paths = with pkgs; [ rspamd ]; } }/bin - ''} - - sieve_global_extensions = +vnd.dovecot.pipe - } - service managesieve-login { inet_listener sieve { port = 4190 @@ -127,33 +144,6 @@ lib.mkIf cfg.enable { systemd.services.dovecot2 = { wants = [ "acme-finished-${cfg.fqdn}.target" ]; after = [ "acme-finished-${cfg.fqdn}.target" ]; - - preStart = lib.mkIf cfg.spam.enable - (lib.mkAfter - (lib.concatStrings - (lib.mapAttrsToList - (name: content: '' - cp ${pkgs.writeText name content} /var/lib/dovecot/sieve/${name} - '') - { - "learn-spam.sieve" = '' - require ["vnd.dovecot.pipe", "copy", "imapsieve"]; - pipe :copy "rspamc" ["learn_spam"]; - ''; - "learn-ham.sieve" = '' - require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"]; - - if environment :matches "imap.mailbox" "*" { - set "mailbox" "''${1}"; - } - - if string "''${mailbox}" "Trash" { - stop; - } - - pipe :copy "rspamc" ["learn_ham"]; - ''; - }))); }; networking.firewall.allowedTCPPorts = [