Simon Bruder
10b8d432d5
This applies the REUSE specification to the repository, so the licensing information can be tracked for every file individually.
171 lines
4.8 KiB
Nix
171 lines
4.8 KiB
Nix
# SPDX-FileCopyrightText: 2021-2023 Simon Bruder <simon@sbruder.de>
|
|
#
|
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
{ config, lib, pkgs, ... }:
|
|
let
|
|
cfg = config.sbruder.mailserver;
|
|
postfixCfg = config.services.postfix;
|
|
|
|
passdb = pkgs.writeText "dovecot-users"
|
|
(lib.concatMapStringsSep
|
|
"\n"
|
|
({ address, passwordHash, ... }: "${address}:{BLF-CRYPT}${passwordHash}")
|
|
cfg.users);
|
|
in
|
|
lib.mkIf cfg.enable {
|
|
services.dovecot2 = {
|
|
enable = true;
|
|
|
|
modules = with pkgs; [ dovecot_pigeonhole ];
|
|
|
|
enableLmtp = true;
|
|
enablePAM = false;
|
|
protocols = [ "sieve" ];
|
|
|
|
mailUser = "vmail";
|
|
mailGroup = "vmail";
|
|
mailLocation = "maildir:${cfg.storage}/%d/%n";
|
|
|
|
sslServerCert = "${cfg.certDir}/fullchain.pem";
|
|
sslServerKey = "${cfg.certDir}/key.pem";
|
|
|
|
mailboxes = {
|
|
Archive = { specialUse = "Archive"; auto = "subscribe"; };
|
|
Sent = { specialUse = "Sent"; auto = "subscribe"; };
|
|
Drafts = { specialUse = "Drafts"; auto = "subscribe"; };
|
|
Trash = { specialUse = "Trash"; auto = "subscribe"; };
|
|
Spam = { specialUse = "Junk"; auto = "subscribe"; };
|
|
};
|
|
|
|
sieveScripts = {
|
|
before = pkgs.writeText "spam.sieve" ''
|
|
require "fileinto";
|
|
|
|
if header :is "X-Spam" "Yes" {
|
|
fileinto "Spam";
|
|
}
|
|
'';
|
|
};
|
|
|
|
extraConfig = ''
|
|
# generated 2021-02-04, Mozilla Guideline v5.6, Dovecot 2.3.13, OpenSSL 1.1.1i, intermediate configuration
|
|
# https://ssl-config.mozilla.org/#server=dovecot&version=2.3.13&config=intermediate&openssl=1.1.1i&guideline=5.6
|
|
ssl = required
|
|
ssl_min_protocol = TLSv1.2
|
|
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 {
|
|
}
|
|
}
|
|
|
|
service lmtp {
|
|
unix_listener dovecot-lmtp {
|
|
mode = 0600
|
|
user = ${postfixCfg.user}
|
|
group = ${postfixCfg.group}
|
|
}
|
|
}
|
|
|
|
passdb {
|
|
driver = passwd-file
|
|
args = username_format=%u ${passdb}
|
|
}
|
|
|
|
userdb {
|
|
driver = static
|
|
args = uid=vmail gid=vmail home=${cfg.storage}/%d/%n
|
|
}
|
|
|
|
service auth {
|
|
unix_listener auth {
|
|
mode = 0660
|
|
user = ${postfixCfg.user}
|
|
group = ${postfixCfg.group}
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|
|
}
|
|
'';
|
|
};
|
|
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 = [
|
|
143 # IMAP
|
|
993 # IMAP (implicit TLS)
|
|
4190 # ManageSieve
|
|
];
|
|
|
|
security.acme.certs."${cfg.fqdn}".postRun = ''
|
|
if systemctl is-active dovecot2; then
|
|
systemctl --no-block reload dovecot2
|
|
fi
|
|
'';
|
|
}
|